void CameraDirector::SetViewObjectGroup(ListIter<Ship> group, bool quick) { if (!ship) return; Starshatter* stars = Starshatter::GetInstance(); if (!stars->InCutscene()) { // only view solid contacts: while (++group) { Ship* s = group.value(); if (s->GetIFF() != ship->GetIFF()) { Contact* c = ship->FindContact(s); if (!c || !c->ActLock()) return; } if (s->Life() == 0 || s->IsDying() || s->IsDead()) return; } } group.reset(); if (external_group.size() > 1 && external_group.size() == group.size()) { bool same = true; for (int i = 0; same && i < external_group.size(); i++) { if (external_group[i] != group.container()[i]) same = false; } if (same) { SetMode(MODE_ZOOM); return; } } ClearGroup(); if (quick) { mode = MODE_ORBIT; transition = 0; } else { SetMode(MODE_TRANSLATE); } external_group.append(group.container()); ListIter<Ship> iter = external_group; while (++iter) { Ship* s = iter.value(); region = s->GetRegion(); Observe(s); } }
void ListBox::SizeColumns() { ListBoxColumn* c = columns.first(); if (c->percent < 0.001) { double total = 0; ListIter<ListBoxColumn> iter = columns; while (++iter) { c = iter.value(); total += c->width; } iter.reset(); while (++iter) { c = iter.value(); c->percent = c->width / total; } } int usable_width = rect.w; int used = 0; if (IsScrollVisible()) { usable_width -= SCROLL_WIDTH + 2; } else { usable_width -= 3; } for (int i = 0; i < columns.size(); i++) { c = columns[i]; if (i < columns.size() - 1) c->width = (int) (c->percent * usable_width); else c->width = usable_width - used; used += c->width; } }
void MenuView::DrawMenu(int mx, int my, Menu* m) { if (m) { MenuItem* locked_item = 0; Menu* submenu = 0; int subx = 0; int suby = 0; Font* font = FontMgr::Find("HUD"); Rect menu_rect(mx, my, 100, m->NumItems() * 10 + 6); int max_width = 0; int max_height = 0; int extra_width = 16; ListIter<MenuItem> item = m->GetItems(); while (++item) { menu_rect.w = width/2; if (item->GetText().length()) { window->SetFont(font); window->DrawText(item->GetText(), 0, menu_rect, DT_LEFT|DT_SINGLELINE|DT_CALCRECT); if (menu_rect.w > max_width) max_width = menu_rect.w; max_height += 11; if (item->GetSubmenu()) extra_width = 28; if (item->GetSelected() > 1) locked_item = item.value(); } else { max_height += 4; } } menu_rect.h = max_height + 6; menu_rect.w = max_width + extra_width; if (menu_rect.x + menu_rect.w >= width) menu_rect.x = width - menu_rect.w - 2; if (menu_rect.y + menu_rect.h >= height) menu_rect.y = height - menu_rect.h - 2; window->FillRect(menu_rect, back_color * 0.2); window->DrawRect(menu_rect, back_color); Rect item_rect = menu_rect; item_rect.x += 4; item_rect.y += 3; item_rect.w -= 8; item_rect.h = 12; item.reset(); while (++item) { int line_height = 0; if (item->GetText().length()) { Rect fill_rect = item_rect; fill_rect.Inflate(2,-1); fill_rect.y -= 1; int mx = Mouse::X() - offset.x; int my = Mouse::Y() - offset.y; // is this item picked? if (menu_rect.Contains(mx, my)) { if (my >= fill_rect.y && my <= fill_rect.y+fill_rect.h) { if (Mouse::LButton()) { menu_item = item.value(); item->SetSelected(2); if (locked_item && locked_item->GetMenu() == m) locked_item->SetSelected(0); locked_item = menu_item; } else if (!locked_item || locked_item->GetMenu() != m) { item->SetSelected(true); menu_item = item.value(); } if (menu_item && menu_item != selected) { selected = menu_item; Button::PlaySound(Button::SND_MENU_HILITE); } } else if (item.value() != locked_item) { item->SetSelected(false); } } if (item->GetSelected()) { window->FillRect(fill_rect, back_color * 0.35); window->DrawRect(fill_rect, back_color * 0.75); if (item->GetSubmenu()) { submenu = item->GetSubmenu(); subx = menu_rect.x + max_width + extra_width; suby = fill_rect.y - 3; } } if (item->GetEnabled()) font->SetColor(text_color); else font->SetColor(text_color * 0.33); window->SetFont(font); window->DrawText(item->GetText(), 0, item_rect, DT_LEFT|DT_SINGLELINE); line_height = 11; } else { window->DrawLine(item_rect.x, item_rect.y + 2, item_rect.x + max_width + extra_width - 8, item_rect.y + 2, back_color); line_height = 4; } if (item->GetSubmenu()) { int left = item_rect.x + max_width + 10; int top = item_rect.y + 1; // draw the arrow: POINT arrow[3]; arrow[0].x = left; arrow[0].y = top; arrow[1].x = left + 8; arrow[1].y = top + 4; arrow[2].x = left; arrow[2].y = top + 8; window->FillPoly(3, arrow, back_color); } item_rect.y += line_height; } if (submenu) { if (subx + 60 > width) subx = menu_rect.x - 60; DrawMenu(subx, suby, submenu); } } }
void TacticalAI::FindThreat() { // pick the closest contact on Threat Warning System: Ship* threat = 0; Shot* threat_missile = 0; Ship* rumor = 0; double threat_dist = 1e9; const DWORD THREAT_REACTION_TIME = 1000; // 1 second ListIter<Contact> iter = ship->ContactList(); while (++iter) { Contact* contact = iter.value(); if (contact->Threat(ship) && (Game::GameTime() - contact->AcquisitionTime()) > THREAT_REACTION_TIME) { if (contact->GetShot()) { threat_missile = contact->GetShot(); rumor = (Ship*) threat_missile->Owner(); } else { double rng = contact->Range(ship); Ship* c_ship = contact->GetShip(); if (c_ship && !c_ship->InTransition() && c_ship->Class() != Ship::FREIGHTER && c_ship->Class() != Ship::FARCASTER) { if (c_ship->GetTarget() == ship) { if (!threat || c_ship->Class() > threat->Class()) { threat = c_ship; threat_dist = 0; } } else if (rng < threat_dist) { threat = c_ship; threat_dist = rng; } } } } } if (rumor && !rumor->InTransition()) { iter.reset(); while (++iter) { if (iter->GetShip() == rumor) { rumor = 0; ship_ai->ClearRumor(); break; } } } else { rumor = 0; ship_ai->ClearRumor(); } ship_ai->SetRumor(rumor); ship_ai->SetThreat(threat); ship_ai->SetThreatMissile(threat_missile); }
Menu* RadioView::GetRadioMenu(Ship* s) { dst_elem = 0; if (s && sim) { if (s->IsStarship()) { starship_menu->ClearItems(); int n = 0; int page_offset = starship_page*PAGE_SIZE; ListIter<Element> elem = sim->GetElements(); if (num_pages == 0) { while (++elem) { if (elem->IsFinished() || elem->IsSquadron() || elem->IsStatic()) continue; if (ship->GetIFF() == elem->GetIFF() && ship->GetElement() != elem.value()) n++; } num_pages = (n/PAGE_SIZE) + (n%PAGE_SIZE > 0); n = 0; elem.reset(); } while (++elem) { if (elem->IsFinished() || elem->IsSquadron() || elem->IsStatic()) continue; if (ship->GetIFF() == elem->GetIFF() && ship->GetElement() != elem.value()) { if (n >= page_offset && n < page_offset+PAGE_SIZE) { char text[64]; sprintf_s(text, "%d. %s", n+1 - page_offset, (const char*) elem->Name()); if (elem->IsActive()) { starship_menu->AddMenu(text, elem_menu, (DWORD) elem.value()); } else { strcat_s(text, " "); strcat_s(text, Game::GetText("RadioView.item.not-avail").data()); starship_menu->AddItem(text, 0, false); } } n++; } } if (num_pages > 1) { char text[64]; sprintf_s(text, Game::GetText("RadioView.item.next-page").data(), starship_page + 1, num_pages); starship_menu->AddItem(text); } return starship_menu; } else if (s->IsDropship()) { return fighter_menu; } } return 0; }
void Weapon::SelectTarget() { bool select_locked = false; SimObject* targ = 0; double dist = 1e9; double az = 0; double el = 0; if (ammo && enabled && (availability > crit_level)) { ZeroAim(); ListIter<Contact> contact = ship->ContactList(); // lock onto any threatening shots first (if we can): if (design->target_type & Ship::DRONE) { while (++contact) { Shot* c_shot = contact->GetShot(); if (c_shot && contact->Threat(ship)) { // distance from self to target: double distance = Point(c_shot->Location() - muzzle_pts[0]).length(); if (distance > design->min_range && distance < design->max_range && distance < dist) { // check aim basket: select_locked = CanLockPoint(c_shot->Location(), az, el); if (select_locked) { targ = c_shot; dist = distance; } } } } } // lock onto a threatening ship only if it is (much) closer: dist *= 0.2; contact.reset(); while (++contact) { Ship* c_ship = contact->GetShip(); if (!c_ship) continue; // can we lock onto this target? if ((c_ship->IsRogue() || c_ship->GetIFF() > 0 && c_ship->GetIFF() != ship->GetIFF()) && (c_ship->Class() & design->target_type) && c_ship->Weapons().size() > 0) { // distance from self to target: double distance = Point(c_ship->Location() - muzzle_pts[0]).length(); if (distance < design->max_range && distance < dist) { // check aim basket: select_locked = CanLockPoint(c_ship->Location(), az, el); if (select_locked) { targ = c_ship; dist = distance; } } } } } if (!ammo || !enabled) { SetTarget(0,0); locked = false; } else { SetTarget(targ, 0); } }