diff options
Diffstat (limited to 'Stars45/MapView.cpp')
-rw-r--r-- | Stars45/MapView.cpp | 3482 |
1 files changed, 0 insertions, 3482 deletions
diff --git a/Stars45/MapView.cpp b/Stars45/MapView.cpp deleted file mode 100644 index dc992d1..0000000 --- a/Stars45/MapView.cpp +++ /dev/null @@ -1,3482 +0,0 @@ -/* Starshatter: The Open Source Project - Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors - Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors - Copyright (c) 1997-2006, Destroyer Studios LLC. - - AUTHOR: John DiCamillo - - - OVERVIEW - ======== - Star Map class -*/ - -#include "MapView.h" - -#include "Galaxy.h" -#include "StarSystem.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Instruction.h" -#include "Element.h" -#include "NavAI.h" -#include "Weapon.h" -#include "Sim.h" -#include "Mission.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "Contact.h" -#include "MenuView.h" - -#include "NetLobby.h" -#include "NetUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "EventDispatch.h" -#include "Video.h" -#include "Button.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "Mouse.h" -#include "FormatUtil.h" -#include "Menu.h" - -// +--------------------------------------------------------------------+ - -// Supported Selection Modes: - -const int SELECT_NONE = -1; -const int SELECT_SYSTEM = 0; -const int SELECT_PLANET = 1; -const int SELECT_REGION = 2; -const int SELECT_STATION = 3; -const int SELECT_STARSHIP = 4; -const int SELECT_FIGHTER = 5; -const int SELECT_NAVPT = 6; - -const int VIEW_GALAXY = 0; -const int VIEW_SYSTEM = 1; -const int VIEW_REGION = 2; - -// +--------------------------------------------------------------------+ - -MapView::MapView(Window* win) -: View(win) -, system(0), zoom(1.1), offset_x(0), offset_y(0), ship(0), campaign(0) -, captured(false), dragging(false), adding_navpt(false) -, moving_navpt(false), moving_elem(false) -, view_mode(VIEW_SYSTEM), seln_mode(SELECT_REGION), ship_filter(0xffffffff) -, current_star(0), current_planet(0), current_region(0) -, current_ship(0), current_elem(0), current_navpt(0), mission(0) -, scrolling(0), scroll_x(0), scroll_y(0), click_x(0), click_y(0) -, active_menu(0), map_menu(0), map_system_menu(0), map_sector_menu(0) -, ship_menu(0), editor(false) -, nav_menu(0), action_menu(0), objective_menu(0), formation_menu(0), speed_menu(0) -, hold_menu(0), farcast_menu(0), menu_view(0) -{ - for (int i = 0; i < 3; i++) { - view_zoom[i] = zoom; - view_offset_x[i] = offset_x; - view_offset_y[i] = offset_y; - } - - menu_view = new MenuView(window); - - title_font = FontMgr::Find("Limerick12"); - font = FontMgr::Find("Verdana"); - - active_window = (ActiveWindow*) window; - - if (active_window) - active_window->AddView(this); -} - -// +--------------------------------------------------------------------+ - -MapView::~MapView() -{ - ClearMenu(); - galaxy_image.ClearImage(); - - delete menu_view; -} - -// +--------------------------------------------------------------------+ - -void -MapView::OnWindowMove() -{ - if (menu_view) - menu_view->OnWindowMove(); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetGalaxy(List<StarSystem>& g) -{ - system_list.clear(); - system_list.append(g); - - if (system_list.size() > 0) { - SetSystem(system_list[0]); - } -} - -void -MapView::SetSystem(StarSystem* s) -{ - if (system != s) { - system = s; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - // flush old object pointers: - stars.clear(); - planets.clear(); - regions.clear(); - - // insert objects from star system: - if (system) { - ListIter<OrbitalBody> star = system->Bodies(); - while (++star) { - switch (star->Type()) { - case Orbital::STAR: stars.append(star.value()); - break; - case Orbital::PLANET: - case Orbital::MOON: planets.append(star.value()); - break; - } - } - - ListIter<OrbitalBody> planet = star->Satellites(); - while (++planet) { - planets.append(planet.value()); - - ListIter<OrbitalBody> moon = planet->Satellites(); - while (++moon) { - planets.append(moon.value()); - } - } - - ListIter<OrbitalRegion> rgn = system->AllRegions(); - while (++rgn) - regions.append(rgn.value()); - - // sort region list by distance from the star: - regions.sort(); - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetShip(Ship* s) -{ - if (ship != s) { - ship = s; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (ship && system_list.size() > 0) { - SimRegion* rgn = ship->GetRegion(); - - if (rgn && rgn->System()) { - system = 0; - SetSystem(rgn->System()); - } - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetMission(Mission* m) -{ - if (mission != m) { - mission = m; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (mission && system_list.size() > 0) { - system = 0; - SetSystem(mission->GetStarSystem()); - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetCampaign(Campaign* c) -{ - if (campaign != c) { - campaign = c; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (campaign) - SetGalaxy(campaign->GetSystemList()); - } -} - -// +--------------------------------------------------------------------+ - -enum MapView_MENU { - MAP_SYSTEM = 1000, - MAP_SECTOR = 2000, - MAP_SHIP = 3000, - MAP_NAV = 4000, - MAP_ADDNAV = 4001, - MAP_DELETE = 4002, - MAP_CLEAR = 4003, - MAP_ACTION = 5000, - MAP_FORMATION = 6000, - MAP_SPEED = 7000, - MAP_HOLD = 8000, - MAP_FARCAST = 8500, - MAP_OBJECTIVE = 9000 -}; - -void -MapView::BuildMenu() -{ - ClearMenu(); - - map_system_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.STARSYSTEM")); - - if (system_list.size() > 0) { - int i = 0; - ListIter<StarSystem> iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - map_system_menu->AddItem(s->Name(), MAP_SYSTEM + i); - i++; - } - } - - else if (system) { - map_system_menu->AddItem(system->Name(), MAP_SYSTEM); - } - - map_sector_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SECTOR")); - for (int i = 0; i < regions.size(); i++) { - Orbital* rgn = regions[i]; - map_sector_menu->AddItem(rgn->Name(), MAP_SECTOR + i); - } - - map_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.MAP")); - map_menu->AddMenu("System", map_system_menu); - map_menu->AddMenu("Sector", map_sector_menu); - - if (ship || mission) { - ship_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SHIP")); - ship_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Starsystem"), map_system_menu); - ship_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Sector"), map_sector_menu); - - ship_menu->AddItem("", 0); - ship_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Add-Nav"), MAP_ADDNAV); - ship_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Clear-All"), MAP_CLEAR); - - action_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.ACTION")); - for (int i = 0; i < Instruction::NUM_ACTIONS; i++) { - action_menu->AddItem(ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(i)), MAP_ACTION + i); - } - - formation_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.FORMATION")); - for (int i = 0; i < Instruction::NUM_FORMATIONS; i++) { - formation_menu->AddItem(ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::FormationName(i)), MAP_FORMATION + i); - } - - speed_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SPEED")); - speed_menu->AddItem("250", MAP_SPEED + 0); - speed_menu->AddItem("500", MAP_SPEED + 1); - speed_menu->AddItem("750", MAP_SPEED + 2); - speed_menu->AddItem("1000", MAP_SPEED + 3); - - hold_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.HOLD")); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.None"), MAP_HOLD + 0); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.1-Minute"), MAP_HOLD + 1); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.5-Minutes"), MAP_HOLD + 2); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.10-Minutes"), MAP_HOLD + 3); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.15-Minutes"), MAP_HOLD + 4); - - farcast_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.FARCAST")); - farcast_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Use-Quantum"), MAP_FARCAST + 0); - farcast_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Use-Farcast"), MAP_FARCAST + 1); - - objective_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.OBJECTIVE")); - - nav_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.NAVPT")); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Action"), action_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Objective"), objective_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Formation"), formation_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Speed"), speed_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Hold"), hold_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Farcast"), farcast_menu); - nav_menu->AddItem("", 0); - nav_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Add-Nav"), MAP_ADDNAV); - nav_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Del-Nav"), MAP_DELETE); - } - - else if (campaign) { - ship_menu = 0; - speed_menu = 0; - hold_menu = 0; - farcast_menu = 0; - objective_menu = 0; - formation_menu = 0; - nav_menu = 0; - } - - active_menu = map_menu; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ClearMenu() -{ - delete map_menu; - delete map_system_menu; - delete map_sector_menu; - delete ship_menu; - delete nav_menu; - delete action_menu; - delete objective_menu; - delete formation_menu; - delete speed_menu; - delete hold_menu; - delete farcast_menu; - - map_menu = 0; - map_system_menu = 0; - map_sector_menu = 0; - ship_menu = 0; - nav_menu = 0; - action_menu = 0; - objective_menu = 0; - formation_menu = 0; - speed_menu = 0; - hold_menu = 0; - farcast_menu = 0; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ProcessMenuItem(int action) -{ - bool send_nav_data = false; - bool can_command = true; - - if (ship && current_ship && ship != current_ship) { - if (ship->GetElement() && current_ship->GetElement()) { - if (!ship->GetElement()->CanCommand(current_ship->GetElement())) { - can_command = false; - } - } - } - - else if (current_elem && NetLobby::GetInstance()) { - can_command = false; - } - - if (action >= MAP_OBJECTIVE) { - int index = action - MAP_OBJECTIVE; - - if (current_navpt && can_command) { - current_navpt->SetTarget(objective_menu->GetItem(index)->GetText()); - send_nav_data = true; - } - } - - else if (action >= MAP_FARCAST) { - if (current_navpt && can_command) { - current_navpt->SetFarcast(action - MAP_FARCAST); - send_nav_data = true; - } - } - - else if (action >= MAP_HOLD) { - int hold_time = 0; - switch (action) { - default: - case MAP_HOLD + 0: hold_time = 0; break; - case MAP_HOLD + 1: hold_time = 60; break; - case MAP_HOLD + 2: hold_time = 300; break; - case MAP_HOLD + 3: hold_time = 600; break; - case MAP_HOLD + 4: hold_time = 900; break; - } - - if (current_navpt && can_command) { - current_navpt->SetHoldTime(hold_time); - send_nav_data = true; - } - } - - else if (action >= MAP_SPEED) { - if (current_navpt && can_command) { - current_navpt->SetSpeed((action - MAP_SPEED + 1) * 250); - send_nav_data = true; - } - } - - else if (action >= MAP_FORMATION) { - if (current_navpt && can_command) { - current_navpt->SetFormation(action - MAP_FORMATION); - send_nav_data = true; - } - } - - else if (action >= MAP_ACTION) { - if (current_navpt && can_command) { - current_navpt->SetAction(action - MAP_ACTION); - SelectNavpt(current_navpt); - send_nav_data = true; - } - } - - else if (action == MAP_ADDNAV) { - Text rgn_name = regions[current_region]->Name(); - Instruction* prior = current_navpt; - Instruction* n = 0; - - if (current_ship && can_command) { - Sim* sim = Sim::GetSim(); - SimRegion* rgn = sim->FindRegion(rgn_name); - Point init_pt; - - if (rgn) { - if (rgn->IsAirSpace()) - init_pt.z = 10e3; - - n = new Instruction(rgn, init_pt); - } - else { - n = new Instruction(rgn_name, init_pt); - } - - n->SetSpeed(500); - - if (prior) { - n->SetAction(prior->Action()); - n->SetFormation(prior->Formation()); - n->SetSpeed(prior->Speed()); - n->SetTarget(prior->GetTarget()); - } - - current_ship->AddNavPoint(n, prior); - } - - else if (current_elem && can_command) { - Point init_pt; - - if (regions[current_region]->Type() == Orbital::TERRAIN) - init_pt.z = 10e3; - - n = new Instruction(rgn_name, init_pt); - n->SetSpeed(500); - - if (prior) { - n->SetAction(prior->Action()); - n->SetFormation(prior->Formation()); - n->SetSpeed(prior->Speed()); - n->SetTarget(prior->GetTarget()); - } - - current_elem->AddNavPoint(n, prior); - } - - if (can_command) { - current_navpt = n; - current_status = Instruction::PENDING; - adding_navpt = true; - captured = SetCapture(); - } - } - - else if (action == MAP_DELETE) { - if (current_navpt && can_command) { - if (current_ship) - current_ship->DelNavPoint(current_navpt); - else if (current_elem && can_command) - current_elem->DelNavPoint(current_navpt); - - SelectNavpt(0); - } - } - - else if (action == MAP_CLEAR) { - if (current_ship && can_command) - current_ship->ClearFlightPlan(); - else if (current_elem && can_command) - current_elem->ClearFlightPlan(); - - SelectNavpt(0); - } - - else if (action >= MAP_NAV) { - } - - else if (action >= MAP_SHIP) { - } - - else if (action >= MAP_SECTOR) { - int index = action - MAP_SECTOR; - - if (index < regions.size()) - current_region = index; - - if (view_mode == VIEW_SYSTEM) { - Orbital* s = regions[current_region]; - SetupScroll(s); - } - } - - else if (system_list.size() > 0 && action >= MAP_SYSTEM) { - int index = action - MAP_SYSTEM; - - if (index < system_list.size()) - SetSystem(system_list[index]); - } - - else { - } - - Sim* sim = Sim::GetSim(); - if (send_nav_data && sim) { - Ship* s = current_ship; - - if (s && s->GetElement()) { - Element* elem = s->GetElement(); - int index = elem->GetNavIndex(current_navpt); - - if (index >= 0) - NetUtil::SendNavData(false, elem, index-1, current_navpt); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::SetCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->CaptureMouse(this) ? true : false; - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::ReleaseCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->ReleaseMouse(this) ? true : false; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetViewMode(int mode) -{ - if (mode >= 0 && mode < 3) { - // save state: - view_zoom[view_mode] = zoom; - view_offset_x[view_mode] = offset_x; - view_offset_y[view_mode] = offset_y; - - // switch mode: - view_mode = mode; - - // restore state: - - if (view_mode == VIEW_GALAXY) { - zoom = 1; - offset_x = 0; - offset_y = 0; - } - else { - zoom = view_zoom[view_mode]; - offset_x = view_offset_x[view_mode]; - offset_y = view_offset_y[view_mode]; - } - - scrolling = 0; - scroll_x = 0; - scroll_y = 0; - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::Update(SimObject* obj) -{ - if (obj == current_ship) { - current_ship = 0; - active_menu = map_menu; - } - - return SimObserver::Update(obj); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectShip(Ship* selship) -{ - if (selship != current_ship) { - current_ship = selship; - - if (current_ship) { - if (current_ship->Life() == 0 || current_ship->IsDying() || current_ship->IsDead()) { - current_ship = 0; - } - else { - Observe(current_ship); - } - } - } - - SelectNavpt(0); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectElem(MissionElement* elem) -{ - if (elem != current_elem) { - current_elem = elem; - - if (current_elem) { - if (current_elem->IsStarship()) { - ship_menu->GetItem(3)->SetEnabled(true); - } - - else if (current_elem->IsDropship()) { - ship_menu->GetItem(3)->SetEnabled(true); - } - - else { - ship_menu->GetItem(3)->SetEnabled(false); - } - } - } - - SelectNavpt(0); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectNavpt(Instruction* navpt) -{ - current_navpt = navpt; - - if (current_navpt) { - current_status = current_navpt->Status(); - - List<Text> ships; - objective_menu->ClearItems(); - - switch (current_navpt->Action()) { - case Instruction::VECTOR: - case Instruction::LAUNCH: - case Instruction::PATROL: - case Instruction::SWEEP: - case Instruction::RECON: - objective_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.not-available"), 0); - objective_menu->GetItem(0)->SetEnabled(false); - break; - - case Instruction::DOCK: - FindShips(true, true, true, false, ships); - break; - - case Instruction::DEFEND: - FindShips(true, true, true, false, ships); - break; - - case Instruction::ESCORT: - FindShips(true, false, true, true, ships); - break; - - case Instruction::INTERCEPT: - FindShips(false, false, false, true, ships); - break; - - case Instruction::ASSAULT: - FindShips(false, false, true, false, ships); - break; - - case Instruction::STRIKE: - FindShips(false, true, false, false, ships); - break; - } - - for (int i = 0; i < ships.size(); i++) - objective_menu->AddItem(ships[i]->data(), MAP_OBJECTIVE + i); - - ships.destroy(); - } - else { - objective_menu->ClearItems(); - objective_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.not-available"), 0); - objective_menu->GetItem(0)->SetEnabled(false); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::FindShips(bool friendly, bool station, bool starship, bool dropship, -List<Text>& result) -{ - if (mission) { - for (int i = 0; i < mission->GetElements().size(); i++) { - MissionElement* elem = mission->GetElements().at(i); - - if (elem->IsSquadron()) continue; - if (!station && elem->IsStatic()) continue; - if (!starship && elem->IsStarship()) continue; - if (!dropship && elem->IsDropship()) continue; - - if (!editor && friendly && elem->GetIFF() > 0 && elem->GetIFF() != mission->Team()) - continue; - - if (!editor && !friendly && (elem->GetIFF() == 0 || elem->GetIFF() == mission->Team())) - continue; - - result.append(new Text(elem->Name())); - } - } - - else if (ship) { - Sim* sim = Sim::GetSim(); - - if (sim) { - for (int r = 0; r < sim->GetRegions().size(); r++) { - SimRegion* rgn = sim->GetRegions().at(r); - - for (int i = 0; i < rgn->Ships().size(); i++) { - Ship* s = rgn->Ships().at(i); - - if (!station && s->IsStatic()) continue; - if (!starship && s->IsStarship()) continue; - if (!dropship && s->IsDropship()) continue; - - if (friendly && s->GetIFF() > 0 && s->GetIFF() != ship->GetIFF()) - continue; - - if (!friendly && (s->GetIFF() == 0 || s->GetIFF() == ship->GetIFF())) - continue; - - result.append(new Text(s->Name())); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetSelectionMode(int mode) -{ - if (mode <= SELECT_NONE) { - seln_mode = SELECT_NONE; - return; - } - - if (mode != seln_mode && mode <= SELECT_FIGHTER) { - seln_mode = mode; - - // when changing mode, - // select the item closest to the current center: - if (system && view_mode == VIEW_SYSTEM) - SelectAt(rect.x + rect.w/2, - rect.y + rect.h/2); - } -} - -void -MapView::SetSelection(int index) -{ - if (scrolling) return; - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - if (index < system_list.size()) - SetSystem(system_list[index]); - s = stars[current_star]; - break; - - default: - case SELECT_PLANET: - if (index < planets.size()) - current_planet = index; - s = planets[current_planet]; - break; - - case SELECT_REGION: - if (index < regions.size()) - current_region = index; - s = regions[current_region]; - break; - - case SELECT_STATION: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter<MissionElement> elem = mission->GetElements(); - while (++elem) { - if (elem->IsStatic()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter<Orbital> rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter<Ship> s = simrgn->Ships(); - while (++s) { - if (s->IsStatic()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - - case SELECT_STARSHIP: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter<MissionElement> elem = mission->GetElements(); - while (++elem) { - if (elem->IsStarship()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter<Orbital> rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter<Ship> s = simrgn->Ships(); - while (++s) { - if (s->IsStarship()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - - case SELECT_FIGHTER: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter<MissionElement> elem = mission->GetElements(); - while (++elem) { - if (elem->IsDropship() && !elem->IsSquadron()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter<Orbital> rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter<Ship> s = simrgn->Ships(); - while (++s) { - if (s->IsDropship()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - } - - SetupScroll(s); -} - -void -MapView::SetSelectedShip(Ship* ship) -{ - if (scrolling) return; - Orbital* s = 0; - Ship* selship = 0; - - - switch (seln_mode) { - case SELECT_SYSTEM: - case SELECT_PLANET: - case SELECT_REGION: - default: - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - - if (simrgn && simrgn->NumShips()) { - selship = simrgn->Ships().find(ship); - } - } - - SelectShip(selship); - } - break; - } - - if (selship) - SetupScroll(s); -} - -void -MapView::SetSelectedElem(MissionElement* elem) -{ - if (scrolling) return; - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - case SELECT_PLANET: - case SELECT_REGION: - default: - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - SelectElem(elem); - } - break; - } - - if (current_elem) - SetupScroll(s); -} - -void -MapView::SetupScroll(Orbital* s) -{ - switch (view_mode) { - case VIEW_GALAXY: - zoom = 1; - offset_x = 0; - offset_y = 0; - scrolling = 0; - break; - - case VIEW_SYSTEM: - if (s == 0) { - offset_x = 0; - offset_y = 0; - scrolling = 0; - } - else { - scroll_x = (offset_x + s->Location().x) / 5.0; - scroll_y = (offset_y + s->Location().y) / 5.0; - scrolling = 5; - } - break; - - case VIEW_REGION: - if (current_navpt) { - // don't move the map - scrolling = 0; - } - else if (current_ship) { - Point sloc = current_ship->Location().OtherHand(); - - if (!IsVisible(sloc)) { - scroll_x = (offset_x + sloc.x) / 5.0; - scroll_y = (offset_y + sloc.y) / 5.0; - scrolling = 5; - } - else { - scroll_x = 0; - scroll_y = 0; - scrolling = 0; - } - } - else if (current_elem) { - Point sloc = current_elem->Location(); - - if (!IsVisible(sloc)) { - scroll_x = (offset_x + sloc.x) / 5.0; - scroll_y = (offset_y + sloc.y) / 5.0; - scrolling = 5; - } - else { - scroll_x = 0; - scroll_y = 0; - scrolling = 0; - } - } - else { - offset_x = 0; - offset_y = 0; - scrolling = 0; - } - break; - } -} - -bool -MapView::IsVisible(const Point& loc) -{ - if (view_mode == VIEW_REGION) { - double scale = c/r; - double ox = offset_x * scale; - double oy = offset_y * scale; - double sx = loc.x * scale; - double sy = loc.y * scale; - double cx = rect.w/2; - double cy = rect.h/2; - - int test_x = (int) (cx + sx + ox); - int test_y = (int) (cy + sy + oy); - - bool visible = test_x >= 0 && test_x < rect.w && - test_y >= 0 && test_y < rect.h; - - return visible; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetRegion(OrbitalRegion* rgn) -{ - if (scrolling || rgn == 0) return; - - int index = regions.index(rgn); - - if (index < 0 || index == current_region || index >= regions.size()) - return; - - current_region = index; - Orbital* s = regions[current_region]; - - if (!s) - return; - - switch (view_mode) { - case VIEW_GALAXY: - case VIEW_SYSTEM: - scroll_x = (offset_x + s->Location().x) / 5.0; - scroll_y = (offset_y + s->Location().y) / 5.0; - scrolling = 5; - break; - - case VIEW_REGION: - offset_x = 0; - offset_y = 0; - scrolling = 0; - break; - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetRegionByName(const char* rgn_name) -{ - OrbitalRegion* rgn = 0; - - for (int i = 0; i < regions.size(); i++) { - Orbital* r = regions[i]; - if (!strcmp(rgn_name, r->Name())) { - rgn = (OrbitalRegion*) r; - break; - } - } - - SetRegion(rgn); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectAt(int x, int y) -{ - if (scrolling) return; - if (c == 0) return; - if (seln_mode < 0) return; - - Orbital* s = 0; - - double scale = r/c; - double cx = rect.w/2; - double cy = rect.h/2; - double test_x = (x - rect.x - cx) * scale - offset_x; - double test_y = (y - rect.y - cy) * scale - offset_y; - double dist = 1.0e20; - int closest = 0; - - if (view_mode == VIEW_GALAXY) { - c = (cx>cy) ? cx : cy; - r = 10; - - Galaxy* g = Galaxy::GetInstance(); - if (g) - r = g->Radius(); - - StarSystem* closest_system = 0; - - // draw the list of systems, and their connections: - ListIter<StarSystem> iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - - double dx = (s->Location().x - test_x); - double dy = (s->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest_system = s; - } - } - - if (closest_system) - SetSystem(closest_system); - } - - else if (view_mode == VIEW_SYSTEM) { - switch (seln_mode) { - case SELECT_SYSTEM: { - if (stars.isEmpty()) return; - int index = 0; - ListIter<Orbital> star = stars; - while (++star) { - double dx = (star->Location().x - test_x); - double dy = (star->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_star = closest; - } - s = stars[current_star]; - break; - - case SELECT_PLANET: { - if (planets.isEmpty()) return; - int index = 0; - ListIter<Orbital> planet = planets; - while (++planet) { - double dx = (planet->Location().x - test_x); - double dy = (planet->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_planet = closest; - } - s = planets[current_planet]; - break; - - default: - case SELECT_REGION: { - if (regions.isEmpty()) return; - int index = 0; - ListIter<Orbital> region = regions; - while (++region) { - double dx = (region->Location().x - test_x); - double dy = (region->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_region = closest; - } - s = regions[current_region]; - break; - } - } - - else if (view_mode == VIEW_REGION) { - dist = 5.0e3; - - if (mission) { - Orbital* rgn = regions[current_region]; - MissionElement* sel_elem = 0; - Instruction* sel_nav = 0; - - if (!rgn) return; - - // check nav points: - ListIter<MissionElement> elem = mission->GetElements(); - while (++elem) { - MissionElement* e = elem.value(); - - if (!e->IsSquadron() && (editor || e->GetIFF() == mission->Team())) { - ListIter<Instruction> navpt = e->NavList(); - while (++navpt) { - Instruction* n = navpt.value(); - - if (!_stricmp(n->RegionName(), rgn->Name())) { - Point nloc = n->Location(); - double dx = nloc.x - test_x; - double dy = nloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_nav = n; - sel_elem = e; - } - } - } - } - } - - if (sel_nav) { - SelectElem(sel_elem); - SelectNavpt(sel_nav); - } - - // check elements: - else { - elem.reset(); - while (++elem) { - MissionElement* e = elem.value(); - - if (e->Region() == rgn->Name() && !e->IsSquadron()) { - Point sloc = e->Location(); - double dx = sloc.x - test_x; - double dy = sloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_elem = e; - } - } - } - - SelectElem(sel_elem); - - if (sel_elem) - s = rgn; - } - } - else if (ship) { - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = 0; - Ship* sel_ship = 0; - Instruction* sel_nav = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - // check nav points: - if (simrgn) { - for (int r = 0; r < sim->GetRegions().size(); r++) { - SimRegion* simrgn = sim->GetRegions().at(r); - - for (int i = 0; i < simrgn->Ships().size(); i++) { - Ship* s = simrgn->Ships().at(i); - - if (s->GetIFF() == ship->GetIFF() && s->GetElementIndex() == 1) { - ListIter<Instruction> navpt = s->GetFlightPlan(); - while (++navpt) { - Instruction* n = navpt.value(); - - if (!_stricmp(n->RegionName(), rgn->Name())) { - Point nloc = n->Location(); - double dx = nloc.x - test_x; - double dy = nloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_nav = n; - sel_ship = s; - } - } - } - } - } - } - } - - if (sel_nav) { - SelectShip(sel_ship); - SelectNavpt(sel_nav); - } - - // check ships: - else if (simrgn->NumShips()) { - ListIter<Ship> ship = simrgn->Ships(); - while (++ship) { - Ship* s = ship.value(); - - if (!IsClutter(*s)) { - Point sloc = s->Location().OtherHand(); - double dx = sloc.x - test_x; - double dy = sloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_ship = s; - } - } - } - - SelectShip(sel_ship); - } - else { - SelectShip(0); - SelectNavpt(0); - } - } - } - - if (s) - SetupScroll(s); -} - -// +--------------------------------------------------------------------+ - -Orbital* -MapView::GetSelection() -{ - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - if (current_star < stars.size()) - s = stars[current_star]; - break; - - default: - case SELECT_PLANET: - if (current_planet < planets.size()) - s = planets[current_planet]; - break; - - case SELECT_REGION: - if (current_region < regions.size()) - s = regions[current_region]; - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - break; - } - - return s; -} - -Ship* -MapView::GetSelectedShip() -{ - return current_ship; -} - -MissionElement* -MapView::GetSelectedElem() -{ - return current_elem; -} - -// +--------------------------------------------------------------------+ - -int -MapView::GetSelectionIndex() -{ - int s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: s = current_star; break; - default: - case SELECT_PLANET: s = current_planet; break; - case SELECT_REGION: s = current_region; break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - s = -1; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - if (simrgn) { - if (current_ship && simrgn->NumShips()) { - s = simrgn->Ships().index(current_ship); - } - } - } - break; - } - - return s; -} - -void -MapView::DrawTabbedText(Font* font, const char* text) -{ - if (font && text && *text) { - Rect label_rect; - - label_rect.w = rect.w; - label_rect.h = rect.h; - - label_rect.Inset(8,8,8,8); - - DWORD text_flags = DT_WORDBREAK | DT_LEFT; - - active_window->SetFont(font); - active_window->DrawText(text, 0, label_rect, text_flags); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::Refresh() -{ - rect = window->GetRect(); - - if (!system) { - DrawGrid(); - DrawTabbedText(title_font, ContentBundle::GetInstance()->GetText("MapView.item.no-system")); - return; - } - - if (font) - font->SetColor(Color::White); - - if (scrolling) { - offset_x -= scroll_x; - offset_y -= scroll_y; - scrolling--; - } - - rect.w -= 2; - rect.h -= 2; - - switch (view_mode) { - case VIEW_GALAXY: DrawGalaxy(); break; - case VIEW_SYSTEM: DrawSystem(); break; - case VIEW_REGION: DrawRegion(); break; - default: DrawGrid(); break; - } - - rect.w += 2; - rect.h += 2; - - if (menu_view) { - if (current_navpt) { - active_menu = nav_menu; - } - else if (current_ship) { - if (current_ship->GetIFF() == ship->GetIFF()) - active_menu = ship_menu; - else - active_menu = map_menu; - } - else if (current_elem) { - if (editor || current_elem->GetIFF() == mission->Team()) - active_menu = ship_menu; - else - active_menu = map_menu; - } - else { - active_menu = map_menu; - } - - menu_view->SetBackColor(Color::Gray); - menu_view->SetTextColor(Color::White); - menu_view->SetMenu(active_menu); - menu_view->DoMouseFrame(); - - if (menu_view->GetAction()) { - ProcessMenuItem(menu_view->GetAction()); - } - - menu_view->Refresh(); - } - - DrawTitle(); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawTitle() -{ - title_font->SetColor(active_window->GetForeColor()); - DrawTabbedText(title_font, title); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawGalaxy() -{ - title = ContentBundle::GetInstance()->GetText("MapView.title.Galaxy"); - DrawGrid(); - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx>cy) ? cx : cy; - r = 10; // * zoom; - - Galaxy* g = Galaxy::GetInstance(); - if (g) - r = g->Radius(); // * zoom; - - double scale = c/r; - double ox = 0; - double oy = 0; - - // compute offset: - ListIter<StarSystem> iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - - if (system == s) { - if (fabs(s->Location().x) > 10 || fabs(s->Location().y) > 10) { - int sx = (int) s->Location().x; - int sy = (int) s->Location().y; - - sx -= sx % 10; - sy -= sy % 10; - - ox = sx * -scale; - oy = sy * -scale; - } - } - } - - // draw the list of systems, and their connections: - iter.reset(); - while (++iter) { - StarSystem* s = iter.value(); - - int sx = (int) (cx + ox + s->Location().x * scale); - int sy = (int) (cy + oy + s->Location().y * scale); - - if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4) - continue; - - window->DrawEllipse(sx-7, sy-7, sx+7, sy+7, Ship::IFFColor(s->Affiliation())); - - if (s == system) { - window->DrawLine(0, sy, rect.w, sy, Color::Gray, Video::BLEND_ADDITIVE); - window->DrawLine(sx, 0, sx, rect.h, Color::Gray, Video::BLEND_ADDITIVE); - } - - ListIter<StarSystem> iter2 = system_list; - while (++iter2) { - StarSystem* s2 = iter2.value(); - - if (s != s2 && s->HasLinkTo(s2)) { - int ax = sx; - int ay = sy; - - int bx = (int) (cx + ox + s2->Location().x * scale); - int by = (int) (cy + oy + s2->Location().y * scale); - - if (ax == bx) { - if (ay < by) { - ay += 8; by -= 8; - } - else { - ay -= 8; by += 8; - } - } - - else if (ay == by) { - if (ax < bx) { - ax += 8; bx -= 8; - } - else { - ax -= 8; bx += 8; - } - } - - else { - Point d = Point(bx, by, 0) - Point(ax, ay, 0); - d.Normalize(); - - ax += (int) (8 * d.x); - ay += (int) (8 * d.y); - - bx -= (int) (8 * d.x); - by -= (int) (8 * d.y); - } - - window->DrawLine(ax, ay, bx, by, Color(120,120,120), Video::BLEND_ADDITIVE); - } - } - } - - // finally draw all the stars in the galaxy: - if (g) { - ListIter<Star> iter = g->Stars(); - while (++iter) { - Star* s = iter.value(); - - int sx = (int) (cx + ox + s->Location().x * scale); - int sy = (int) (cy + oy + s->Location().y * scale); - int sr = s->GetSize(); - - if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4) - continue; - - window->FillEllipse(sx-sr, sy-sr, sx+sr, sy+sr, s->GetColor()); - - if (!strncmp(s->Name(), "GSC", 3)) - font->SetColor(Color(100,100,100)); - else - font->SetColor(Color::White); - - Rect name_rect(sx-60, sy+8, 120, 20); - active_window->SetFont(font); - active_window->DrawText(s->Name(), 0, name_rect, DT_SINGLELINE | DT_CENTER); - } - } - - font->SetColor(Color::White); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawSystem() -{ - Text caption = ContentBundle::GetInstance()->GetText("MapView.title.Starsystem"); - caption += " "; - caption += system->Name(); - - if (current_ship) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_ship->Name(); - } - else if (current_elem) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_elem->Name(); - } - - title = caption; - - ListIter<OrbitalBody> star = system->Bodies(); - while (++star) { - int p_orb = 1; - - ListIter<OrbitalBody> planet = star->Satellites(); - while (++planet) { - DrawOrbital(*planet, p_orb++); - - int m_orb = 1; - - ListIter<OrbitalBody> moon = planet->Satellites(); - while (++moon) { - DrawOrbital(*moon, m_orb++); - - ListIter<OrbitalRegion> region = moon->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - } - - ListIter<OrbitalRegion> region = planet->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - } - - ListIter<OrbitalRegion> region = star->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - - DrawOrbital(*star, 0); - } - - char r_txt[32]; - FormatNumber(r_txt, system->Radius() * zoom); - char resolution[64]; - sprintf_s(resolution, "%s: %s", ContentBundle::GetInstance()->GetText("MapView.info.Resolution").data(), r_txt); - - active_window->SetFont(font); - Rect text_rect(4, 4, rect.w - 8, 24); - active_window->DrawText(resolution, -1, text_rect, DT_SINGLELINE|DT_RIGHT); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawRegion() -{ - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - Text caption = ContentBundle::GetInstance()->GetText("MapView.title.Sector"); - caption += " "; - caption += rgn->Name(); - - if (current_ship) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_ship->Name(); - } - else if (current_elem) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_elem->Name(); - } - - title = caption; - - double cx = rect.w/2; - double cy = rect.h/2; - - int size = (int) rgn->Radius(); - int step = (int) rgn->GridSpace(); - - c = (cx<cy) ? cx : cy; - r = rgn->Radius() * zoom; - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - int left = (int) (-size * scale + ox + cx); - int right = (int) ( size * scale + ox + cx); - int top = (int) (-size * scale + oy + cy); - int bottom = (int) ( size * scale + oy + cy); - - Color major(48,48,48); - Color minor(24,24,24); - - int x,y; - int tick = 0; - - for (x = 0; x <= size; x += step) { - int lx = (int) (x * scale + ox + cx); - if (!tick) - window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE); - - lx = (int) (-x * scale + ox + cx); - if (!tick) - window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE); - - if (++tick > 3) tick = 0; - } - - tick = 0; - - for (y = 0; y <= size; y += step) { - int ly = (int) (y * scale + oy + cy); - if (!tick) - window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE); - - ly = (int) (-y * scale + oy + cy); - if (!tick) - window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE); - - if (++tick > 3) tick = 0; - } - - int rep = 3; - if (r > 70e3) rep = 2; - if (r > 250e3) rep = 1; - - if (campaign && rgn) { - // draw the combatants in this region: - ListIter<Combatant> iter = campaign->GetCombatants(); - while (++iter) { - Combatant* combatant = iter.value(); - DrawCombatGroup(combatant->GetForce(), rep); - } - } - - else if (mission && rgn) { - // draw the elements in this region: - ListIter<MissionElement> elem = mission->GetElements(); - while (++elem) - if (!elem->IsSquadron()) - DrawElem(*elem, (elem.value() == current_elem), rep); - } - - else if (ship) { - // draw the ships in this region: - Sim* sim = Sim::GetSim(); - SimRegion* simrgn = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - // this algorithm uses the allied track list for the region, - // even if this ship is in a different region. a previous - // version used the ship's own contact list, which only shows - // ships in the player's region. this way is less "realistic" - // but more fun for managing large battles. - - if (simrgn) { - ListIter<Contact> c = simrgn->TrackList(ship->GetIFF()); - while (++c) { - Contact* contact = c.value(); - Ship* s = contact->GetShip(); - - if (s && (s->Class() & ship_filter) && !IsClutter(*s) && s != ship) - DrawShip(*s, (s == current_ship), rep); - } - - ListIter<Ship> s_iter = simrgn->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s && (s->IsStatic()) && !IsClutter(*s) && - (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0)) - DrawShip(*s, (s == current_ship), rep); - } - - // draw nav routes for allied ships not in the region: - ListIter<SimRegion> r_iter = sim->GetRegions(); - while (++r_iter) { - SimRegion* r = r_iter.value(); - - if (r != simrgn) { - ListIter<Ship> s_iter = r->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s && !s->IsStatic() && !IsClutter(*s) && - (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0)) { - DrawNavRoute(simrgn->GetOrbitalRegion(), - s->GetFlightPlan(), - s->MarkerColor(), - s, 0); - } - } - } - } - } - - // draw our own ship: - DrawShip(*ship, (ship == current_ship), rep); - } - - char r_txt[32]; - FormatNumber(r_txt, r*2); - char resolution[64]; - sprintf_s(resolution, "%s: %s", ContentBundle::GetInstance()->GetText("MapView.info.Resolution").data(), r_txt); - - active_window->SetFont(font); - Rect text_rect(4, 4, rect.w - 8, 24); - active_window->DrawText(resolution, -1, text_rect, DT_SINGLELINE|DT_RIGHT); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawGrid() -{ - int grid_step = rect.w/8; - int cx = rect.w/2; - int cy = rect.h/2; - - Color c(32,32,32); - - window->DrawLine(0, cy, rect.w, cy, c, Video::BLEND_ADDITIVE); - window->DrawLine(cx, 0, cx, rect.h, c, Video::BLEND_ADDITIVE); - - for (int i = 1; i < 4; i++) { - window->DrawLine(0, cy + (i*grid_step), rect.w, cy + (i*grid_step), c, Video::BLEND_ADDITIVE); - window->DrawLine(0, cy - (i*grid_step), rect.w, cy - (i*grid_step), c, Video::BLEND_ADDITIVE); - window->DrawLine(cx + (i*grid_step), 0, cx + (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE); - window->DrawLine(cx - (i*grid_step), 0, cx - (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawOrbital(Orbital& body, int index) -{ - int type = body.Type(); - - if (type == Orbital::NOTHING) - return; - - int x1, y1, x2, y2; - Rect label_rect; - int label_w = 64; - int label_h = 18; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = system->Radius() * zoom; - - if ((r > 300e9) && (type > Orbital::PLANET)) - return; - - double xscale = cx / r; - double yscale = cy / r * 0.75; - - double ox = offset_x * xscale; - double oy = offset_y * yscale; - - double bo_x = body.Orbit() * xscale; - double bo_y = body.Orbit() * yscale; - double br = body.Radius() * yscale; - double bx = body.Location().x * xscale; - double by = body.Location().y * yscale; - - double px = 0; - double py = 0; - - if (body.Primary()) { - double min_pr = GetMinRadius(body.Primary()->Type()); - - if (index) { - if (min_pr < 4) - min_pr = 4; - - min_pr *= (index+1); - } - - double min_x = min_pr * xscale / yscale; - double min_y = min_pr; - - if (bo_x < min_x) - bo_x = min_x; - - if (bo_y < min_y) - bo_y = min_y; - - px = body.Primary()->Location().x * xscale; - py = body.Primary()->Location().y * yscale; - } - - if (type == Orbital::TERRAIN) - bo_x = bo_y; - - int ipx = (int) (cx + px + ox); - int ipy = (int) (cy + py + oy); - int ibo_x = (int) bo_x; - int ibo_y = (int) bo_y; - - x1 = ipx - ibo_x; - y1 = ipy - ibo_y; - x2 = ipx + ibo_x; - y2 = ipy + ibo_y; - - if (type != Orbital::TERRAIN) { - double a = x2-x1; - double b = rect.w*32; - - if (a < b) - window->DrawEllipse(x1, y1, x2, y2, Color(64,64,64), Video::BLEND_ADDITIVE); - } - - // show body's location on possibly magnified orbit - bx = px + bo_x * cos(body.Phase()); - by = py + bo_y * sin(body.Phase()); - - double min_br = GetMinRadius(type); - if (br < min_br) br = min_br; - - Color color; - - switch (type) { - case Orbital::STAR: color = Color(248, 248, 128); break; - case Orbital::PLANET: color = Color( 64, 64, 192); break; - case Orbital::MOON: color = Color( 32, 192, 96); break; - case Orbital::REGION: color = Color(255, 255, 255); break; - case Orbital::TERRAIN: color = Color( 16, 128, 48); break; - } - - int icx = (int) (cx + bx + ox); - int icy = (int) (cy + by + oy); - int ibr = (int) br; - - x1 = icx - ibr; - y1 = icy - ibr; - x2 = icx + ibr; - y2 = icy + ibr; - - if (type < Orbital::REGION) { - if (body.GetMapIcon().Width() > 64) { - Bitmap* map_icon = (Bitmap*) &body.GetMapIcon(); - - if (type == Orbital::STAR) - window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ADDITIVE); - else - window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ALPHA); - } - else { - window->FillEllipse(x1, y1, x2, y2, color); - } - } - else { - window->DrawRect(x1, y1, x2, y2, color); - - if (campaign) { - ListIter<Combatant> iter = campaign->GetCombatants(); - while (++iter) { - Combatant* combatant = iter.value(); - - if (ibr >= 4 || combatant->GetIFF() == 1) - DrawCombatantSystem(combatant, &body, icx, icy, ibr); - } - } - } - - if (type == Orbital::STAR || bo_y > label_h) { - label_rect.x = x1 - label_w + (int) br; - label_rect.y = y1 - label_h; - label_rect.w = label_w * 2; - label_rect.h = label_h; - - active_window->SetFont(font); - active_window->DrawText(body.Name(), -1, label_rect, DT_SINGLELINE|DT_CENTER); - } -} - -// +--------------------------------------------------------------------+ - -double -MapView::GetMinRadius(int type) -{ - switch (type) { - case Orbital::STAR: return 8; - case Orbital::PLANET: return 4; - case Orbital::MOON: return 2; - case Orbital::REGION: return 2; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -static void -ColorizeBitmap(Bitmap& img, Color color) -{ - int w = img.Width(); - int h = img.Height(); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - Color c = img.GetColor(x, y); - - if (c != Color::Black && c != Color::White) { - img.SetColor(x,y,color.ShadeColor(c.Blue()/2)); - } - } - } - - img.AutoMask(); -} - -static POINT shipshape1[] = { {6,0}, {-6,4}, {-6,-4} }; -static POINT shipshape2[] = { {8,0}, { 4,4}, {-8,4}, {-8,-4}, {4,-4} }; -static POINT shipshape3[] = { {8,8}, {-8,8}, {-8,-8}, {8,-8} }; - -void -MapView::DrawShip(Ship& s, bool current, int rep) -{ - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - if (!rgn) return; - - int x1, y1, x2, y2; - POINT shiploc; - Point sloc = s.Location().OtherHand(); - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = rgn->Radius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - window->SetFont(font); - - // draw ship icon: - if (rep && view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion()) { - double sx = (sloc.x + rlx) * scale; - double sy = (sloc.y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor()); - sprite_width = 2; - - if (&s == ship || !IsCrowded(s)) - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - else { - Point heading = s.Heading().OtherHand(); - heading.z = 0; - heading.Normalize(); - - double theta = 0; - - if (heading.y > 0) - theta = acos(heading.x); - else - theta = -acos(heading.x); - - const double THETA_SLICE = 4 / PI; - const double THETA_OFFSET = PI + THETA_SLICE/2; - - int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE); - int nsprites = s.Design()->map_sprites.size(); - - if (nsprites) { - if (sprite_index < 0 || sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = s.Design()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, s.MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - theta -= PI/2; - - if (s.IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (s.IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - } - } - - // draw nav route: - // draw current ship marker: - if (current && Text(s.GetRegion()->Name()) == regions[current_region]->Name()) { - x1 = (int) (shiploc.x - sprite_width - 1); - x2 = (int) (shiploc.x + sprite_width + 1); - y1 = (int) (shiploc.y - sprite_width - 1); - y2 = (int) (shiploc.y + sprite_width + 1); - - window->DrawRect(x1, y1, x2, y2, Color::White); - } - - // only see routes for your own team: - if (s.GetIFF() == 0 || ship && s.GetIFF() == ship->GetIFF()) { - DrawNavRoute(rgn, s.GetFlightPlan(), s.MarkerColor(), &s, 0); - } -} - -void -MapView::DrawElem(MissionElement& s, bool current, int rep) -{ - if (!mission) return; - - bool visible = editor || - s.GetIFF() == 0 || - s.GetIFF() == mission->Team() || - s.IntelLevel() > Intel::KNOWN; - - if (!visible) return; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (!rgn) return; - - int x1, y1, x2, y2; - POINT shiploc; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = rgn->Radius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - window->SetFont(font); - - // draw ship icon: - if (!_stricmp(s.Region(), rgn->Name())) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor()); - sprite_width = 2; - - if (!IsCrowded(s)) - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - else { - double theta = s.Heading(); - - const double THETA_SLICE = 4 / PI; - const double THETA_OFFSET = PI / 2; - - int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE); - int nsprites = 0; - - if (s.GetDesign()) - nsprites = s.GetDesign()->map_sprites.size(); - - if (nsprites > 0) { - if (sprite_index < 0 || sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = s.GetDesign()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, s.MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - theta -= PI/2; - - if (s.IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (s.IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - char label[64]; - - if (s.Count() > 1) - sprintf_s(label, "%s x %d", (const char*) s.Name(), s.Count()); - else - strcpy_s(label, (const char*) s.Name()); - - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label); - } - } - } - - // draw nav route: - // draw current ship marker: - if (current && s.Region() == regions[current_region]->Name()) { - x1 = (int) (shiploc.x - sprite_width - 1); - x2 = (int) (shiploc.x + sprite_width + 1); - y1 = (int) (shiploc.y - sprite_width - 1); - y2 = (int) (shiploc.y + sprite_width + 1); - - window->DrawRect(x1, y1, x2, y2, Color::White); - } - - // only see routes for your own team: - if (editor || s.GetIFF() == 0 || mission && s.GetIFF() == mission->Team()) { - DrawNavRoute(rgn, s.NavList(), s.MarkerColor(), 0, &s); - } -} - -void -MapView::DrawNavRoute(OrbitalRegion* rgn, -List<Instruction>& s_route, -Color s_marker, -Ship* ship, -MissionElement* elem) -{ - int x1, y1, x2, y2; - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = system->Radius() * zoom; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - double ox = offset_x * scale; - double oy = offset_y * scale; - - Point old_loc; - double old_x = 0; - double old_y = 0; - bool old_in = false; - - Point first_loc; - int first_x = 0; - int first_y = 0; - bool first_in = false; - - bool draw_route = true; - bool draw_bold = false; - - if (ship && ship->GetElementIndex() > 1) - draw_route = false; - - if (ship && ship == current_ship) { - s_marker = s_marker * 1.5; - draw_bold = true; - } - - else if (elem && elem == current_elem) { - s_marker = s_marker * 1.5; - draw_bold = true; - } - - for (int i = 0; i < s_route.size(); i++) { - Instruction* navpt = s_route[i]; - - if (!_stricmp(navpt->RegionName(), rgn->Name())) { - double nav_x = navpt->Location().x * scale; - double nav_y = navpt->Location().y * scale; - - int isx = (int) (cx + nav_x + ox); - int isy = (int) (cy + nav_y + oy); - - if (old_in && draw_route) { - int iox = (int) (cx + old_x + ox); - int ioy = (int) (cy + old_y + oy); - window->DrawLine(iox, ioy, isx, isy, s_marker); - - int x1 = (iox-isx); - int y1 = (ioy-isy); - - if (draw_bold) { - if (x1 > y1) { - window->DrawLine(iox, ioy+1, isx, isy+1, s_marker); - } - else { - window->DrawLine(iox+1, ioy, isx+1, isy, s_marker); - } - } - - if ((x1*x1 + y1*y1) > 2000) { - double dist = Point(navpt->Location() - old_loc).length(); - - int imx = (int) (cx + (old_x+nav_x)/2 + ox); - int imy = (int) (cy + (old_y+nav_y)/2 + oy); - - char dist_txt[32]; - FormatNumber(dist_txt, dist); - font->SetColor(Color::Gray); - window->SetFont(font); - window->Print(imx-20, imy-6, dist_txt); - font->SetColor(Color::White); - } - } - - x1 = isx - 3; - y1 = isy - 3; - x2 = isx + 3; - y2 = isy + 3; - - Color c = Color::White; - if (navpt->Status() > Instruction::ACTIVE) { - c = Color::Gray; - } - else if (!first_in) { - first_in = true; - first_loc = navpt->Location(); - first_x = isx; - first_y = isy; - } - - if (draw_route) { - window->DrawLine(x1, y1, x2, y2, c); - window->DrawLine(x1, y2, x2, y1, c); - - if (navpt == current_navpt) - window->DrawRect(x1-2, y1-2, x2+2, y2+2, c); - - char buf[256]; - sprintf_s(buf, "%d", i+1); - window->SetFont(font); - window->Print(x2+3, y1, buf); - - if (navpt == current_navpt) { - if (navpt->TargetName() && strlen(navpt->TargetName())) { - sprintf_s(buf, "%s %s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data(), navpt->TargetName()); - window->Print(x2+3, y1+10, buf); - } - else { - sprintf_s(buf, "%s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data()); - window->Print(x2+3, y1+10, buf); - } - - sprintf_s(buf, "%s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::FormationName(navpt->Formation())).data()); - window->Print(x2+3, y1+20, buf); - - sprintf_s(buf, "%d", navpt->Speed()); - window->Print(x2+3, y1+30, buf); - - if (navpt->HoldTime()) { - char hold_time[32]; - FormatTime(hold_time, navpt->HoldTime()); - - sprintf_s(buf, "%s %s", ContentBundle::GetInstance()->GetText("MapView.item.Hold").data(), hold_time); - window->Print(x2+3, y1+40, buf); - } - } - } - - old_loc = navpt->Location(); - old_x = nav_x; - old_y = nav_y; - old_in = true; - } - - else { - old_loc = navpt->Location(); - old_x = 0; - old_y = 0; - old_in = false; - } - } - - // if the ship and the first active navpoint are both in the region, - // draw a line from the ship to the first active navpoint: - - if (first_in) { - old_in = false; - - if (ship && ship->GetRegion()) { - old_in = (ship->GetRegion()->GetOrbitalRegion() == rgn); - - if (old_in) { - old_loc = ship->Location().OtherHand(); - old_x = old_loc.x * scale; - old_y = old_loc.y * scale; - } - } - - else if (elem) { - old_in = (elem->Region() == rgn->Name()) ? true : false; - - if (old_in) { - old_loc = elem->Location(); - old_x = old_loc.x * scale; - old_y = old_loc.y * scale; - } - } - - if (old_in) { - int iox = (int) (cx + old_x + ox); - int ioy = (int) (cy + old_y + oy); - window->DrawLine(iox, ioy, first_x, first_y, s_marker); - - int x1 = (iox-first_x); - int y1 = (ioy-first_y); - - if (draw_bold) { - if (x1 > y1) { - window->DrawLine(iox, ioy+1, first_x, first_y+1, s_marker); - } - else { - window->DrawLine(iox+1, ioy, first_x+1, first_y, s_marker); - } - } - - if ((x1*x1 + y1*y1) > 2000) { - double dist = Point(first_loc - old_loc).length(); - double nav_x = first_loc.x * scale; - double nav_y = first_loc.y * scale; - - int imx = (int) (cx + (old_x+nav_x)/2 + ox); - int imy = (int) (cy + (old_y+nav_y)/2 + oy); - - char dist_txt[32]; - FormatNumber(dist_txt, dist); - font->SetColor(Color::Gray); - window->SetFont(font); - window->Print(imx-20, imy-6, dist_txt); - font->SetColor(Color::White); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatantSystem(Combatant* c, Orbital* rgn, int x, int y, int r) -{ - int team = c->GetIFF(); - int x1 = 0; - int x2 = 0; - int y1 = y - r; - int a = 0; - - switch (team) { - case 0: x1 = x - 64; - x2 = x + 64; - y1 = y + r + 4; - a = DT_CENTER; - break; - - case 1: x1 = x - 200; - x2 = x - r - 4; - a = DT_RIGHT; - break; - - default: x1 = x + r + 4; - x2 = x + 200; - a = DT_LEFT; - break; - } - - DrawCombatGroupSystem(c->GetForce(), rgn, x1, x2, y1, a); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatGroupSystem(CombatGroup* group, Orbital* rgn, int x1, int x2, int& y, int a) -{ - if (!group || group->IsReserve() || group->CalcValue() < 1) - return; - - char txt[80]; - - if (group->GetRegion() == rgn->Name()) { - switch (group->Type()) { - case CombatGroup::CARRIER_GROUP: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::DESTROYER_SQUADRON: - { - sprintf_s(txt, "%s '%s'", group->GetShortDescription(), group->Name().data()); - active_window->SetFont(font); - Rect text_rect(x1, y, x2 - x1, 12); - active_window->DrawText(txt, 0, text_rect, a); - y += 10; - break; - } - case CombatGroup::BATTALION: - case CombatGroup::STATION: - case CombatGroup::STARBASE: - - case CombatGroup::MINEFIELD: - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: - { - active_window->SetFont(font); - Rect text_rect(x1, y, x2 - x1, 12); - active_window->DrawText(group->GetShortDescription(), 0, text_rect, a); - y += 10; - break; - } - default: - break; - } - } - - ListIter<CombatGroup> iter = group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - DrawCombatGroupSystem(g, rgn, x1, x2, y, a); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatGroup(CombatGroup* group, int rep) -{ - // does group even exist yet? - if (!group || group->IsReserve() || group->CalcValue() < 1) - return; - - // is group a squadron? don't draw squadrons on map: - if (group->Type() >= CombatGroup::WING && group->Type() < CombatGroup::FLEET) - return; - - // has group been discovered yet? - CombatGroup* player_group = campaign->GetPlayerGroup(); - if (group->GetIFF() && player_group && player_group->GetIFF() != group->GetIFF()) - if (group->IntelLevel() <= Intel::KNOWN) - return; - - // has group been destroyed already? - if (group->CalcValue() < 1) - return; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - if (!rgn) return; - - POINT shiploc; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = rgn->Radius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - if (group->GetUnits().size() > 0) { - CombatUnit* unit = 0; - - for (int i = 0; i < group->GetUnits().size(); i++) { - unit = group->GetUnits().at(i); - - if (unit->Count() - unit->DeadCount() > 0) - break; - } - - // draw unit icon: - if (unit->GetRegion() == rgn->Name() && unit->Type() > Ship::LCA && unit->Count() > 0) { - double sx = (unit->Location().x + rlx) * scale; - double sy = (unit->Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, unit->MarkerColor()); - sprite_width = 2; - - char buf[256]; - sprintf_s(buf, "%s", unit->Name().data()); - window->SetFont(font); - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, buf); - } - else { - int sprite_index = 2; - int nsprites = 0; - - if (unit->GetDesign()) - nsprites = unit->GetDesign()->map_sprites.size(); - - if (nsprites) { - if (sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = unit->GetDesign()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, unit->MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - if (unit->IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, unit->MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (unit->IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, unit->MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, unit->MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - char label[128]; - strcpy_s(label, unit->GetDescription()); - window->SetFont(font); - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label); - } - } - } - } - - // recurse - ListIter<CombatGroup> iter = group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - DrawCombatGroup(g, rep); - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsClutter(Ship& test) -{ - // get leader: - Ship* lead = test.GetLeader(); - - if (lead == &test) // this is the leader: - return false; - - // too close? - if (lead) { - POINT testloc, leadloc; - - GetShipLoc(test, testloc); - GetShipLoc(*lead, leadloc); - - double dx = testloc.x - leadloc.x; - double dy = testloc.y - leadloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsCrowded(Ship& test) -{ - POINT testloc, refloc; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = sim->FindRegion(rgn->Name()); - - if (simrgn) { - GetShipLoc(test, testloc); - - ListIter<Ship> s = simrgn->Ships(); - while (++s) { - Ship* ref = s.value(); - - // too close? - if (ref && ref != &test) { - GetShipLoc(*ref, refloc); - - double dx = testloc.x - refloc.x; - double dy = testloc.y - refloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - } - } - - return false; -} - -void -MapView::GetShipLoc(Ship& s, POINT& shiploc) -{ - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = system->Radius() * zoom; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - if (view_mode == VIEW_SYSTEM) { - rgn = system->ActiveRegion(); - - if (rgn) { - rlx = rgn->Location().x; - rly = rgn->Location().y; - } - } - - if (view_mode == VIEW_SYSTEM || - (view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion())) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - } - else { - shiploc.x = -1; - shiploc.y = -1; - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsCrowded(MissionElement& test) -{ - POINT testloc, refloc; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - - if (mission) { - GetElemLoc(test, testloc); - - ListIter<MissionElement> s = mission->GetElements(); - while (++s) { - MissionElement* ref = s.value(); - - if (ref && ref != &test && !_stricmp(ref->Region(), rgn->Name())) { - GetElemLoc(*ref, refloc); - - double dx = testloc.x - refloc.x; - double dy = testloc.y - refloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - } - } - - return false; -} - -void -MapView::GetElemLoc(MissionElement& s, POINT& shiploc) -{ - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx<cy) ? cx : cy; - r = system->Radius() * zoom; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - if (view_mode == VIEW_SYSTEM) { - rgn = system->ActiveRegion(); - - if (rgn) { - rlx = rgn->Location().x; - rly = rgn->Location().y; - } - } - - if (view_mode == VIEW_SYSTEM || - (view_mode == VIEW_REGION && !_stricmp(s.Region(), rgn->Name()))) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - } - else { - shiploc.x = -1; - shiploc.y = -1; - } -} - -// +--------------------------------------------------------------------+ - -OrbitalRegion* -MapView::GetRegion() const -{ - OrbitalRegion* result = 0; - - if (current_region < regions.size()) - result = (OrbitalRegion*) regions[current_region]; - - return result; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ZoomIn() -{ - zoom *= 0.9; - - if (view_mode == VIEW_SYSTEM) { - if (system && zoom * system->Radius() < 2e6) { - zoom = 2e6 / system->Radius(); - } - } - else if (view_mode == VIEW_REGION) { - OrbitalRegion* rgn = GetRegion(); - if (rgn && zoom * rgn->Radius() < 1e3) { - zoom = 1e3 / rgn->Radius(); - } - } -} - -void -MapView::ZoomOut() -{ - zoom *= 1.1; - - if (view_mode == VIEW_SYSTEM) { - if (system && zoom * system->Radius() > 500e9) { - zoom = 500e9 / system->Radius(); - } - } - else if (view_mode == VIEW_REGION) { - OrbitalRegion* rgn = GetRegion(); - if (rgn && zoom * rgn->Radius() > 1e6) { - zoom = 1e6 / rgn->Radius(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::OnShow() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->Register(this); -} - -void -MapView::OnHide() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->Unregister(this); - - if (captured) { - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - dragging = false; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsEnabled() const -{ - if (active_window) - return active_window->IsEnabled(); - - return false; -} - -bool -MapView::IsVisible() const -{ - if (active_window) - return active_window->IsVisible(); - - return false; -} - -bool -MapView::IsFormActive() const -{ - if (active_window) - return active_window->IsFormActive(); - - return false; -} - -Rect -MapView::TargetRect() const -{ - if (active_window) - return active_window->TargetRect(); - - return Rect(); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnMouseMove(int x, int y) -{ - if (captured) { - EventTarget* test = 0; - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - test = dispatch->GetCapture(); - - if (test != this) { - captured = false; - Mouse::Show(true); - } - - else { - if (dragging) { - int delta_x = x - mouse_x; - int delta_y = y - mouse_y; - - offset_x += delta_x * r / c; - offset_y += delta_y * r / c; - - Mouse::SetCursorPos(mouse_x, mouse_y); - } - - else if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if ((adding_navpt || moving_navpt) && current_navpt) { - Point loc = current_navpt->Location(); - loc.x = click_x; - loc.y = click_y; - current_navpt->SetLocation(loc); - current_navpt->SetStatus(current_status); - } - - else if (editor && moving_elem && current_elem) { - Point loc = current_elem->Location(); - loc.x = click_x; - loc.y = click_y; - current_elem->SetLocation(loc); - } - } - } - } - - return active_window->OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnRButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - if (captured) { - dragging = true; - mouse_x = x; - mouse_y = y; - Mouse::Show(false); - } - - return active_window->OnRButtonDown(x, y); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnRButtonUp(int x, int y) -{ - if (captured) { - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - dragging = false; - - return active_window->OnRButtonUp(x, y); -} - -// +--------------------------------------------------------------------+ - -int MapView::OnClick() -{ - return active_window->OnClick(); -} - -int MapView::OnLButtonDown(int x, int y) -{ - if (menu_view && menu_view->IsShown()) { - // ignore this event... - } - else { - if (!captured) - captured = SetCapture(); - - if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if (current_navpt) { - Point nloc = current_navpt->Location(); - double dx = nloc.x - click_x; - double dy = nloc.y - click_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < 5e3) { - moving_navpt = true; - - if (ship && current_ship && ship != current_ship) { - if (ship->GetElement() && current_ship->GetElement()) { - if (!ship->GetElement()->CanCommand(current_ship->GetElement())) { - moving_navpt = false; - } - } - } - else if (current_elem && NetLobby::GetInstance()) { - moving_navpt = false; - } - } - } - - else if (editor && current_elem) { - Point nloc = current_elem->Location(); - double dx = nloc.x - click_x; - double dy = nloc.y - click_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < 5e3) { - moving_elem = true; - - if (current_elem && NetLobby::GetInstance()) { - moving_elem = false; - } - } - } - } - } - - return active_window->OnLButtonDown(x,y); -} - -int MapView::OnLButtonUp(int x, int y) -{ - bool process_event = false; - - if (captured) { - process_event = true; - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - if (process_event && !adding_navpt) { - if (!moving_navpt && !moving_elem) { - Button::PlaySound(); - } - - if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if (!scrolling) - SelectAt(x,y); - - active_window->ClientEvent(EID_MAP_CLICK, x, y); - } - - else if (!scrolling) { - SelectAt(x,y); - - active_window->ClientEvent(EID_MAP_CLICK, x, y); - } - } - - if ((adding_navpt || moving_navpt) && current_navpt) { - current_navpt->SetStatus(current_status); - - Sim* sim = Sim::GetSim(); - if (sim) { - Ship* s = current_ship; - - if (s && s->GetElement()) { - Element* elem = s->GetElement(); - int index = elem->GetNavIndex(current_navpt); - - if (index >= 0) - NetUtil::SendNavData(false, elem, index-1, current_navpt); - } - } - } - - adding_navpt = false; - moving_navpt = false; - moving_elem = false; - - return active_window->OnLButtonUp(x,y); -} - - |