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);
    }
}
Example #2
0
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);
		}
	}
}
Example #4
0
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;
}
Example #6
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);
    }
}