Files
spacetrader/source/SpaceTraderSource201/Game.cs
T

4430 lines
140 KiB
C#

/*******************************************************************************
*
* Space Trader for Windows 2.00
*
* Copyright (C) 2005 Jay French, All Rights Reserved
*
* Additional coding by David Pierron
* Original coding by Pieter Spronck, Sam Anderson, Samuel Goldstein, Matt Lee
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* If you'd like a copy of the GNU General Public License, go to
* http://www.gnu.org/copyleft/gpl.html.
*
* You can contact the author at spacetrader@frenchfryz.com
*
******************************************************************************/
using System;
using System.Collections;
using System.Windows.Forms;
namespace Fryz.Apps.SpaceTrader
{
public class Game : STSerializableObject
{
#region Member Declarations
private static Game _game;
// Game Data
private StarSystem[] _universe;
private int[] _wormholes = new int[6];
private CrewMember[] _mercenaries = new CrewMember[Strings.CrewMemberNames.Length];
private Commander _commander;
private Ship _dragonfly = new Ship(ShipType.Dragonfly);
private Ship _scarab = new Ship(ShipType.Scarab);
private Ship _scorpion = new Ship(ShipType.Scorpion);
private Ship _spaceMonster = new Ship(ShipType.SpaceMonster);
private Ship _opponent = new Ship(ShipType.Gnat);
private bool _opponentDisabled = false;
private int _chanceOfTradeInOrbit = 100;
private int _clicks = 0; // Distance from target system, 0 = arrived
private bool _raided = false; // True when the commander has been raided during the trip
private bool _inspected = false; // True when the commander has been inspected during the trip
private bool _tribbleMessage = false; // Is true if the Ship Yard on the current system informed you about the tribbles
private bool _arrivedViaWormhole = false; // flag to indicate whether player arrived on current planet via wormhole
private bool _paidForNewspaper = false; // once you buy a paper on a system, you don't have to pay again.
private bool _litterWarning = false; // Warning against littering has been issued.
private ArrayList _newsEvents = new ArrayList(30);
// Current Selections
private Difficulty _difficulty = Difficulty.Normal; // Difficulty level
private bool _cheatEnabled = false;
private bool _autoSave = false;
private bool _easyEncounters = false;
private GameEndType _endStatus = GameEndType.NA;
private EncounterType _encounterType = 0; // Type of current encounter
private StarSystemId _selectedSystemId = StarSystemId.NA; // Current system on chart
private StarSystemId _warpSystemId = StarSystemId.NA; // Target system for warp
private StarSystemId _trackedSystemId = StarSystemId.NA; // The short-range chart will display an arrow towards this system if the value is not null
private bool _targetWormhole = false; // Wormhole selected?
private int[] _priceCargoBuy = new int[10];
private int[] _priceCargoSell = new int[10];
// Status of Quests
private int _questStatusArtifact = 0; // 0 = not given yet, 1 = Artifact on board, 2 = Artifact no longer on board (either delivered or lost)
private int _questStatusDragonfly = 0; // 0 = not available, 1 = Go to Baratas, 2 = Go to Melina, 3 = Go to Regulas, 4 = Go to Zalkon, 5 = Dragonfly destroyed, 6 = Got Shield
private int _questStatusExperiment = 0; // 0 = not given yet, 1-11 = days from start; 12 = performed, 13 = cancelled
private int _questStatusGemulon = 0; // 0 = not given yet, 1-7 = days from start, 8 = too late, 9 = in time, 10 = done
private int _questStatusJapori = 0; // 0 = no disease, 1 = Go to Japori (always at least 10 medicine cannisters), 2 = Assignment finished or canceled
private int _questStatusJarek = 0; // 0 = not delivered, 1-11 = on board, 12 = delivered
private int _questStatusMoon = 0; // 0 = not bought, 1 = bought, 2 = claimed
private int _questStatusPrincess = 0; // 0 = not available, 1 = Go to Centauri, 2 = Go to Inthara, 3 = Go to Qonos, 4 = Princess Rescued, 5-14 = On Board, 15 = Princess Returned, 16 = Got Quantum Disruptor
private int _questStatusReactor = 0; // 0 = not encountered, 1-20 = days of mission (bays of fuel left = 10 - (ReactorStatus / 2), 21 = delivered, 22 = Done
private int _questStatusScarab = 0; // 0 = not given yet, 1 = not destroyed, 2 = destroyed - upgrade not performed, 3 = destroyed - hull upgrade performed
private int _questStatusSculpture = 0; // 0 = not given yet, 1 = on board, 2 = delivered, 3 = done
private int _questStatusSpaceMonster = 0; // 0 = not available, 1 = Space monster is in Acamar system, 2 = Space monster is destroyed, 3 = Claimed reward
private int _questStatusWild = 0; // 0 = not delivered, 1-11 = on board, 12 = delivered
private int _fabricRipProbability = 0; // if Experiment = 12, this is the probability of being warped to a random planet.
private bool _justLootedMarie = false; // flag to indicate whether player looted Marie Celeste
private bool _canSuperWarp = false; // Do you have the Portable Singularity on board?
private int _chanceOfVeryRareEncounter = 5;
private ArrayList _veryRareEncounters = new ArrayList(6); // Array of Very Rare encounters not done yet.
// Options
private GameOptions _options = new GameOptions(true);
// The rest of the member variables are not saved between games.
private SpaceTrader _parentWin = null;
private bool _encounterContinueFleeing = false;
private bool _encounterContinueAttacking = false;
private bool _encounterCmdrFleeing = false;
private bool _encounterCmdrHit = false;
private bool _encounterOppFleeingPrev = false;
private bool _encounterOppFleeing = false;
private bool _encounterOppHit = false;
#endregion
#region Methods
public Game(string name, Difficulty difficulty, int pilot, int fighter, int trader, int engineer, SpaceTrader parentWin)
{
_game = this;
_parentWin = parentWin;
_difficulty = difficulty;
// Keep Generating a new universe until PlaceSpecialEvents and PlaceShipyards return true,
// indicating all special events and shipyards were placed.
do
GenerateUniverse();
while (!(PlaceSpecialEvents() && PlaceShipyards()));
InitializeCommander(name, new CrewMember(CrewMemberId.Commander, pilot, fighter, trader, engineer, StarSystemId.NA));
GenerateCrewMemberList();
CreateShips();
CalculatePrices(Commander.CurrentSystem);
ResetVeryRareEncounters();
if (Difficulty < Difficulty.Normal)
Commander.CurrentSystem.SpecialEventType = SpecialEventType.Lottery;
// TODO: JAF - DEBUG
/*
Commander.Cash = 1000000;
CheatEnabled = true;
EasyEncounters = true;
*/
}
public Game(Hashtable hash, SpaceTrader parentWin): base(hash)
{
_game = this;
_parentWin = parentWin;
string version = (string)GetValueFromHash(hash, "_version");
if (version.CompareTo(Consts.CurrentVersion) > 0)
throw new FutureVersionException();
_universe = (StarSystem[])ArrayListToArray((ArrayList)GetValueFromHash(hash, "_universe"), "StarSystem");
_wormholes = (int[])GetValueFromHash(hash, "_wormholes", _wormholes);
_mercenaries = (CrewMember[])ArrayListToArray((ArrayList)GetValueFromHash(hash, "_mercenaries"), "CrewMember");
_commander = new Commander((Hashtable)GetValueFromHash(hash, "_commander"));
_dragonfly = new Ship((Hashtable)GetValueFromHash(hash, "_dragonfly", _dragonfly.Serialize()));
_scarab = new Ship((Hashtable)GetValueFromHash(hash, "_scarab", _scarab.Serialize()));
_scorpion = new Ship((Hashtable)GetValueFromHash(hash, "_scorpion", _scorpion.Serialize()));
_spaceMonster = new Ship((Hashtable)GetValueFromHash(hash, "_spaceMonster", _spaceMonster.Serialize()));
_opponent = new Ship((Hashtable)GetValueFromHash(hash, "_opponent", _opponent.Serialize()));
_chanceOfTradeInOrbit = (int)GetValueFromHash(hash, "_chanceOfTradeInOrbit", _chanceOfTradeInOrbit);
_clicks = (int)GetValueFromHash(hash, "_clicks", _clicks);
_raided = (bool)GetValueFromHash(hash, "_raided", _raided);
_inspected = (bool)GetValueFromHash(hash, "_inspected", _inspected);
_tribbleMessage = (bool)GetValueFromHash(hash, "_tribbleMessage", _tribbleMessage);
_arrivedViaWormhole = (bool)GetValueFromHash(hash, "_arrivedViaWormhole", _arrivedViaWormhole);
_paidForNewspaper = (bool)GetValueFromHash(hash, "_paidForNewspaper", _paidForNewspaper);
_litterWarning = (bool)GetValueFromHash(hash, "_litterWarning", _litterWarning);
_newsEvents = new ArrayList((int[])GetValueFromHash(hash, "_newsEvents", _newsEvents.ToArray(System.Type.GetType("System.Int32"))));
_difficulty = (Difficulty)GetValueFromHash(hash, "_difficulty", _difficulty);
_cheatEnabled = (bool)GetValueFromHash(hash, "_cheatEnabled", _cheatEnabled);
_autoSave = (bool)GetValueFromHash(hash, "_autoSave", _autoSave);
_easyEncounters = (bool)GetValueFromHash(hash, "_easyEncounters", _easyEncounters);
_endStatus = (GameEndType)GetValueFromHash(hash, "_endStatus", _endStatus);
_encounterType = (EncounterType)GetValueFromHash(hash, "_encounterType", _encounterType);
_selectedSystemId = (StarSystemId)GetValueFromHash(hash, "_selectedSystemId", _selectedSystemId);
_warpSystemId = (StarSystemId)GetValueFromHash(hash, "_warpSystemId", _warpSystemId);
_trackedSystemId = (StarSystemId)GetValueFromHash(hash, "_trackedSystemId", _trackedSystemId);
_targetWormhole = (bool)GetValueFromHash(hash, "_targetWormhole", _targetWormhole);
_priceCargoBuy = (int[])GetValueFromHash(hash, "_priceCargoBuy", _priceCargoBuy);
_priceCargoSell = (int[])GetValueFromHash(hash, "_priceCargoSell", _priceCargoSell);
_questStatusArtifact = (int)GetValueFromHash(hash, "_questStatusArtifact", _questStatusArtifact);
_questStatusDragonfly = (int)GetValueFromHash(hash, "_questStatusDragonfly", _questStatusDragonfly);
_questStatusExperiment = (int)GetValueFromHash(hash, "_questStatusExperiment", _questStatusExperiment);
_questStatusGemulon = (int)GetValueFromHash(hash, "_questStatusGemulon", _questStatusGemulon);
_questStatusJapori = (int)GetValueFromHash(hash, "_questStatusJapori", _questStatusJapori);
_questStatusJarek = (int)GetValueFromHash(hash, "_questStatusJarek", _questStatusJarek);
_questStatusMoon = (int)GetValueFromHash(hash, "_questStatusMoon", _questStatusMoon);
_questStatusPrincess = (int)GetValueFromHash(hash, "_questStatusPrincess", _questStatusPrincess);
_questStatusReactor = (int)GetValueFromHash(hash, "_questStatusReactor", _questStatusReactor);
_questStatusScarab = (int)GetValueFromHash(hash, "_questStatusScarab", _questStatusScarab);
_questStatusSculpture = (int)GetValueFromHash(hash, "_questStatusSculpture", _questStatusSculpture);
_questStatusSpaceMonster = (int)GetValueFromHash(hash, "_questStatusSpaceMonster", _questStatusSpaceMonster);
_questStatusWild = (int)GetValueFromHash(hash, "_questStatusWild", _questStatusWild);
_fabricRipProbability = (int)GetValueFromHash(hash, "_fabricRipProbability", _fabricRipProbability);
_justLootedMarie = (bool)GetValueFromHash(hash, "_justLootedMarie", _justLootedMarie);
_canSuperWarp = (bool)GetValueFromHash(hash, "_canSuperWarp", _canSuperWarp);
_chanceOfVeryRareEncounter = (int)GetValueFromHash(hash, "_chanceOfVeryRareEncounter", _chanceOfVeryRareEncounter);
_veryRareEncounters = new ArrayList((int[])GetValueFromHash(hash, "_veryRareEncounters", _veryRareEncounters.ToArray(System.Type.GetType("System.Int32"))));
_options = new GameOptions((Hashtable)GetValueFromHash(hash, "_options", _options.Serialize()));
}
public void Arrested()
{
int term = Math.Max(30, -Commander.PoliceRecordScore);
int fine = (1 + Commander.Worth * Math.Min(80, -Commander.PoliceRecordScore) / 50000) * 500;
if (Commander.Ship.WildOnBoard)
fine = (int)(fine * 1.05);
FormAlert.Alert(AlertType.EncounterArrested, ParentWindow);
FormAlert.Alert(AlertType.JailConvicted, ParentWindow, Functions.Multiples(term, Strings.TimeUnit),
Functions.Multiples(fine, Strings.MoneyUnit));
if (Commander.Ship.HasGadget(GadgetType.HiddenCargoBays))
{
while (Commander.Ship.HasGadget(GadgetType.HiddenCargoBays))
Commander.Ship.RemoveEquipment(EquipmentType.Gadget, GadgetType.HiddenCargoBays);
FormAlert.Alert(AlertType.JailHiddenCargoBaysRemoved, ParentWindow);
}
if (Commander.Ship.ReactorOnBoard)
{
FormAlert.Alert(AlertType.ReactorConfiscated, ParentWindow);
QuestStatusReactor = SpecialEvent.StatusReactorNotStarted;
}
if (Commander.Ship.SculptureOnBoard)
{
FormAlert.Alert(AlertType.SculptureConfiscated, ParentWindow);
QuestStatusSculpture = SpecialEvent.StatusSculptureNotStarted;
}
if (Commander.Ship.WildOnBoard)
{
FormAlert.Alert(AlertType.WildArrested, ParentWindow);
NewsAddEvent(NewsEvent.WildArrested);
QuestStatusWild = SpecialEvent.StatusWildNotStarted;
}
if (Commander.Ship.AnyIllegalCargo)
{
FormAlert.Alert(AlertType.JailIllegalGoodsImpounded, ParentWindow);
Commander.Ship.RemoveIllegalGoods();
}
if (Commander.Insurance)
{
FormAlert.Alert(AlertType.JailInsuranceLost, ParentWindow);
Commander.Insurance = false;
Commander.NoClaim = 0;
}
if (Commander.Ship.CrewCount - Commander.Ship.SpecialCrew.Length > 1)
{
FormAlert.Alert(AlertType.JailMercenariesLeave, ParentWindow);
for (int i = 1; i < Commander.Ship.Crew.Length; i++)
Commander.Ship.Crew[i] = null;
}
if (Commander.Ship.JarekOnBoard)
{
FormAlert.Alert(AlertType.JarekTakenHome, ParentWindow);
QuestStatusJarek = SpecialEvent.StatusJarekNotStarted;
}
if (Commander.Ship.PrincessOnBoard)
{
FormAlert.Alert(AlertType.PrincessTakenHome, ParentWindow);
QuestStatusPrincess = SpecialEvent.StatusPrincessNotStarted;
}
if (QuestStatusJapori == SpecialEvent.StatusJaporiInTransit)
{
FormAlert.Alert(AlertType.AntidoteTaken, ParentWindow);
QuestStatusJapori = SpecialEvent.StatusJaporiDone;
}
if (Commander.Cash >= fine)
Commander.Cash -= fine;
else
{
Commander.Cash = Math.Max(0, Commander.Cash + Commander.Ship.Worth(true) - fine);
FormAlert.Alert(AlertType.JailShipSold, ParentWindow);
if (Commander.Ship.Tribbles > 0)
FormAlert.Alert(AlertType.TribblesRemoved, ParentWindow);
FormAlert.Alert(AlertType.FleaBuilt, ParentWindow);
CreateFlea();
}
if (Commander.Debt > 0)
{
int paydown = Math.Min(Commander.Cash, Commander.Debt);
Commander.Debt -= paydown;
Commander.Cash -= paydown;
if (Commander.Debt > 0)
for (int i = 0; i < term; i++)
Commander.PayInterest();
}
Commander.PoliceRecordScore = Consts.PoliceRecordScoreDubious;
IncDays(term, ParentWindow);
}
private void Arrival()
{
Commander.CurrentSystem = WarpSystem;
Commander.CurrentSystem.Visited = true;
PaidForNewspaper = false;
if (TrackedSystem == Commander.CurrentSystem && Options.TrackAutoOff)
TrackedSystemId = StarSystemId.NA;
ArrivalCheckReactor();
ArrivalCheckTribbles();
ArrivalCheckDebt();
ArrivalPerformRepairs();
ArrivalUpdatePressuresAndQuantities();
ArrivalCheckEasterEgg();
CalculatePrices(Commander.CurrentSystem);
NewsAddEventsOnArrival();
if (Options.NewsAutoShow)
ShowNewspaper();
}
private void ArrivalCheckDebt()
{
// Check for Large Debt - 06/30/01 SRA
if (Commander.Debt >= Consts.DebtWarning)
FormAlert.Alert(AlertType.DebtWarning, ParentWindow);
// Debt Reminder
else if (Commander.Debt > 0 && Options.RemindLoans && Commander.Days % 5 == 0)
FormAlert.Alert(AlertType.DebtReminder, ParentWindow, Functions.Multiples(Commander.Debt, Strings.MoneyUnit));
}
private void ArrivalCheckEasterEgg()
{
/* This Easter Egg gives the commander a Lighting Shield */
if (Commander.CurrentSystem.Id == StarSystemId.Og)
{
bool egg = true;
for (int i = 0; i < Commander.Ship.Cargo.Length && egg; i++)
if (Commander.Ship.Cargo[i] != 1)
egg = false;
if (egg && Commander.Ship.FreeSlotsShield > 0)
{
FormAlert.Alert(AlertType.Egg, ParentWindow);
Commander.Ship.AddEquipment(Consts.Shields[(int)ShieldType.Lightning]);
for (int i = 0; i < Commander.Ship.Cargo.Length; i++)
{
Commander.Ship.Cargo[i] = 0;
Commander.PriceCargo[i] = 0;
}
}
}
}
private void ArrivalCheckReactor()
{
if (QuestStatusReactor == SpecialEvent.StatusReactorDate)
{
FormAlert.Alert(AlertType.ReactorMeltdown, ParentWindow);
QuestStatusReactor = SpecialEvent.StatusReactorNotStarted;
if (Commander.Ship.EscapePod)
EscapeWithPod();
else
{
FormAlert.Alert(AlertType.ReactorDestroyed, ParentWindow);
throw new GameEndException(GameEndType.Killed);
}
}
else
{
// Reactor warnings:
// now they know the quest has a time constraint!
if (QuestStatusReactor == SpecialEvent.StatusReactorFuelOk + 1)
FormAlert.Alert(AlertType.ReactorWarningFuel, ParentWindow);
// better deliver it soon!
else if (QuestStatusReactor == SpecialEvent.StatusReactorDate - 4)
FormAlert.Alert(AlertType.ReactorWarningFuelGone, ParentWindow);
// last warning!
else if (QuestStatusReactor == SpecialEvent.StatusReactorDate - 2)
FormAlert.Alert(AlertType.ReactorWarningTemp, ParentWindow);
}
}
private void ArrivalCheckTribbles()
{
Ship ship = Commander.Ship;
if (ship.Tribbles > 0)
{
int previousTribbles = ship.Tribbles;
int narc = (int)TradeItemType.Narcotics;
int food = (int)TradeItemType.Food;
if (ship.ReactorOnBoard)
{
if (ship.Tribbles < 20)
{
ship.Tribbles = 0;
FormAlert.Alert(AlertType.TribblesAllDied, ParentWindow);
}
else
{
ship.Tribbles /= 2;
FormAlert.Alert(AlertType.TribblesHalfDied, ParentWindow);
}
}
else if (ship.Cargo[narc] > 0)
{
int dead = Math.Min(1 + Functions.GetRandom(3), ship.Cargo[narc]);
Commander.PriceCargo[narc] = Commander.PriceCargo[narc] * (ship.Cargo[narc] - dead) / ship.Cargo[narc];
ship.Cargo[narc] -= dead;
ship.Cargo[(int)TradeItemType.Furs] += dead;
ship.Tribbles -= Math.Min(dead * (Functions.GetRandom(5) + 98), ship.Tribbles - 1);
FormAlert.Alert(AlertType.TribblesMostDied, ParentWindow);
}
else
{
if (ship.Cargo[food] > 0 && ship.Tribbles < Consts.MaxTribbles)
{
int eaten = ship.Cargo[food] - Functions.GetRandom(ship.Cargo[food]);
Commander.PriceCargo[food] -= Commander.PriceCargo[food] * eaten / ship.Cargo[food];
ship.Cargo[food] -= eaten;
ship.Tribbles += eaten * 100;
FormAlert.Alert(AlertType.TribblesAteFood, ParentWindow);
}
if (ship.Tribbles < Consts.MaxTribbles)
ship.Tribbles += 1 + Functions.GetRandom(ship.Cargo[food] > 0 ? ship.Tribbles : ship.Tribbles / 2);
if (ship.Tribbles > Consts.MaxTribbles)
ship.Tribbles = Consts.MaxTribbles;
if ((previousTribbles < 100 && ship.Tribbles >= 100) ||
(previousTribbles < 1000 && ship.Tribbles >= 1000) ||
(previousTribbles < 10000 && ship.Tribbles >= 10000) ||
(previousTribbles < 50000 && ship.Tribbles >= 50000) ||
(previousTribbles < Consts.MaxTribbles && ship.Tribbles == Consts.MaxTribbles))
{
string qty = ship.Tribbles == Consts.MaxTribbles ? Strings.TribbleDangerousNumber :
Functions.FormatNumber(ship.Tribbles);
FormAlert.Alert(AlertType.TribblesInspector, ParentWindow, qty);
}
}
TribbleMessage = false;
}
}
private void ArrivalPerformRepairs()
{
Ship ship = Commander.Ship;
if (ship.Hull < ship.HullStrength)
ship.Hull += Math.Min(ship.HullStrength - ship.Hull, Functions.GetRandom(ship.Engineer));
for (int i = 0; i < ship.Shields.Length; ++i)
if (ship.Shields[i] != null)
ship.Shields[i].Charge = ship.Shields[i].Power;
bool fuelOk = true;
int toAdd = ship.FuelTanks - ship.Fuel;
if (Options.AutoFuel && toAdd > 0)
{
if (Commander.Cash >= toAdd * ship.FuelCost)
{
ship.Fuel += toAdd;
Commander.Cash -= toAdd * ship.FuelCost;
}
else
fuelOk = false;
}
bool repairOk = true;
toAdd = ship.HullStrength - ship.Hull;
if (Options.AutoRepair && toAdd > 0)
{
if (Commander.Cash >= toAdd * ship.RepairCost)
{
ship.Hull += toAdd;
Commander.Cash -= toAdd * ship.RepairCost;
}
else
repairOk = false;
}
if (!fuelOk && !repairOk)
FormAlert.Alert(AlertType.ArrivalIFFuelRepairs, ParentWindow);
else if (!fuelOk)
FormAlert.Alert(AlertType.ArrivalIFFuel, ParentWindow);
else if (!repairOk)
FormAlert.Alert(AlertType.ArrivalIFRepairs, ParentWindow);
}
private void ArrivalUpdatePressuresAndQuantities()
{
for (int i = 0; i < Universe.Length; i++)
{
if (Functions.GetRandom(100) < 15)
Universe[i].SystemPressure = Universe[i].SystemPressure == SystemPressure.None ?
(SystemPressure)Functions.GetRandom((int)SystemPressure.War,
(int)SystemPressure.Employment + 1) : SystemPressure.None;
if (Universe[i].CountDown > 0)
{
Universe[i].CountDown--;
if (Universe[i].CountDown > CountDownStart)
Universe[i].CountDown = CountDownStart;
else if (Universe[i].CountDown <= 0)
Universe[i].InitializeTradeItems();
else
{
for (int j = 0; j < Consts.TradeItems.Length; j++)
{
if (WarpSystem.ItemTraded(Consts.TradeItems[j]))
Universe[i].TradeItems[j] = Math.Max(0, Universe[i].TradeItems[j] + Functions.GetRandom(-4, 5));
}
}
}
}
}
private void CalculatePrices(StarSystem system)
{
for (int i = 0; i < Consts.TradeItems.Length; i++)
{
int price = Consts.TradeItems[i].StandardPrice(system);
if (price > 0)
{
// In case of a special status, adapt price accordingly
if (Consts.TradeItems[i].PressurePriceHike == system.SystemPressure)
price = price * 3 / 2;
// Randomize price a bit
int variance = Math.Min(Consts.TradeItems[i].PriceVariance, price - 1);
price = price + Functions.GetRandom(-variance, variance + 1);
// Criminals have to pay off an intermediary
if (Commander.PoliceRecordScore < Consts.PoliceRecordScoreDubious)
price = price * 90 / 100;
}
_priceCargoSell[i] = price;
}
RecalculateBuyPrices(system);
}
private void CargoBuy(int tradeItem, bool max, IWin32Window owner, CargoBuyOp op)
{
int freeBays = Commander.Ship.FreeCargoBays;
int[] items = null;
int unitPrice = 0;
int cashToSpend = Commander.Cash;
switch (op)
{
case CargoBuyOp.BuySystem:
freeBays = Math.Max(0, Commander.Ship.FreeCargoBays - Options.LeaveEmpty);
items = Commander.CurrentSystem.TradeItems;
unitPrice = PriceCargoBuy[tradeItem];
cashToSpend = Commander.CashToSpend;
break;
case CargoBuyOp.BuyTrader:
items = Opponent.Cargo;
TradeItem item = Consts.TradeItems[tradeItem];
int chance = item.Illegal ? 45 : 10;
double adj = Functions.GetRandom(100) < chance ? 1.1 : (item.Illegal ? 0.8 : 0.9);
unitPrice = Math.Min(item.MaxTradePrice, Math.Max(item.MinTradePrice,
(int)Math.Round(PriceCargoBuy[tradeItem] * adj / item.RoundOff) * item.RoundOff));
break;
case CargoBuyOp.Plunder:
items = Opponent.Cargo;
break;
}
if (op == CargoBuyOp.BuySystem && Commander.Debt > Consts.DebtTooLarge)
FormAlert.Alert(AlertType.DebtTooLargeTrade, owner);
else if (op == CargoBuyOp.BuySystem && (items[tradeItem] <= 0 || unitPrice <= 0))
FormAlert.Alert(AlertType.CargoNoneAvailable, owner);
else if (freeBays == 0)
FormAlert.Alert(AlertType.CargoNoEmptyBays, owner);
else if (op != CargoBuyOp.Plunder && cashToSpend < unitPrice)
FormAlert.Alert(AlertType.CargoIF, owner);
else
{
int qty = 0;
int maxAmount = Math.Min(freeBays, items[tradeItem]);
if (op == CargoBuyOp.BuySystem)
maxAmount = Math.Min(maxAmount, Commander.CashToSpend / unitPrice);
if (max)
qty = maxAmount;
else
{
FormCargoBuy form = new FormCargoBuy(tradeItem, maxAmount, op);
if (form.ShowDialog(owner) == DialogResult.OK)
qty = form.Amount;
}
if (qty > 0)
{
int totalPrice = qty * unitPrice;
Commander.Ship.Cargo[tradeItem] += qty;
items[tradeItem] -= qty;
Commander.Cash -= totalPrice;
Commander.PriceCargo[tradeItem] += totalPrice;
}
}
}
public void CargoBuySystem(int tradeItem, bool max, IWin32Window owner)
{
CargoBuy(tradeItem, max, owner, CargoBuyOp.BuySystem);
}
public void CargoBuyTrader(int tradeItem, IWin32Window owner)
{
CargoBuy(tradeItem, false, owner, CargoBuyOp.BuyTrader);
}
public void CargoPlunder(int tradeItem, bool max, IWin32Window owner)
{
CargoBuy(tradeItem, max, owner, CargoBuyOp.Plunder);
}
public void CargoDump(int tradeItem, IWin32Window owner)
{
CargoSell(tradeItem, false, owner, CargoSellOp.Dump);
}
public void CargoJettison(int tradeItem, bool all, IWin32Window owner)
{
CargoSell(tradeItem, all, owner, CargoSellOp.Jettison);
}
public void CargoSellSystem(int tradeItem, bool all, IWin32Window owner)
{
CargoSell(tradeItem, all, owner, CargoSellOp.SellSystem);
}
private void CargoSell(int tradeItem, bool all, IWin32Window owner, CargoSellOp op)
{
int qtyInHand = Commander.Ship.Cargo[tradeItem];
int unitPrice;
switch (op)
{
case CargoSellOp.SellSystem:
unitPrice = PriceCargoSell[tradeItem];
break;
case CargoSellOp.SellTrader:
TradeItem item = Consts.TradeItems[tradeItem];
int chance = item.Illegal ? 45 : 10;
double adj = Functions.GetRandom(100) < chance ? (item.Illegal ? 0.8 : 0.9) : 1.1;
unitPrice = Math.Min(item.MaxTradePrice, Math.Max(item.MinTradePrice,
(int)Math.Round(PriceCargoSell[tradeItem] * adj / item.RoundOff) * item.RoundOff));
break;
default:
unitPrice = 0;
break;
}
if (qtyInHand == 0)
FormAlert.Alert(AlertType.CargoNoneToSell, owner, Strings.CargoSellOps[(int)op]);
else if (op == CargoSellOp.SellSystem && unitPrice <= 0)
FormAlert.Alert(AlertType.CargoNotInterested, owner);
else
{
if (op != CargoSellOp.Jettison || LitterWarning ||
Commander.PoliceRecordScore <= Consts.PoliceRecordScoreDubious ||
FormAlert.Alert(AlertType.EncounterDumpWarning, owner) == DialogResult.Yes)
{
int unitCost = 0;
int maxAmount = (op == CargoSellOp.SellTrader) ? Math.Min(qtyInHand, Opponent.FreeCargoBays) : qtyInHand;
if (op == CargoSellOp.Dump)
{
unitCost = 5 * ((int)Difficulty + 1);
maxAmount = Math.Min(maxAmount, Commander.CashToSpend / unitCost);
}
int price = unitPrice > 0 ? unitPrice : -unitCost;
int qty = 0;
if (all)
qty = maxAmount;
else
{
FormCargoSell form = new FormCargoSell(tradeItem, maxAmount, op, price);
if (form.ShowDialog(owner) == DialogResult.OK)
qty = form.Amount;
}
if (qty > 0)
{
int totalPrice = qty * price;
Commander.Ship.Cargo[tradeItem] -= qty;
Commander.PriceCargo[tradeItem] = (Commander.PriceCargo[tradeItem] * (qtyInHand - qty)) / qtyInHand;
Commander.Cash += totalPrice;
if (op == CargoSellOp.Jettison)
{
if (Functions.GetRandom(10) < (int)Difficulty + 1)
{
if (Commander.PoliceRecordScore > Consts.PoliceRecordScoreDubious)
Commander.PoliceRecordScore = Consts.PoliceRecordScoreDubious;
else
Commander.PoliceRecordScore--;
NewsAddEvent(NewsEvent.CaughtLittering);
}
}
}
}
}
}
public void CargoSellTrader(int tradeItem, IWin32Window owner)
{
CargoSell(tradeItem, false, owner, CargoSellOp.SellTrader);
}
public void CreateFlea()
{
Commander.Ship = new Ship(ShipType.Flea);
Commander.Ship.Crew[0] = Commander;
Commander.Insurance = false;
Commander.NoClaim = 0;
}
private void CreateShips()
{
Dragonfly.Crew[0] = Mercenaries[(int)CrewMemberId.Dragonfly];
Dragonfly.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
Dragonfly.AddEquipment(Consts.Weapons[(int)WeaponType.PulseLaser]);
Dragonfly.AddEquipment(Consts.Shields[(int)ShieldType.Lightning]);
Dragonfly.AddEquipment(Consts.Shields[(int)ShieldType.Lightning]);
Dragonfly.AddEquipment(Consts.Shields[(int)ShieldType.Lightning]);
Dragonfly.AddEquipment(Consts.Gadgets[(int)GadgetType.AutoRepairSystem]);
Dragonfly.AddEquipment(Consts.Gadgets[(int)GadgetType.TargetingSystem]);
Scarab.Crew[0] = Mercenaries[(int)CrewMemberId.Scarab];
Scarab.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
Scarab.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
Scorpion.Crew[0] = Mercenaries[(int)CrewMemberId.Scorpion];
Scorpion.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
Scorpion.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
Scorpion.AddEquipment(Consts.Shields[(int)ShieldType.Reflective]);
Scorpion.AddEquipment(Consts.Shields[(int)ShieldType.Reflective]);
Scorpion.AddEquipment(Consts.Gadgets[(int)GadgetType.AutoRepairSystem]);
Scorpion.AddEquipment(Consts.Gadgets[(int)GadgetType.TargetingSystem]);
SpaceMonster.Crew[0] = Mercenaries[(int)CrewMemberId.SpaceMonster];
SpaceMonster.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
SpaceMonster.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
SpaceMonster.AddEquipment(Consts.Weapons[(int)WeaponType.MilitaryLaser]);
}
private bool DetermineEncounter()
{
// If there is a specific encounter that needs to happen, it will, otherwise we'll generate a random encounter.
return DetermineNonRandomEncounter() || DetermineRandomEncounter();
}
private bool DetermineNonRandomEncounter()
{
bool showEncounter = false;
// Encounter with space monster
if (Clicks == 1 && WarpSystem.Id == StarSystemId.Acamar &&
QuestStatusSpaceMonster == SpecialEvent.StatusSpaceMonsterAtAcamar)
{
Opponent = SpaceMonster;
EncounterType = Commander.Ship.Cloaked ? EncounterType.SpaceMonsterIgnore : EncounterType.SpaceMonsterAttack;
showEncounter = true;
}
// Encounter with the stolen Scarab
else if (ArrivedViaWormhole && Clicks == 20 && WarpSystem.SpecialEventType != SpecialEventType.NA &&
WarpSystem.SpecialEvent.Type == SpecialEventType.ScarabDestroyed &&
QuestStatusScarab == SpecialEvent.StatusScarabHunting)
{
Opponent = Scarab;
EncounterType = Commander.Ship.Cloaked ? EncounterType.ScarabIgnore : EncounterType.ScarabAttack;
showEncounter = true;
}
// Encounter with stolen Dragonfly
else if (Clicks == 1 && WarpSystem.Id == StarSystemId.Zalkon &&
QuestStatusDragonfly == SpecialEvent.StatusDragonflyFlyZalkon)
{
Opponent = Dragonfly;
EncounterType = Commander.Ship.Cloaked ? EncounterType.DragonflyIgnore : EncounterType.DragonflyAttack;
showEncounter = true;
}
// Encounter with kidnappers in the Scorpion
else if (Clicks == 1 && WarpSystem.Id == StarSystemId.Qonos &&
QuestStatusPrincess == SpecialEvent.StatusPrincessFlyQonos)
{
Opponent = Scorpion;
EncounterType = Commander.Ship.Cloaked ? EncounterType.ScorpionIgnore : EncounterType.ScorpionAttack;
showEncounter = true;
}
// ah, just when you thought you were gonna get away with it...
else if (Clicks == 1 && JustLootedMarie)
{
GenerateOpponent(OpponentType.Police);
EncounterType = EncounterType.MarieCelestePolice;
JustLootedMarie = false;
showEncounter = true;
}
return showEncounter;
}
private bool DeterminePirateEncounter(bool mantis)
{
bool showEncounter = false;
if (mantis)
{
GenerateOpponent(OpponentType.Mantis);
EncounterType = EncounterType.PirateAttack;
}
else
{
GenerateOpponent(OpponentType.Pirate);
// If you have a cloak, they don't see you
if (Commander.Ship.Cloaked)
EncounterType = EncounterType.PirateIgnore;
// Pirates will mostly attack, but they are cowardly: if your rep is too high, they tend to flee
// if Pirates are in a better ship, they won't flee, even if you have a very scary
// reputation.
else if (Opponent.Type > Commander.Ship.Type || Opponent.Type >= ShipType.Grasshopper ||
Functions.GetRandom(Consts.ReputationScoreElite) >
(Commander.ReputationScore * 4) / (1 + (int)Opponent.Type))
EncounterType = EncounterType.PirateAttack;
else
EncounterType = EncounterType.PirateFlee;
}
// If they ignore you or flee and you can't see them, the encounter doesn't take place
// If you automatically don't want to confront someone who ignores you, the
// encounter may not take place
if (EncounterType == EncounterType.PirateAttack || !(Opponent.Cloaked || Options.AlwaysIgnorePirates))
showEncounter = true;
return showEncounter;
}
private bool DeterminePoliceEncounter()
{
bool showEncounter = false;
GenerateOpponent(OpponentType.Police);
// If you are cloaked, they don't see you
EncounterType = EncounterType.PoliceIgnore;
if (!Commander.Ship.Cloaked)
{
if (Commander.PoliceRecordScore < Consts.PoliceRecordScoreDubious)
{
// If you're a criminal, the police will tend to attack
// JAF - fixed this; there was code that didn't do anything.
// if you're suddenly stuck in a lousy ship, Police won't flee even if you
// have a fearsome reputation.
if (Opponent.WeaponStrength() > 0 && (Commander.ReputationScore < Consts.ReputationScoreAverage ||
Functions.GetRandom(Consts.ReputationScoreElite) >
(Commander.ReputationScore / (1 + (int)Opponent.Type))) || Opponent.Type > Commander.Ship.Type)
{
if (Commander.PoliceRecordScore >= Consts.PoliceRecordScoreCriminal)
EncounterType = EncounterType.PoliceSurrender;
else
EncounterType = EncounterType.PoliceAttack;
}
else if (Opponent.Cloaked)
EncounterType = EncounterType.PoliceIgnore;
else
EncounterType = EncounterType.PoliceFlee;
}
else if (!Inspected && (Commander.PoliceRecordScore < Consts.PoliceRecordScoreClean ||
(Commander.PoliceRecordScore < Consts.PoliceRecordScoreLawful &&
Functions.GetRandom(12 - (int)Difficulty) < 1) ||
(Commander.PoliceRecordScore >= Consts.PoliceRecordScoreLawful && Functions.GetRandom(40) == 0)))
{
// If you're reputation is dubious, the police will inspect you
// If your record is clean, the police will inspect you with a chance of 10% on Normal
// If your record indicates you are a lawful trader, the chance on inspection drops to 2.5%
EncounterType = EncounterType.PoliceInspect;
Inspected = true;
}
}
// If they ignore you or flee and you can't see them, the encounter doesn't take place
// If you automatically don't want to confront someone who ignores you, the
// encounter may not take place. Otherwise it will - JAF
if (EncounterType == EncounterType.PoliceAttack || EncounterType == EncounterType.PoliceInspect ||
!(Opponent.Cloaked || Options.AlwaysIgnorePolice))
showEncounter = true;
return showEncounter;
}
private bool DetermineRandomEncounter()
{
bool showEncounter = false;
bool mantis = false;
bool pirate = false;
bool police = false;
bool trader = false;
if (WarpSystem.Id == StarSystemId.Gemulon && QuestStatusGemulon == SpecialEvent.StatusGemulonTooLate)
{
if (Functions.GetRandom(10) > 4)
mantis = true;
}
else
{
// Check if it is time for an encounter
int encounter = Functions.GetRandom(44 - (2 * (int)Difficulty));
int policeModifier = Math.Max(1, 3 - (int)PoliceRecord.GetPoliceRecordFromScore(Commander.PoliceRecordScore).Type);
// encounters are half as likely if you're in a flea.
if (Commander.Ship.Type == ShipType.Flea)
encounter *= 2;
if (encounter < (int)WarpSystem.PoliticalSystem.ActivityPirates)
// When you are already raided, other pirates have little to gain
pirate = !Raided;
else if (encounter < (int)WarpSystem.PoliticalSystem.ActivityPirates +
(int)WarpSystem.PoliticalSystem.ActivityPolice * policeModifier)
// policeModifier adapts itself to your criminal record: you'll
// encounter more police if you are a hardened criminal.
police = true;
else if (encounter < (int)WarpSystem.PoliticalSystem.ActivityPirates +
(int)WarpSystem.PoliticalSystem.ActivityPolice * policeModifier +
(int)WarpSystem.PoliticalSystem.ActivityTraders)
trader = true;
else if (Commander.Ship.WildOnBoard && WarpSystem.Id == StarSystemId.Kravat)
// if you're coming in to Kravat & you have Wild onboard, there'll be swarms o' cops.
police = Functions.GetRandom(100) < 100 / Math.Max(2, Math.Min(4, 5 - (int)Difficulty));
else if (Commander.Ship.ArtifactOnBoard && Functions.GetRandom(20) <= 3)
mantis = true;
}
if (police)
showEncounter = DeterminePoliceEncounter();
else if (pirate || mantis)
showEncounter = DeterminePirateEncounter(mantis);
else if (trader)
showEncounter = DetermineTraderEncounter();
else if (Commander.Days > 10 && Functions.GetRandom(1000) < ChanceOfVeryRareEncounter &&
VeryRareEncounters.Count > 0)
showEncounter = DetermineVeryRareEncounter();
return showEncounter;
}
private bool DetermineTraderEncounter()
{
bool showEncounter = false;
GenerateOpponent(OpponentType.Trader);
// If you are cloaked, they don't see you
EncounterType = EncounterType.TraderIgnore;
if (!Commander.Ship.Cloaked)
{
// If you're a criminal, traders tend to flee if you've got at least some reputation
if (!Commander.Ship.Cloaked && Commander.PoliceRecordScore <= Consts.PoliceRecordScoreCriminal &&
Functions.GetRandom(Consts.ReputationScoreElite) <= (Commander.ReputationScore * 10) / (1 + (int)Opponent.Type))
EncounterType = EncounterType.TraderFlee;
// Will there be trade in orbit?
else if (Functions.GetRandom(1000) < ChanceOfTradeInOrbit)
{
if (Commander.Ship.FreeCargoBays > 0 && Opponent.HasTradeableItems())
EncounterType = EncounterType.TraderSell;
// we fudge on whether the trader has capacity to carry the stuff he's buying.
else if (Commander.Ship.HasTradeableItems())
EncounterType = EncounterType.TraderBuy;
}
}
// If they ignore you or flee and you can't see them, the encounter doesn't take place
// If you automatically don't want to confront someone who ignores you, the
// encounter may not take place; otherwise it will.
if (!Opponent.Cloaked && !(Options.AlwaysIgnoreTraders &&
(EncounterType == EncounterType.TraderIgnore || EncounterType == EncounterType.TraderFlee)) &&
!((EncounterType == EncounterType.TraderBuy || EncounterType == EncounterType.TraderSell) &&
Options.AlwaysIgnoreTradeInOrbit))
showEncounter = true;
return showEncounter;
}
private bool DetermineVeryRareEncounter()
{
bool showEncounter = false;
// Very Rare Random Events:
// 1. Encounter the abandoned Marie Celeste, which you may loot.
// 2. Captain Ahab will trade your Reflective Shield for skill points in Piloting.
// 3. Captain Conrad will trade your Military Laser for skill points in Engineering.
// 4. Captain Huie will trade your Military Laser for points in Trading.
// 5. Encounter an out-of-date bottle of Captain Marmoset's Skill Tonic. This
// will affect skills depending on game difficulty level.
// 6. Encounter a good bottle of Captain Marmoset's Skill Tonic, which will invoke
// IncreaseRandomSkill one or two times, depending on game difficulty.
switch ((VeryRareEncounter)VeryRareEncounters[Functions.GetRandom(VeryRareEncounters.Count)])
{
case VeryRareEncounter.MarieCeleste:
// Marie Celeste cannot be at Acamar, Qonos, or Zalkon as it may cause problems with the
// Space Monster, Scorpion, or Dragonfly
if (Clicks > 1 && Commander.CurrentSystemId != StarSystemId.Acamar &&
Commander.CurrentSystemId != StarSystemId.Zalkon &&
Commander.CurrentSystemId != StarSystemId.Qonos)
{
VeryRareEncounters.Remove(VeryRareEncounter.MarieCeleste);
EncounterType = EncounterType.MarieCeleste;
GenerateOpponent(OpponentType.Trader);
for (int i = 0; i < Opponent.Cargo.Length; i++)
Opponent.Cargo[i] = 0;
Opponent.Cargo[(int)TradeItemType.Narcotics] = Math.Min(Opponent.CargoBays, 5);
showEncounter = true;
}
break;
case VeryRareEncounter.CaptainAhab:
if (Commander.Ship.HasShield(ShieldType.Reflective) && Commander.Pilot < 10 &&
Commander.PoliceRecordScore > Consts.PoliceRecordScoreCriminal)
{
VeryRareEncounters.Remove(VeryRareEncounter.CaptainAhab);
EncounterType = EncounterType.CaptainAhab;
GenerateOpponent(OpponentType.FamousCaptain);
showEncounter = true;
}
break;
case VeryRareEncounter.CaptainConrad:
if (Commander.Ship.HasWeapon(WeaponType.MilitaryLaser, true) && Commander.Engineer < 10 &&
Commander.PoliceRecordScore > Consts.PoliceRecordScoreCriminal)
{
VeryRareEncounters.Remove(VeryRareEncounter.CaptainConrad);
EncounterType = EncounterType.CaptainConrad;
GenerateOpponent(OpponentType.FamousCaptain);
showEncounter = true;
}
break;
case VeryRareEncounter.CaptainHuie:
if (Commander.Ship.HasWeapon(WeaponType.MilitaryLaser, true) && Commander.Trader < 10 &&
Commander.PoliceRecordScore > Consts.PoliceRecordScoreCriminal)
{
VeryRareEncounters.Remove(VeryRareEncounter.CaptainHuie);
EncounterType = EncounterType.CaptainHuie;
GenerateOpponent(OpponentType.FamousCaptain);
showEncounter = true;
}
break;
case VeryRareEncounter.BottleOld:
VeryRareEncounters.Remove(VeryRareEncounter.BottleOld);
EncounterType = EncounterType.BottleOld;
GenerateOpponent(OpponentType.Bottle);
showEncounter = true;
break;
case VeryRareEncounter.BottleGood:
VeryRareEncounters.Remove(VeryRareEncounter.BottleGood);
EncounterType = EncounterType.BottleGood;
GenerateOpponent(OpponentType.Bottle);
showEncounter = true;
break;
}
return showEncounter;
}
public void EncounterBegin()
{
// Set up the encounter variables.
EncounterContinueFleeing =
EncounterContinueAttacking =
OpponentDisabled = false;
}
private void EncounterDefeatDragonfly()
{
Commander.KillsPirate++;
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
QuestStatusDragonfly = SpecialEvent.StatusDragonflyDestroyed;
}
private void EncounterDefeatScarab()
{
Commander.KillsPirate++;
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
QuestStatusScarab = SpecialEvent.StatusScarabDestroyed;
}
private void EncounterDefeatScorpion()
{
Commander.KillsPirate++;
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
QuestStatusPrincess = SpecialEvent.StatusPrincessRescued;
}
public void EncounterDrink(IWin32Window owner)
{
if (FormAlert.Alert(AlertType.EncounterDrinkContents, owner) == DialogResult.Yes)
{
if (EncounterType == EncounterType.BottleGood)
{
// two points if you're on beginner-normal, one otherwise
Commander.IncreaseRandomSkill();
if (Difficulty <= Difficulty.Normal)
Commander.IncreaseRandomSkill();
FormAlert.Alert(AlertType.EncounterTonicConsumedGood, owner);
}
else
{
Commander.TonicTweakRandomSkill();
FormAlert.Alert(AlertType.EncounterTonicConsumedStrange, owner);
}
}
}
public EncounterResult EncounterExecuteAction(IWin32Window owner)
{
EncounterResult result = EncounterResult.Continue;
int prevCmdrHull = Commander.Ship.Hull;
int prevOppHull = Opponent.Hull;
EncounterCmdrHit = false;
EncounterOppHit = false;
EncounterOppFleeingPrev = EncounterOppFleeing;
EncounterOppFleeing = false;
// Fire shots
switch (EncounterType)
{
case EncounterType.DragonflyAttack:
case EncounterType.FamousCaptainAttack:
case EncounterType.MarieCelestePolice:
case EncounterType.PirateAttack:
case EncounterType.PoliceAttack:
case EncounterType.ScarabAttack:
case EncounterType.ScorpionAttack:
case EncounterType.SpaceMonsterAttack:
case EncounterType.TraderAttack:
EncounterCmdrHit = EncounterExecuteAttack(Opponent, Commander.Ship, EncounterCmdrFleeing);
EncounterOppHit = !EncounterCmdrFleeing && EncounterExecuteAttack(Commander.Ship, Opponent, false);
break;
case EncounterType.PirateFlee:
case EncounterType.PirateSurrender:
case EncounterType.PoliceFlee:
case EncounterType.TraderFlee:
case EncounterType.TraderSurrender:
EncounterOppHit = !EncounterCmdrFleeing && EncounterExecuteAttack(Commander.Ship, Opponent, true);
EncounterOppFleeing = true;
break;
default:
EncounterOppHit = !EncounterCmdrFleeing && EncounterExecuteAttack(Commander.Ship, Opponent, false);
break;
}
// Determine whether someone gets destroyed
if (Commander.Ship.Hull <= 0)
{
if (Commander.Ship.EscapePod)
result = EncounterResult.EscapePod;
else
{
FormAlert.Alert(Opponent.Hull <= 0 ? AlertType.EncounterBothDestroyed : AlertType.EncounterYouLose, owner);
result = EncounterResult.Killed;
}
}
else if (OpponentDisabled)
{
if (Opponent.Type == ShipType.Dragonfly || Opponent.Type == ShipType.Scarab || Opponent.Type == ShipType.Scorpion)
{
string str2 = "";
switch (Opponent.Type)
{
case ShipType.Dragonfly:
EncounterDefeatDragonfly();
break;
case ShipType.Scarab:
EncounterDefeatScarab();
break;
case ShipType.Scorpion:
str2 = Strings.EncounterPrincessRescued;
EncounterDefeatScorpion();
break;
}
FormAlert.Alert(AlertType.EncounterDisabledOpponent, owner, EncounterShipText, str2);
Commander.ReputationScore += (int)Opponent.Type / 2 + 1;
result = EncounterResult.Normal;
}
else
{
EncounterUpdateEncounterType(prevCmdrHull, prevOppHull);
EncounterOppFleeing = false;
}
}
else if (Opponent.Hull <= 0)
{
EncounterWon(owner);
result = EncounterResult.Normal;
}
else
{
bool escaped = false;
// Determine whether someone gets away.
if (EncounterCmdrFleeing && (Difficulty == Difficulty.Beginner ||
(Functions.GetRandom(7) + Commander.Ship.Pilot / 3) * 2 >=
Functions.GetRandom(Opponent.Pilot) * (2 + (int)Difficulty)))
{
FormAlert.Alert(EncounterCmdrHit ? AlertType.EncounterEscapedHit : AlertType.EncounterEscaped, owner);
escaped = true;
}
else if (EncounterOppFleeing && Functions.GetRandom(Commander.Ship.Pilot) * 4 <=
Functions.GetRandom(7 + Opponent.Pilot / 3) * 2)
{
FormAlert.Alert(AlertType.EncounterOpponentEscaped, owner);
escaped = true;
}
if (escaped)
result = EncounterResult.Normal;
else
{
// Determine whether the opponent's actions must be changed
EncounterType prevEncounter = EncounterType;
EncounterUpdateEncounterType(prevCmdrHull, prevOppHull);
// Update the opponent fleeing flag.
switch (EncounterType)
{
case EncounterType.PirateFlee:
case EncounterType.PirateSurrender:
case EncounterType.PoliceFlee:
case EncounterType.TraderFlee:
case EncounterType.TraderSurrender:
EncounterOppFleeing = true;
break;
default:
EncounterOppFleeing = false;
break;
}
if (Options.ContinuousAttack && (EncounterCmdrFleeing || !EncounterOppFleeing ||
Options.ContinuousAttackFleeing && (EncounterType == prevEncounter ||
EncounterType != EncounterType.PirateSurrender && EncounterType != EncounterType.TraderSurrender)))
{
if (EncounterCmdrFleeing)
EncounterContinueFleeing = true;
else
EncounterContinueAttacking = true;
}
}
}
return result;
}
private bool EncounterExecuteAttack(Ship attacker, Ship defender, bool fleeing)
{
bool hit = false;
// On beginner level, if you flee, you will escape unharmed.
// Otherwise, Fighterskill attacker is pitted against pilotskill defender; if defender
// is fleeing the attacker has a free shot, but the chance to hit is smaller
// JAF - if the opponent is disabled and attacker has targeting system, they WILL be hit.
if (!(Difficulty == Difficulty.Beginner && defender.CommandersShip && fleeing) &&
(attacker.CommandersShip && OpponentDisabled && attacker.HasGadget(GadgetType.TargetingSystem) ||
Functions.GetRandom(attacker.Fighter + (int)defender.Size) >=
(fleeing ? 2 : 1) * Functions.GetRandom(5 + defender.Pilot / 2)))
{
// If the defender is disabled, it only takes one shot to destroy it completely.
if (attacker.CommandersShip && OpponentDisabled)
defender.Hull = 0;
else
{
int attackerLasers = attacker.WeaponStrength(WeaponType.PulseLaser, WeaponType.MorgansLaser);
int attackerDisruptors = attacker.WeaponStrength(WeaponType.PhotonDisruptor, WeaponType.QuantumDistruptor);
if (defender.Type == ShipType.Scarab)
{
attackerLasers -= attacker.WeaponStrength(WeaponType.BeamLaser, WeaponType.MilitaryLaser);
attackerDisruptors -= attacker.WeaponStrength(WeaponType.PhotonDisruptor, WeaponType.PhotonDisruptor);
}
int attackerWeapons = attackerLasers + attackerDisruptors;
int disrupt = 0;
// Attempt to disable the opponent if they're not already disabled, their shields are down,
// we have disabling weapons, and the option is checked.
if (defender.Disableable && defender.ShieldCharge == 0 && !OpponentDisabled &&
Options.DisableOpponents && attackerDisruptors > 0)
{
disrupt = Functions.GetRandom(attackerDisruptors * (100 + 2 * attacker.Fighter) / 100);
}
else
{
int damage = attackerWeapons == 0 ? 0 :
Functions.GetRandom(attackerWeapons * (100 + 2 * attacker.Fighter) / 100);
if (damage > 0)
{
hit = true;
// Reactor on board -- damage is boosted!
if (defender.ReactorOnBoard)
damage *= (int)(1 + ((int)Difficulty + 1) * (Difficulty < Difficulty.Normal ? 0.25 : 0.33));
// First, shields are depleted
for (int i = 0; i < defender.Shields.Length && defender.Shields[i] != null && damage > 0; i++)
{
int applied = Math.Min(defender.Shields[i].Charge, damage);
defender.Shields[i].Charge -= applied;
damage -= applied;
}
// If there still is damage after the shields have been depleted,
// this is subtracted from the hull, modified by the engineering skill
// of the defender.
// JAF - If the player only has disabling weapons, no damage will be done to the hull.
if (damage > 0)
{
damage = Math.Max(1, damage - Functions.GetRandom(defender.Engineer));
disrupt = damage * attackerDisruptors / attackerWeapons;
// Only that damage coming from Lasers will deplete the hull.
damage -= disrupt;
// At least 2 shots on Normal level are needed to destroy the hull
// (3 on Easy, 4 on Beginner, 1 on Hard or Impossible). For opponents,
// it is always 2.
damage = Math.Min(damage, defender.HullStrength /
(defender.CommandersShip ? Math.Max(1, Difficulty.Impossible - Difficulty) : 2));
// If the hull is hardened, damage is halved.
if (QuestStatusScarab == SpecialEvent.StatusScarabDone)
damage /= 2;
defender.Hull = Math.Max(0, defender.Hull - damage);
}
}
}
// Did the opponent get disabled? (Disruptors are 3 times more effective against the ship's
// systems than they are against the shields).
if (defender.Hull > 0 && defender.Disableable && Functions.GetRandom(100) <
disrupt * Consts.DisruptorSystemsMultiplier * 100 / defender.Hull)
OpponentDisabled = true;
// Make sure the Scorpion doesn't get destroyed.
if (defender.Type == ShipType.Scorpion && defender.Hull == 0)
{
defender.Hull = 1;
OpponentDisabled = true;
}
}
}
return hit;
}
public void EncounterMeet(IWin32Window owner)
{
AlertType initialAlert = AlertType.Alert;
int skill = 0;
EquipmentType equipType = EquipmentType.Gadget;
object equipSubType = null;
switch (EncounterType)
{
case EncounterType.CaptainAhab:
// Trade a reflective shield for skill points in piloting?
initialAlert = AlertType.MeetCaptainAhab;
equipType = EquipmentType.Shield;
equipSubType = ShieldType.Reflective;
skill = (int)SkillType.Pilot;
break;
case EncounterType.CaptainConrad:
// Trade a military laser for skill points in engineering?
initialAlert = AlertType.MeetCaptainConrad;
equipType = EquipmentType.Weapon;
equipSubType = WeaponType.MilitaryLaser;
skill = (int)SkillType.Engineer;
break;
case EncounterType.CaptainHuie:
// Trade a military laser for skill points in trading?
initialAlert = AlertType.MeetCaptainHuie;
equipType = EquipmentType.Weapon;
equipSubType = WeaponType.MilitaryLaser;
skill = (int)SkillType.Trader;
break;
}
if (FormAlert.Alert(initialAlert, owner) == DialogResult.Yes)
{
// Remove the equipment we're trading.
Commander.Ship.RemoveEquipment(equipType, equipSubType);
// Add points to the appropriate skill - two points if beginner-normal, one otherwise.
Commander.Skills[skill] = Math.Min(Consts.MaxSkill, Commander.Skills[skill] +
(Difficulty <= Difficulty.Normal ? 2 : 1));
FormAlert.Alert(AlertType.SpecialTrainingCompleted, owner);
}
}
public void EncounterPlunder(IWin32Window owner)
{
(new FormPlunder()).ShowDialog(owner);
if (EncounterType >= EncounterType.TraderAttack)
{
Commander.PoliceRecordScore += Consts.ScorePlunderTrader;
if (OpponentDisabled)
Commander.KillsTrader++;
}
else if (OpponentDisabled)
{
if (Commander.PoliceRecordScore >= Consts.PoliceRecordScoreDubious)
{
FormAlert.Alert(AlertType.EncounterPiratesBounty, owner, Strings.EncounterPiratesDisabled,
Strings.EncounterPiratesLocation, Functions.Multiples(Opponent.Bounty(), Strings.MoneyUnit));
Commander.Cash += Opponent.Bounty();
}
Commander.KillsPirate++;
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
}
else
Commander.PoliceRecordScore += Consts.ScorePlunderPirate;
Commander.ReputationScore += (int)Opponent.Type / 2 + 1;
}
private void EncounterScoop(IWin32Window owner)
{
// Chance 50% to pick something up on Normal level, 33% on Hard level, 25% on
// Impossible level, and 100% on Easy or Beginner.
if ((Difficulty < Difficulty.Normal || Functions.GetRandom((int)Difficulty) == 0) &&
Opponent.FilledCargoBays > 0)
{
// Changed this to actually pick a good that was in the opponent's cargo hold - JAF.
int index = Functions.GetRandom(Opponent.FilledCargoBays);
int tradeItem = -1;
for (int sum = 0; sum <= index; sum += Opponent.Cargo[++tradeItem]);
if (FormAlert.Alert(AlertType.EncounterScoop, owner, Consts.TradeItems[tradeItem].Name) == DialogResult.Yes)
{
bool jettisoned = false;
if (Commander.Ship.FreeCargoBays == 0 &&
FormAlert.Alert(AlertType.EncounterScoopNoRoom, owner) == DialogResult.Yes)
{
(new FormJettison()).ShowDialog(owner);
jettisoned = true;
}
if (Commander.Ship.FreeCargoBays > 0)
Commander.Ship.Cargo[tradeItem]++;
else if (jettisoned)
FormAlert.Alert(AlertType.EncounterScoopNoScoop, owner);
}
}
}
public void EncounterTrade(IWin32Window owner)
{
bool buy = (EncounterType == EncounterType.TraderBuy);
int item = (buy ? Commander.Ship : Opponent).GetRandomTradeableItem();
string alertStr = (buy ? Strings.CargoSelling : Strings.CargoBuying);
int cash = Commander.Cash;
if (EncounterType == EncounterType.TraderBuy)
CargoSellTrader(item, owner);
else // EncounterType.TraderSell
CargoBuyTrader(item, owner);
if (Commander.Cash != cash)
FormAlert.Alert(AlertType.EncounterTradeCompleted, owner, alertStr, Consts.TradeItems[item].Name);
}
private void EncounterUpdateEncounterType(int prevCmdrHull, int prevOppHull)
{
int chance = Functions.GetRandom(100);
if (Opponent.Hull < prevOppHull || OpponentDisabled)
{
switch (EncounterType)
{
case EncounterType.FamousCaptainAttack:
if (OpponentDisabled)
EncounterType = EncounterType.FamousCaptDisabled;
break;
case EncounterType.PirateAttack:
case EncounterType.PirateFlee:
case EncounterType.PirateSurrender:
if (OpponentDisabled)
EncounterType = EncounterType.PirateDisabled;
else if (Opponent.Hull < (prevOppHull * 2) / 3)
{
if (Commander.Ship.Hull < (prevCmdrHull * 2) / 3)
{
if (chance < 60)
EncounterType = EncounterType.PirateFlee;
}
else
{
if (chance < 10 && Opponent.Type != ShipType.Mantis)
EncounterType = EncounterType.PirateSurrender;
else
EncounterType = EncounterType.PirateFlee;
}
}
break;
case EncounterType.PoliceAttack:
case EncounterType.PoliceFlee:
if (OpponentDisabled)
EncounterType = EncounterType.PoliceDisabled;
else if (Opponent.Hull < prevOppHull / 2 && (Commander.Ship.Hull >= prevCmdrHull / 2 || chance < 40))
EncounterType = EncounterType.PoliceFlee;
break;
case EncounterType.TraderAttack:
case EncounterType.TraderFlee:
case EncounterType.TraderSurrender:
if (OpponentDisabled)
EncounterType = EncounterType.TraderDisabled;
else if (Opponent.Hull < (prevOppHull * 2) / 3)
{
if (chance < 60)
EncounterType = EncounterType.TraderSurrender;
else
EncounterType = EncounterType.TraderFlee;
}
// If you get damaged a lot, the trader tends to keep shooting; if
// you get damaged a little, the trader may keep shooting; if you
// get damaged very little or not at all, the trader will flee.
else if (Opponent.Hull < (prevOppHull * 9) / 10 &&
(Commander.Ship.Hull < (prevCmdrHull * 2) / 3 && chance < 20 ||
Commander.Ship.Hull < (prevCmdrHull * 9) / 10 && chance < 60 ||
Commander.Ship.Hull >= (prevCmdrHull * 9) / 10))
EncounterType = EncounterType.TraderFlee;
break;
default:
break;
}
}
}
public bool EncounterVerifyAttack(IWin32Window owner)
{
bool attack = true;
if (Commander.Ship.WeaponStrength() == 0)
{
FormAlert.Alert(AlertType.EncounterAttackNoWeapons, owner);
attack = false;
}
else if (!Opponent.Disableable && Commander.Ship.WeaponStrength(WeaponType.PulseLaser, WeaponType.MorgansLaser) == 0)
{
FormAlert.Alert(AlertType.EncounterAttackNoLasers, owner);
attack = false;
}
else if (Opponent.Type == ShipType.Scorpion && Commander.Ship.WeaponStrength(WeaponType.PhotonDisruptor, WeaponType.QuantumDistruptor) == 0)
{
FormAlert.Alert(AlertType.EncounterAttackNoDisruptors, owner);
attack = false;
}
else
{
switch (EncounterType)
{
case EncounterType.DragonflyIgnore:
case EncounterType.PirateIgnore:
case EncounterType.ScarabIgnore:
case EncounterType.ScorpionIgnore:
case EncounterType.SpaceMonsterIgnore:
EncounterType = EncounterType - 1;
break;
case EncounterType.PoliceInspect:
if (!Commander.Ship.DetectableIllegalCargoOrPassengers &&
FormAlert.Alert(AlertType.EncounterPoliceNothingIllegal, owner) != DialogResult.Yes)
attack = false;
// Fall through...
if (attack)
goto case EncounterType.PoliceIgnore;
break;
case EncounterType.MarieCelestePolice:
case EncounterType.PoliceFlee:
case EncounterType.PoliceIgnore:
case EncounterType.PoliceSurrender:
if (Commander.PoliceRecordScore <= Consts.PoliceRecordScoreCriminal ||
FormAlert.Alert(AlertType.EncounterAttackPolice, owner) == DialogResult.Yes)
{
if (Commander.PoliceRecordScore > Consts.PoliceRecordScoreCriminal)
Commander.PoliceRecordScore = Consts.PoliceRecordScoreCriminal;
Commander.PoliceRecordScore += Consts.ScoreAttackPolice;
if (EncounterType != EncounterType.PoliceFlee)
EncounterType = EncounterType.PoliceAttack;
}
else
attack = false;
break;
case EncounterType.TraderBuy:
case EncounterType.TraderIgnore:
case EncounterType.TraderSell:
if (Commander.PoliceRecordScore < Consts.PoliceRecordScoreClean)
Commander.PoliceRecordScore += Consts.ScoreAttackTrader;
else if (FormAlert.Alert(AlertType.EncounterAttackTrader, owner) == DialogResult.Yes)
Commander.PoliceRecordScore = Consts.PoliceRecordScoreDubious;
else
attack = false;
// Fall through...
if (attack)
goto case EncounterType.TraderAttack;
break;
case EncounterType.TraderAttack:
case EncounterType.TraderSurrender:
if (Functions.GetRandom(Consts.ReputationScoreElite) <=
Commander.ReputationScore * 10 / ((int)Opponent.Type + 1) || Opponent.WeaponStrength() == 0)
EncounterType = EncounterType.TraderFlee;
else
EncounterType = EncounterType.TraderAttack;
break;
case EncounterType.CaptainAhab:
case EncounterType.CaptainConrad:
case EncounterType.CaptainHuie:
if (FormAlert.Alert(AlertType.EncounterAttackCaptain, owner) == DialogResult.Yes)
{
if (Commander.PoliceRecordScore > Consts.PoliceRecordScoreVillain)
Commander.PoliceRecordScore = Consts.PoliceRecordScoreVillain;
Commander.PoliceRecordScore += Consts.ScoreAttackTrader;
switch (EncounterType)
{
case EncounterType.CaptainAhab:
NewsAddEvent(NewsEvent.CaptAhabAttacked);
break;
case EncounterType.CaptainConrad:
NewsAddEvent(NewsEvent.CaptConradAttacked);
break;
case EncounterType.CaptainHuie:
NewsAddEvent(NewsEvent.CaptHuieAttacked);
break;
}
EncounterType = EncounterType.FamousCaptainAttack;
}
else
attack = false;
break;
}
// Make sure the fleeing flag isn't set if we're attacking.
if (attack)
EncounterCmdrFleeing = false;
}
return attack;
}
public bool EncounterVerifyBoard(IWin32Window owner)
{
bool board = false;
if (FormAlert.Alert(AlertType.EncounterMarieCeleste, owner) == DialogResult.Yes)
{
board = true;
int narcs = Commander.Ship.Cargo[(int)TradeItemType.Narcotics];
(new FormPlunder()).ShowDialog(owner);
if (Commander.Ship.Cargo[(int)TradeItemType.Narcotics] > narcs)
JustLootedMarie = true;
}
return board;
}
public bool EncounterVerifyBribe(IWin32Window owner)
{
bool bribed = false;
if (EncounterType == EncounterType.MarieCelestePolice)
FormAlert.Alert(AlertType.EncounterMarieCelesteNoBribe, owner);
else if (WarpSystem.PoliticalSystem.BribeLevel <= 0)
FormAlert.Alert(AlertType.EncounterPoliceBribeCant, owner);
else if (Commander.Ship.DetectableIllegalCargoOrPassengers ||
FormAlert.Alert(AlertType.EncounterPoliceNothingIllegal, owner) == DialogResult.Yes)
{
// Bribe depends on how easy it is to bribe the police and commander's current worth
int diffMod = 10 + 5 * (Difficulty.Impossible - Difficulty);
int passMod = Commander.Ship.IllegalSpecialCargo ? (Difficulty <= Difficulty.Normal ? 2 : 3) : 1;
int bribe = Math.Max(100, Math.Min(10000, (int)Math.Ceiling((double)Commander.Worth /
WarpSystem.PoliticalSystem.BribeLevel / diffMod / 100) * 100 * passMod));
if (FormAlert.Alert(AlertType.EncounterPoliceBribe, owner, Functions.Multiples(bribe, Strings.MoneyUnit)) ==
DialogResult.Yes)
{
if (Commander.Cash >= bribe)
{
Commander.Cash -= bribe;
bribed = true;
}
else
FormAlert.Alert(AlertType.EncounterPoliceBribeLowCash, owner);
}
}
return bribed;
}
public bool EncounterVerifyFlee(IWin32Window owner)
{
EncounterCmdrFleeing = false;
if (EncounterType != EncounterType.PoliceInspect || Commander.Ship.DetectableIllegalCargoOrPassengers ||
FormAlert.Alert(AlertType.EncounterPoliceNothingIllegal, owner) == DialogResult.Yes)
{
EncounterCmdrFleeing = true;
if (EncounterType == EncounterType.MarieCelestePolice &&
FormAlert.Alert(AlertType.EncounterPostMarieFlee, owner) == DialogResult.No)
{
EncounterCmdrFleeing = false;
}
else if (EncounterType == EncounterType.PoliceInspect || EncounterType == EncounterType.MarieCelestePolice)
{
int scoreMod = EncounterType == EncounterType.PoliceInspect ?
Consts.ScoreFleePolice : Consts.ScoreAttackPolice;
int scoreMin = EncounterType == EncounterType.PoliceInspect ? Consts.PoliceRecordScoreDubious -
(Difficulty < Difficulty.Normal ? 0 : 1) : Consts.PoliceRecordScoreCriminal;
EncounterType = EncounterType.PoliceAttack;
Commander.PoliceRecordScore = Math.Min(Commander.PoliceRecordScore + scoreMod, scoreMin);
}
}
return EncounterCmdrFleeing;
}
public bool EncounterVerifySubmit(IWin32Window owner)
{
bool submit = false;
if (Commander.Ship.DetectableIllegalCargoOrPassengers)
{
string str1 = Commander.Ship.IllegalSpecialCargoDescription("", true, true);
string str2 = Commander.Ship.IllegalSpecialCargo ? Strings.EncounterPoliceSubmitArrested : "";
if (FormAlert.Alert(AlertType.EncounterPoliceSubmit, owner, str1, str2) == DialogResult.Yes)
{
submit = true;
// If you carry illegal goods, they are impounded and you are fined
if (Commander.Ship.DetectableIllegalCargo)
{
Commander.Ship.RemoveIllegalGoods();
int fine = (int)Math.Max(100, Math.Min(10000, Math.Ceiling((double)Commander.Worth /
((Difficulty.Impossible - Difficulty + 2) * 10) / 50) * 50));
int cashPayment = Math.Min(Commander.Cash, fine);
Commander.Debt += fine - cashPayment;
Commander.Cash -= cashPayment;
FormAlert.Alert(AlertType.EncounterPoliceFine, owner, Functions.Multiples(fine, Strings.MoneyUnit));
Commander.PoliceRecordScore += Consts.ScoreTrafficking;
}
}
}
else
{
submit = true;
// If you aren't carrying illegal cargo or passengers, the police will increase your lawfulness record
FormAlert.Alert(AlertType.EncounterPoliceNothingFound, owner);
Commander.PoliceRecordScore -= Consts.ScoreTrafficking;
}
return submit;
}
public EncounterResult EncounterVerifySurrender(IWin32Window owner)
{
EncounterResult result = EncounterResult.Continue;
if (Opponent.Type == ShipType.Mantis)
{
if (Commander.Ship.ArtifactOnBoard)
{
if (FormAlert.Alert(AlertType.EncounterAliensSurrender, owner) == DialogResult.Yes)
{
FormAlert.Alert(AlertType.ArtifactRelinquished, owner);
QuestStatusArtifact = SpecialEvent.StatusArtifactNotStarted;
result = EncounterResult.Normal;
}
}
else
FormAlert.Alert(AlertType.EncounterSurrenderRefused, owner);
}
else if (EncounterType == EncounterType.PoliceAttack || EncounterType == EncounterType.PoliceSurrender)
{
if (Commander.PoliceRecordScore <= Consts.PoliceRecordScorePsychopath)
FormAlert.Alert(AlertType.EncounterSurrenderRefused, owner);
else if (FormAlert.Alert(AlertType.EncounterPoliceSurrender, owner,
new string[] { Commander.Ship.IllegalSpecialCargoDescription(Strings.EncounterPoliceSurrenderCargo, true, false),
Commander.Ship.IllegalSpecialCargoActions() }) == DialogResult.Yes)
result = EncounterResult.Arrested;
}
else if (Commander.Ship.PrincessOnBoard && !Commander.Ship.HasGadget(GadgetType.HiddenCargoBays))
{
FormAlert.Alert(AlertType.EncounterPiratesSurrenderPrincess, owner);
}
else
{
Raided = true;
if (Commander.Ship.HasGadget(GadgetType.HiddenCargoBays))
{
ArrayList precious = new ArrayList();
if (Commander.Ship.PrincessOnBoard)
precious.Add(Strings.EncounterHidePrincess);
if (Commander.Ship.SculptureOnBoard)
precious.Add(Strings.EncounterHideSculpture);
FormAlert.Alert(AlertType.PreciousHidden, owner,
Functions.StringVars(Strings.ListStrings[precious.Count],
(string[])precious.ToArray(System.Type.GetType("System.String"))));
}
else if (Commander.Ship.SculptureOnBoard)
{
QuestStatusSculpture = SpecialEvent.StatusSculptureNotStarted;
FormAlert.Alert(AlertType.EncounterPiratesTakeSculpture, owner);
}
ArrayList cargoToSteal = Commander.Ship.StealableCargo;
if (cargoToSteal.Count == 0)
{
int blackmail = Math.Min(25000, Math.Max(500, Commander.Worth / 20));
int cashPayment = Math.Min(Commander.Cash, blackmail);
Commander.Debt += blackmail - cashPayment;
Commander.Cash -= cashPayment;
FormAlert.Alert(AlertType.EncounterPiratesFindNoCargo, owner,
Functions.Multiples(blackmail, Strings.MoneyUnit));
}
else
{
FormAlert.Alert(AlertType.EncounterLooting, owner);
// Pirates steal as much as they have room for, which could be everything - JAF.
// Take most high-priced items - JAF.
while (Opponent.FreeCargoBays > 0 && cargoToSteal.Count > 0)
{
int item = (int)cargoToSteal[0];
Commander.PriceCargo[item] -= Commander.PriceCargo[item] / Commander.Ship.Cargo[item];
Commander.Ship.Cargo[item]--;
Opponent.Cargo[item]++;
cargoToSteal.RemoveAt(0);
}
}
if (Commander.Ship.WildOnBoard)
{
if (Opponent.CrewQuarters > 1)
{
// Wild hops onto Pirate Ship
QuestStatusWild = SpecialEvent.StatusWildNotStarted;
FormAlert.Alert(AlertType.WildGoesPirates, owner);
}
else
// no room on pirate ship
FormAlert.Alert(AlertType.WildChatsPirates, owner);
}
// pirates puzzled by reactor
if (Commander.Ship.ReactorOnBoard)
FormAlert.Alert(AlertType.EncounterPiratesExamineReactor, owner);
result = EncounterResult.Normal;
}
return result;
}
public EncounterResult EncounterVerifyYield(IWin32Window owner)
{
EncounterResult result = EncounterResult.Continue;
if (Commander.Ship.IllegalSpecialCargo)
{
if (FormAlert.Alert(AlertType.EncounterPoliceSurrender, owner,
new string[] { Commander.Ship.IllegalSpecialCargoDescription(Strings.EncounterPoliceSurrenderCargo, true, true),
Commander.Ship.IllegalSpecialCargoActions() }) == DialogResult.Yes)
result = EncounterResult.Arrested;
}
else
{
string str1 = Commander.Ship.IllegalSpecialCargoDescription("", false, true);
if (FormAlert.Alert(AlertType.EncounterPoliceSubmit, owner, str1, "") == DialogResult.Yes)
{
// Police Record becomes dubious, if it wasn't already.
if (Commander.PoliceRecordScore > Consts.PoliceRecordScoreDubious)
Commander.PoliceRecordScore = Consts.PoliceRecordScoreDubious;
Commander.Ship.RemoveIllegalGoods();
result = EncounterResult.Normal;
}
}
return result;
}
private void EncounterWon(IWin32Window owner)
{
if (EncounterType >= EncounterType.PirateAttack && EncounterType <= EncounterType.PirateDisabled &&
Opponent.Type != ShipType.Mantis && Commander.PoliceRecordScore >= Consts.PoliceRecordScoreDubious)
FormAlert.Alert(AlertType.EncounterPiratesBounty, owner, Strings.EncounterPiratesDestroyed, "",
Functions.Multiples(Opponent.Bounty(), Strings.MoneyUnit));
else
FormAlert.Alert(AlertType.EncounterYouWin, owner);
switch (EncounterType)
{
case EncounterType.FamousCaptainAttack:
Commander.KillsTrader++;
if (Commander.ReputationScore < Consts.ReputationScoreDangerous)
Commander.ReputationScore = Consts.ReputationScoreDangerous;
else
Commander.ReputationScore += Consts.ScoreKillCaptain;
// bump news flag from attacked to ship destroyed
NewsReplaceEvent(NewsLatestEvent(), NewsLatestEvent() + 1);
break;
case EncounterType.DragonflyAttack:
EncounterDefeatDragonfly();
break;
case EncounterType.PirateAttack:
case EncounterType.PirateFlee:
case EncounterType.PirateSurrender:
Commander.KillsPirate++;
if (Opponent.Type != ShipType.Mantis)
{
if (Commander.PoliceRecordScore >= Consts.PoliceRecordScoreDubious)
Commander.Cash += Opponent.Bounty();
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
EncounterScoop(owner);
}
break;
case EncounterType.PoliceAttack:
case EncounterType.PoliceFlee:
Commander.KillsPolice++;
Commander.PoliceRecordScore += Consts.ScoreKillPolice;
break;
case EncounterType.ScarabAttack:
EncounterDefeatScarab();
break;
case EncounterType.SpaceMonsterAttack:
Commander.KillsPirate++;
Commander.PoliceRecordScore += Consts.ScoreKillPirate;
QuestStatusSpaceMonster = SpecialEvent.StatusSpaceMonsterDestroyed;
break;
case EncounterType.TraderAttack:
case EncounterType.TraderFlee:
case EncounterType.TraderSurrender:
Commander.KillsTrader++;
Commander.PoliceRecordScore += Consts.ScoreKillTrader;
EncounterScoop(owner);
break;
default:
break;
}
Commander.ReputationScore += (int)Opponent.Type / 2 + 1;
}
public void EscapeWithPod()
{
FormAlert.Alert(AlertType.EncounterEscapePodActivated, ParentWindow);
if (Commander.Ship.SculptureOnBoard)
FormAlert.Alert(AlertType.SculptureSaved, ParentWindow);
if (Commander.Ship.ReactorOnBoard)
{
FormAlert.Alert(AlertType.ReactorDestroyed, ParentWindow);
QuestStatusReactor = SpecialEvent.StatusReactorDone;
}
if (Commander.Ship.Tribbles > 0)
FormAlert.Alert(AlertType.TribblesKilled, ParentWindow);
if (QuestStatusJapori == SpecialEvent.StatusJaporiInTransit)
{
int system;
for (system = 0; system < Universe.Length && Universe[system].SpecialEventType != SpecialEventType.Japori; system++);
FormAlert.Alert(AlertType.AntidoteDestroyed, ParentWindow, Universe[system].Name);
QuestStatusJapori = SpecialEvent.StatusJaporiNotStarted;
}
if (Commander.Ship.ArtifactOnBoard)
{
FormAlert.Alert(AlertType.ArtifactLost, ParentWindow);
QuestStatusArtifact = SpecialEvent.StatusArtifactDone;
}
if (Commander.Ship.JarekOnBoard)
{
FormAlert.Alert(AlertType.JarekTakenHome, ParentWindow);
QuestStatusJarek = SpecialEvent.StatusJarekNotStarted;
}
if (Commander.Ship.PrincessOnBoard)
{
FormAlert.Alert(AlertType.PrincessTakenHome, ParentWindow);
QuestStatusPrincess = SpecialEvent.StatusPrincessNotStarted;
}
if (Commander.Ship.WildOnBoard)
{
FormAlert.Alert(AlertType.WildArrested, ParentWindow);
Commander.PoliceRecordScore += Consts.ScoreCaughtWithWild;
NewsAddEvent(NewsEvent.WildArrested);
QuestStatusWild = SpecialEvent.StatusWildNotStarted;
}
if (Commander.Insurance)
{
FormAlert.Alert(AlertType.InsurancePayoff, ParentWindow);
Commander.Cash += Commander.Ship.BaseWorth(true);
}
if (Commander.Cash > Consts.FleaConversionCost)
Commander.Cash -= Consts.FleaConversionCost;
else
{
Commander.Debt += Consts.FleaConversionCost - Commander.Cash;
Commander.Cash = 0;
}
FormAlert.Alert(AlertType.FleaBuilt, ParentWindow);
IncDays(3, ParentWindow);
CreateFlea();
}
private bool FindDistantSystem(StarSystemId baseSystem, SpecialEventType specEvent)
{
int bestDistance = 999;
int system = -1;
for (int i = 0; i < Universe.Length; i++)
{
int distance = Functions.Distance(Universe[(int)baseSystem], Universe[i]);
if (distance >= 70 && distance < bestDistance && Universe[i].SpecialEventType == SpecialEventType.NA)
{
system = i;
bestDistance = distance;
}
}
if (system >= 0)
Universe[system].SpecialEventType = specEvent;
return (system >= 0);
}
private void GenerateCrewMemberList()
{
int[] used = new int[Universe.Length];
int d = (int)Difficulty;
// Zeethibal may be on Kravat
used[(int)StarSystemId.Kravat] = 1;
// special individuals:
// Zeethibal, Jonathan Wild's Nephew - skills will be set later.
// Wild, Jonathan Wild earns his keep now - JAF.
// Jarek, Ambassador Jarek earns his keep now - JAF.
// Dummy pilots for opponents.
Mercenaries[(int)CrewMemberId.Zeethibal] = new CrewMember(CrewMemberId.Zeethibal, 5, 5, 5, 5, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Opponent] = new CrewMember(CrewMemberId.Opponent, 5, 5, 5, 5, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Wild] = new CrewMember(CrewMemberId.Wild, 7, 10, 2, 5, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Jarek] = new CrewMember(CrewMemberId.Jarek, 3, 2, 10, 4, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Princess] = new CrewMember(CrewMemberId.Princess, 4, 3, 8, 9, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.FamousCaptain] = new CrewMember(CrewMemberId.FamousCaptain, 10, 10, 10, 10, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Dragonfly] = new CrewMember(CrewMemberId.Dragonfly, 4 + d, 6 + d, 1, 6 + d, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Scarab] = new CrewMember(CrewMemberId.Scarab, 5 + d, 6 + d, 1, 6 + d, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.Scorpion] = new CrewMember(CrewMemberId.Scorpion, 8 + d, 8 + d, 1, 6 + d, StarSystemId.NA);
Mercenaries[(int)CrewMemberId.SpaceMonster] = new CrewMember(CrewMemberId.SpaceMonster, 8 + d, 8 + d, 1, 1 + d, StarSystemId.NA);
// JAF - Changing this to allow multiple mercenaries in each system, but no more
// than three.
for (int i = 1; i < Mercenaries.Length; i++)
{
// Only create a CrewMember object if one doesn't already exist in this slot in the array.
if (Mercenaries[i] == null)
{
StarSystemId id;
bool ok = false;
do
{
id = (StarSystemId)Functions.GetRandom(Universe.Length);
if (used[(int)id] < 3)
{
used[(int)id]++;
ok = true;
}
} while (!ok);
Mercenaries[i] = new CrewMember((CrewMemberId)i, Functions.RandomSkill(), Functions.RandomSkill(), Functions.RandomSkill(), Functions.RandomSkill(), id);
}
}
}
private void GenerateOpponent(OpponentType oppType)
{
Opponent = new Ship(oppType);
}
private void GenerateUniverse()
{
_universe = new StarSystem[Strings.SystemNames.Length];
int i, j;
for (i = 0; i < Universe.Length; i++)
{
StarSystemId id = (StarSystemId)i;
SystemPressure pressure = SystemPressure.None;
SpecialResource specRes = SpecialResource.Nothing;
Size size = (Size)Functions.GetRandom((int)Size.Huge + 1);
PoliticalSystem polSys = Consts.PoliticalSystems[Functions.GetRandom(Consts.PoliticalSystems.Length)];
TechLevel tech = (TechLevel)Functions.GetRandom((int)polSys.MinimumTechLevel, (int)polSys.MaximumTechLevel + 1);
// Galvon must be a Monarchy.
if (id == StarSystemId.Galvon)
{
size = Size.Large;
polSys = Consts.PoliticalSystems[(int)PoliticalSystemType.Monarchy];
tech = TechLevel.HiTech;
}
if (Functions.GetRandom(100) < 15)
pressure = (SystemPressure)Functions.GetRandom((int)SystemPressure.War, (int)SystemPressure.Employment + 1);
if (Functions.GetRandom(5) >= 3)
specRes = (SpecialResource)Functions.GetRandom((int)SpecialResource.MineralRich, (int)SpecialResource.Warlike + 1);
int x = 0;
int y = 0;
if (i < Wormholes.Length)
{
// Place the first systems somewhere in the center.
x = ((Consts.GalaxyWidth * (1 + 2 * ( i % 3))) / 6) - Functions.GetRandom(-Consts.CloseDistance + 1, Consts.CloseDistance);
y = ((Consts.GalaxyHeight * (i < 3 ? 1 : 3)) / 4) - Functions.GetRandom(-Consts.CloseDistance + 1, Consts.CloseDistance);
Wormholes[i] = i;
}
else
{
bool ok = false;
while (!ok)
{
x = Functions.GetRandom(1, Consts.GalaxyWidth);
y = Functions.GetRandom(1, Consts.GalaxyHeight);
bool closeFound = false;
bool tooClose = false;
for (j = 0; j < i && !tooClose; j++)
{
// Minimum distance between any two systems not to be accepted.
if (Functions.Distance(Universe[j], x, y) < Consts.MinDistance)
tooClose = true;
// There should be at least one system which is close enough.
if (Functions.Distance(Universe[j], x, y) < Consts.CloseDistance)
closeFound = true;
}
ok = (closeFound && !tooClose);
}
}
Universe[i] = new StarSystem(id, x, y, size, tech, polSys.Type, pressure, specRes);
}
// Randomize the system locations a bit more, otherwise the systems with the first
// names in the alphabet are all in the center.
for (i = 0; i < Universe.Length; i++)
{
j = Functions.GetRandom(Universe.Length);
if (!Functions.WormholeExists(j, -1))
{
int x = Universe[i].X;
int y = Universe[i].Y;
Universe[i].X = Universe[j].X;
Universe[i].Y = Universe[j].Y;
Universe[j].X = x;
Universe[j].Y = y;
int w = Array.IndexOf(Wormholes, i);
if (w >= 0)
Wormholes[w] = j;
}
}
// Randomize wormhole order
for (i = 0; i < Wormholes.Length; i++)
{
j = Functions.GetRandom(Wormholes.Length);
int w = Wormholes[i];
Wormholes[i] = Wormholes[j];
Wormholes[j] = w;
}
}
public void HandleSpecialEvent()
{
StarSystem curSys = Commander.CurrentSystem;
bool remove = true;
switch (curSys.SpecialEventType)
{
case SpecialEventType.Artifact:
QuestStatusArtifact = SpecialEvent.StatusArtifactOnBoard;
break;
case SpecialEventType.ArtifactDelivery:
QuestStatusArtifact = SpecialEvent.StatusArtifactDone;
break;
case SpecialEventType.CargoForSale:
FormAlert.Alert(AlertType.SpecialSealedCanisters, ParentWindow);
int tradeItem = Functions.GetRandom(Consts.TradeItems.Length);
Commander.Ship.Cargo[tradeItem] += 3;
Commander.PriceCargo[tradeItem] += Commander.CurrentSystem.SpecialEvent.Price;
break;
case SpecialEventType.Dragonfly:
case SpecialEventType.DragonflyBaratas:
case SpecialEventType.DragonflyMelina:
case SpecialEventType.DragonflyRegulas:
QuestStatusDragonfly++;
break;
case SpecialEventType.DragonflyDestroyed:
curSys.SpecialEventType = SpecialEventType.DragonflyShield;
remove = false;
break;
case SpecialEventType.DragonflyShield:
if (Commander.Ship.FreeSlotsShield == 0)
{
FormAlert.Alert(AlertType.EquipmentNotEnoughSlots, ParentWindow);
remove = false;
}
else
{
FormAlert.Alert(AlertType.EquipmentLightningShield, ParentWindow);
Commander.Ship.AddEquipment(Consts.Shields[(int)ShieldType.Lightning]);
QuestStatusDragonfly = SpecialEvent.StatusDragonflyDone;
}
break;
case SpecialEventType.EraseRecord:
FormAlert.Alert(AlertType.SpecialCleanRecord, ParentWindow);
Commander.PoliceRecordScore = Consts.PoliceRecordScoreClean;
RecalculateSellPrices(curSys);
break;
case SpecialEventType.Experiment:
QuestStatusExperiment = SpecialEvent.StatusExperimentStarted;
break;
case SpecialEventType.ExperimentFailed:
break;
case SpecialEventType.ExperimentStopped:
QuestStatusExperiment = SpecialEvent.StatusExperimentCancelled;
CanSuperWarp = true;
break;
case SpecialEventType.Gemulon:
QuestStatusGemulon = SpecialEvent.StatusGemulonStarted;
break;
case SpecialEventType.GemulonFuel:
if (Commander.Ship.FreeSlotsGadget == 0)
{
FormAlert.Alert(AlertType.EquipmentNotEnoughSlots, ParentWindow);
remove = false;
}
else
{
FormAlert.Alert(AlertType.EquipmentFuelCompactor, ParentWindow);
Commander.Ship.AddEquipment(Consts.Gadgets[(int)GadgetType.FuelCompactor]);
QuestStatusGemulon = SpecialEvent.StatusGemulonDone;
}
break;
case SpecialEventType.GemulonRescued:
curSys.SpecialEventType = SpecialEventType.GemulonFuel;
QuestStatusGemulon = SpecialEvent.StatusGemulonFuel;
remove = false;
break;
case SpecialEventType.Japori:
// The japori quest should not be removed since you can fail and start it over again.
remove = false;
if (Commander.Ship.FreeCargoBays < 10)
FormAlert.Alert(AlertType.CargoNoEmptyBays, ParentWindow);
else
{
FormAlert.Alert(AlertType.AntidoteOnBoard, ParentWindow);
QuestStatusJapori = SpecialEvent.StatusJaporiInTransit;
}
break;
case SpecialEventType.JaporiDelivery:
QuestStatusJapori = SpecialEvent.StatusJaporiDone;
Commander.IncreaseRandomSkill();
Commander.IncreaseRandomSkill();
break;
case SpecialEventType.Jarek:
if (Commander.Ship.FreeCrewQuarters == 0)
{
FormAlert.Alert(AlertType.SpecialNoQuarters, ParentWindow);
remove = false;
}
else
{
CrewMember jarek = Mercenaries[(int)CrewMemberId.Jarek];
FormAlert.Alert(AlertType.SpecialPassengerOnBoard, ParentWindow, jarek.Name);
Commander.Ship.Hire(jarek);
QuestStatusJarek = SpecialEvent.StatusJarekStarted;
}
break;
case SpecialEventType.JarekGetsOut:
QuestStatusJarek = SpecialEvent.StatusJarekDone;
Commander.Ship.Fire(CrewMemberId.Jarek);
break;
case SpecialEventType.Lottery:
break;
case SpecialEventType.Moon:
FormAlert.Alert(AlertType.SpecialMoonBought, ParentWindow);
QuestStatusMoon = SpecialEvent.StatusMoonBought;
break;
case SpecialEventType.MoonRetirement:
QuestStatusMoon = SpecialEvent.StatusMoonDone;
throw new GameEndException(GameEndType.BoughtMoon);
case SpecialEventType.Princess:
curSys.SpecialEventType = SpecialEventType.PrincessReturned;
remove = false;
QuestStatusPrincess++;
break;
case SpecialEventType.PrincessCentauri:
case SpecialEventType.PrincessInthara:
QuestStatusPrincess++;
break;
case SpecialEventType.PrincessQonos:
if (Commander.Ship.FreeCrewQuarters == 0)
{
FormAlert.Alert(AlertType.SpecialNoQuarters, ParentWindow);
remove = false;
}
else
{
CrewMember princess = Mercenaries[(int)CrewMemberId.Princess];
FormAlert.Alert(AlertType.SpecialPassengerOnBoard, ParentWindow, princess.Name);
Commander.Ship.Hire(princess);
}
break;
case SpecialEventType.PrincessQuantum:
if (Commander.Ship.FreeSlotsWeapon == 0)
{
FormAlert.Alert(AlertType.EquipmentNotEnoughSlots, ParentWindow);
remove = false;
}
else
{
FormAlert.Alert(AlertType.EquipmentQuantumDisruptor, ParentWindow);
Commander.Ship.AddEquipment(Consts.Weapons[(int)WeaponType.QuantumDistruptor]);
QuestStatusPrincess = SpecialEvent.StatusPrincessDone;
}
break;
case SpecialEventType.PrincessReturned:
Commander.Ship.Fire(CrewMemberId.Princess);
curSys.SpecialEventType = SpecialEventType.PrincessQuantum;
QuestStatusPrincess = SpecialEvent.StatusPrincessReturned;
remove = false;
break;
case SpecialEventType.Reactor:
if (Commander.Ship.FreeCargoBays < 15)
{
FormAlert.Alert(AlertType.CargoNoEmptyBays, ParentWindow);
remove = false;
}
else
{
if (Commander.Ship.WildOnBoard)
{
if (FormAlert.Alert(AlertType.WildWontStayAboardReactor, ParentWindow, curSys.Name) ==
DialogResult.OK)
{
FormAlert.Alert(AlertType.WildLeavesShip, ParentWindow, curSys.Name);
QuestStatusWild = SpecialEvent.StatusWildNotStarted;
}
else
remove = false;
}
if (remove)
{
FormAlert.Alert(AlertType.ReactorOnBoard, ParentWindow);
QuestStatusReactor = SpecialEvent.StatusReactorFuelOk;
}
}
break;
case SpecialEventType.ReactorDelivered:
curSys.SpecialEventType = SpecialEventType.ReactorLaser;
QuestStatusReactor = SpecialEvent.StatusReactorDelivered;
remove = false;
break;
case SpecialEventType.ReactorLaser:
if (Commander.Ship.FreeSlotsWeapon == 0)
{
FormAlert.Alert(AlertType.EquipmentNotEnoughSlots, ParentWindow);
remove = false;
}
else
{
FormAlert.Alert(AlertType.EquipmentMorgansLaser, ParentWindow);
Commander.Ship.AddEquipment(Consts.Weapons[(int)WeaponType.MorgansLaser]);
QuestStatusReactor = SpecialEvent.StatusReactorDone;
}
break;
case SpecialEventType.Scarab:
QuestStatusScarab = SpecialEvent.StatusScarabHunting;
break;
case SpecialEventType.ScarabDestroyed:
QuestStatusScarab = SpecialEvent.StatusScarabDestroyed;
curSys.SpecialEventType = SpecialEventType.ScarabUpgradeHull;
remove = false;
break;
case SpecialEventType.ScarabUpgradeHull:
FormAlert.Alert(AlertType.ShipHullUpgraded, ParentWindow);
Commander.Ship.HullUpgraded = true;
Commander.Ship.Hull += Consts.HullUpgrade;
QuestStatusScarab = SpecialEvent.StatusScarabDone;
remove = false;
break;
case SpecialEventType.Sculpture:
QuestStatusSculpture = SpecialEvent.StatusSculptureInTransit;
break;
case SpecialEventType.SculptureDelivered:
QuestStatusSculpture = SpecialEvent.StatusSculptureDelivered;
curSys.SpecialEventType = SpecialEventType.SculptureHiddenBays;
remove = false;
break;
case SpecialEventType.SculptureHiddenBays:
QuestStatusSculpture = SpecialEvent.StatusSculptureDone;
if (Commander.Ship.FreeSlotsGadget == 0)
{
FormAlert.Alert(AlertType.EquipmentNotEnoughSlots, ParentWindow);
remove = false;
}
else
{
FormAlert.Alert(AlertType.EquipmentHiddenCompartments, ParentWindow);
Commander.Ship.AddEquipment(Consts.Gadgets[(int)GadgetType.HiddenCargoBays]);
QuestStatusSculpture = SpecialEvent.StatusSculptureDone;
}
break;
case SpecialEventType.Skill:
FormAlert.Alert(AlertType.SpecialSkillIncrease, ParentWindow);
Commander.IncreaseRandomSkill();
break;
case SpecialEventType.SpaceMonster:
QuestStatusSpaceMonster = SpecialEvent.StatusSpaceMonsterAtAcamar;
break;
case SpecialEventType.SpaceMonsterKilled:
QuestStatusSpaceMonster = SpecialEvent.StatusSpaceMonsterDone;
break;
case SpecialEventType.Tribble:
FormAlert.Alert(AlertType.TribblesOwn, ParentWindow);
Commander.Ship.Tribbles = 1;
break;
case SpecialEventType.TribbleBuyer:
FormAlert.Alert(AlertType.TribblesGone, ParentWindow);
Commander.Cash += Commander.Ship.Tribbles / 2;
Commander.Ship.Tribbles = 0;
break;
case SpecialEventType.Wild:
if (Commander.Ship.FreeCrewQuarters == 0)
{
FormAlert.Alert(AlertType.SpecialNoQuarters, ParentWindow);
remove = false;
}
else if (!Commander.Ship.HasWeapon(WeaponType.BeamLaser, false))
{
FormAlert.Alert(AlertType.WildWontBoardLaser, ParentWindow);
remove = false;
}
else if (Commander.Ship.ReactorOnBoard)
{
FormAlert.Alert(AlertType.WildWontBoardReactor, ParentWindow);
remove = false;
}
else
{
CrewMember wild = Mercenaries[(int)CrewMemberId.Wild];
FormAlert.Alert(AlertType.SpecialPassengerOnBoard, ParentWindow, wild.Name);
Commander.Ship.Hire(wild);
QuestStatusWild = SpecialEvent.StatusWildStarted;
if (Commander.Ship.SculptureOnBoard)
FormAlert.Alert(AlertType.WildSculpture, ParentWindow);
}
break;
case SpecialEventType.WildGetsOut:
// Zeethibal has a 10 in player's lowest score, an 8
// in the next lowest score, and 5 elsewhere.
CrewMember zeethibal = Mercenaries[(int)CrewMemberId.Zeethibal];
zeethibal.CurrentSystem = Universe[(int)StarSystemId.Kravat];
int lowest1 = Commander.NthLowestSkill(1);
int lowest2 = Commander.NthLowestSkill(2);
for (int i = 0; i < zeethibal.Skills.Length; i++)
zeethibal.Skills[i] = (i == lowest1 ? 10 : (i == lowest2 ? 8 : 5));
QuestStatusWild = SpecialEvent.StatusWildDone;
Commander.PoliceRecordScore = Consts.PoliceRecordScoreClean;
Commander.Ship.Fire(CrewMemberId.Wild);
RecalculateSellPrices(curSys);
break;
}
if (curSys.SpecialEvent.Price != 0)
Commander.Cash -= curSys.SpecialEvent.Price;
if (remove)
curSys.SpecialEventType = SpecialEventType.NA;
}
public void IncDays(int num, IWin32Window owner)
{
Commander.Days += num;
if (Commander.Insurance)
Commander.NoClaim += num;
// Police Record will gravitate towards neutral (0).
if (Commander.PoliceRecordScore > Consts.PoliceRecordScoreClean)
Commander.PoliceRecordScore = Math.Max(Consts.PoliceRecordScoreClean, Commander.PoliceRecordScore - num / 3);
else if (Commander.PoliceRecordScore < Consts.PoliceRecordScoreDubious)
Commander.PoliceRecordScore = Math.Min(Consts.PoliceRecordScoreDubious, Commander.PoliceRecordScore + num /
(Difficulty <= Difficulty.Normal ? 1 : (int)Difficulty));
// The Space Monster's strength increases 5% per day until it is back to full strength.
if (SpaceMonster.Hull < SpaceMonster.HullStrength)
SpaceMonster.Hull = Math.Min(SpaceMonster.HullStrength, (int)(SpaceMonster.Hull * Math.Pow(1.05, num)));
if (QuestStatusGemulon > SpecialEvent.StatusGemulonNotStarted &&
QuestStatusGemulon < SpecialEvent.StatusGemulonTooLate)
{
QuestStatusGemulon = Math.Min(QuestStatusGemulon + num, SpecialEvent.StatusGemulonTooLate);
if (QuestStatusGemulon == SpecialEvent.StatusGemulonTooLate)
{
StarSystem gemulon = Universe[(int)StarSystemId.Gemulon];
gemulon.SpecialEventType = SpecialEventType.GemulonInvaded;
gemulon.TechLevel = TechLevel.PreAgricultural;
gemulon.PoliticalSystemType = PoliticalSystemType.Anarchy;
}
}
if (Commander.Ship.ReactorOnBoard)
QuestStatusReactor = Math.Min(QuestStatusReactor + num, SpecialEvent.StatusReactorDate);
if (QuestStatusExperiment > SpecialEvent.StatusExperimentNotStarted &&
QuestStatusExperiment < SpecialEvent.StatusExperimentPerformed)
{
QuestStatusExperiment = Math.Min(QuestStatusExperiment + num, SpecialEvent.StatusExperimentPerformed);
if (QuestStatusExperiment == SpecialEvent.StatusExperimentPerformed)
{
FabricRipProbability = Consts.FabricRipInitialProbability;
Universe[(int)StarSystemId.Daled].SpecialEventType = SpecialEventType.ExperimentFailed;
FormAlert.Alert(AlertType.SpecialExperimentPerformed, owner);
NewsAddEvent(NewsEvent.ExperimentPerformed);
}
}
else if (QuestStatusExperiment == SpecialEvent.StatusExperimentPerformed && FabricRipProbability > 0)
FabricRipProbability -= num;
if (Commander.Ship.JarekOnBoard)
{
if (QuestStatusJarek == SpecialEvent.StatusJarekImpatient / 2)
FormAlert.Alert(AlertType.SpecialPassengerConcernedJarek, owner);
else if (QuestStatusJarek == SpecialEvent.StatusJarekImpatient - 1)
{
FormAlert.Alert(AlertType.SpecialPassengerImpatientJarek, owner);
Mercenaries[(int)CrewMemberId.Jarek].Pilot = 0;
Mercenaries[(int)CrewMemberId.Jarek].Fighter = 0;
Mercenaries[(int)CrewMemberId.Jarek].Trader = 0;
Mercenaries[(int)CrewMemberId.Jarek].Engineer = 0;
}
if (QuestStatusJarek < SpecialEvent.StatusJarekImpatient)
QuestStatusJarek++;
}
if (Commander.Ship.PrincessOnBoard)
{
if (QuestStatusPrincess == (SpecialEvent.StatusPrincessImpatient + SpecialEvent.StatusPrincessRescued) / 2)
FormAlert.Alert(AlertType.SpecialPassengerConcernedPrincess, owner);
else if (QuestStatusPrincess == SpecialEvent.StatusPrincessImpatient - 1)
{
FormAlert.Alert(AlertType.SpecialPassengerImpatientPrincess, owner);
Mercenaries[(int)CrewMemberId.Princess].Pilot = 0;
Mercenaries[(int)CrewMemberId.Princess].Fighter = 0;
Mercenaries[(int)CrewMemberId.Princess].Trader = 0;
Mercenaries[(int)CrewMemberId.Princess].Engineer = 0;
}
if (QuestStatusPrincess < SpecialEvent.StatusPrincessImpatient)
QuestStatusPrincess++;
}
if (Commander.Ship.WildOnBoard)
{
if (QuestStatusWild == SpecialEvent.StatusWildImpatient / 2)
FormAlert.Alert(AlertType.SpecialPassengerConcernedWild, owner);
else if (QuestStatusWild == SpecialEvent.StatusWildImpatient - 1)
{
FormAlert.Alert(AlertType.SpecialPassengerImpatientWild, owner);
Mercenaries[(int)CrewMemberId.Wild].Pilot = 0;
Mercenaries[(int)CrewMemberId.Wild].Fighter = 0;
Mercenaries[(int)CrewMemberId.Wild].Trader = 0;
Mercenaries[(int)CrewMemberId.Wild].Engineer = 0;
}
if (QuestStatusWild < SpecialEvent.StatusWildImpatient)
QuestStatusWild++;
}
}
private void InitializeCommander(string name, CrewMember commanderCrewMember)
{
_commander = new Commander(commanderCrewMember);
Mercenaries[(int)CrewMemberId.Commander] = Commander;
Strings.CrewMemberNames[(int)CrewMemberId.Commander] = name;
while (Commander.CurrentSystem == null)
{
StarSystem system = Universe[Functions.GetRandom(Universe.Length)];
if (system.SpecialEventType == SpecialEventType.NA &&
system.TechLevel > TechLevel.PreAgricultural &&
system.TechLevel < TechLevel.HiTech)
{
// Make sure at least three other systems can be reached
int close = 0;
for (int i = 0; i < Universe.Length && close < 3; i++)
{
if (i != (int)system.Id && Functions.Distance(Universe[i], system) <= Commander.Ship.FuelTanks)
close++;
}
if (close >= 3)
Commander.CurrentSystem = system;
}
}
Commander.CurrentSystem.Visited = true;
}
public void NewsAddEvent(NewsEvent newEvent)
{
NewsEvents.Add(newEvent);
}
public void NewsAddEventsOnArrival()
{
if (Commander.CurrentSystem.SpecialEventType != SpecialEventType.NA)
{
switch (Commander.CurrentSystem.SpecialEventType)
{
case SpecialEventType.ArtifactDelivery:
if (Commander.Ship.ArtifactOnBoard)
NewsAddEvent(NewsEvent.ArtifactDelivery);
break;
case SpecialEventType.Dragonfly:
NewsAddEvent(NewsEvent.Dragonfly);
break;
case SpecialEventType.DragonflyBaratas:
if (QuestStatusDragonfly == SpecialEvent.StatusDragonflyFlyBaratas)
NewsAddEvent(NewsEvent.DragonflyBaratas);
break;
case SpecialEventType.DragonflyDestroyed:
if (QuestStatusDragonfly == SpecialEvent.StatusDragonflyFlyZalkon)
NewsAddEvent(NewsEvent.DragonflyZalkon);
else if (QuestStatusDragonfly == SpecialEvent.StatusDragonflyDestroyed)
NewsAddEvent(NewsEvent.DragonflyDestroyed);
break;
case SpecialEventType.DragonflyMelina:
if (QuestStatusDragonfly == SpecialEvent.StatusDragonflyFlyMelina)
NewsAddEvent(NewsEvent.DragonflyMelina);
break;
case SpecialEventType.DragonflyRegulas:
if (QuestStatusDragonfly == SpecialEvent.StatusDragonflyFlyRegulas)
NewsAddEvent(NewsEvent.DragonflyRegulas);
break;
case SpecialEventType.ExperimentFailed:
NewsAddEvent(NewsEvent.ExperimentFailed);
break;
case SpecialEventType.ExperimentStopped:
if (QuestStatusExperiment > SpecialEvent.StatusExperimentNotStarted &&
QuestStatusExperiment < SpecialEvent.StatusExperimentPerformed)
NewsAddEvent(NewsEvent.ExperimentStopped);
break;
case SpecialEventType.Gemulon:
NewsAddEvent(NewsEvent.Gemulon);
break;
case SpecialEventType.GemulonRescued:
if (QuestStatusGemulon > SpecialEvent.StatusGemulonNotStarted)
{
if (QuestStatusGemulon < SpecialEvent.StatusGemulonTooLate)
NewsAddEvent(NewsEvent.GemulonRescued);
else
NewsAddEvent(NewsEvent.GemulonInvaded);
}
break;
case SpecialEventType.Japori:
if (QuestStatusJapori == SpecialEvent.StatusJaporiNotStarted)
NewsAddEvent(NewsEvent.Japori);
break;
case SpecialEventType.JaporiDelivery:
if (QuestStatusJapori == SpecialEvent.StatusJaporiInTransit)
NewsAddEvent(NewsEvent.JaporiDelivery);
break;
case SpecialEventType.JarekGetsOut:
if (Commander.Ship.JarekOnBoard)
NewsAddEvent(NewsEvent.JarekGetsOut);
break;
case SpecialEventType.Princess:
NewsAddEvent(NewsEvent.Princess);
break;
case SpecialEventType.PrincessCentauri:
if (QuestStatusPrincess == SpecialEvent.StatusPrincessFlyCentauri)
NewsAddEvent(NewsEvent.PrincessCentauri);
break;
case SpecialEventType.PrincessInthara:
if (QuestStatusPrincess == SpecialEvent.StatusPrincessFlyInthara)
NewsAddEvent(NewsEvent.PrincessInthara);
break;
case SpecialEventType.PrincessQonos:
if (QuestStatusPrincess == SpecialEvent.StatusPrincessFlyQonos)
NewsAddEvent(NewsEvent.PrincessQonos);
else if (QuestStatusPrincess == SpecialEvent.StatusPrincessRescued)
NewsAddEvent(NewsEvent.PrincessRescued);
break;
case SpecialEventType.PrincessReturned:
if (QuestStatusPrincess == SpecialEvent.StatusPrincessReturned)
NewsAddEvent(NewsEvent.PrincessReturned);
break;
case SpecialEventType.Scarab:
NewsAddEvent(NewsEvent.Scarab);
break;
case SpecialEventType.ScarabDestroyed:
if (QuestStatusScarab == SpecialEvent.StatusScarabHunting)
NewsAddEvent(NewsEvent.ScarabHarass);
else if (QuestStatusScarab >= SpecialEvent.StatusScarabDestroyed)
NewsAddEvent(NewsEvent.ScarabDestroyed);
break;
case SpecialEventType.Sculpture:
NewsAddEvent(NewsEvent.SculptureStolen);
break;
case SpecialEventType.SculptureDelivered:
NewsAddEvent(NewsEvent.SculptureTracked);
break;
case SpecialEventType.SpaceMonsterKilled:
if (QuestStatusSpaceMonster == SpecialEvent.StatusSpaceMonsterAtAcamar)
NewsAddEvent(NewsEvent.SpaceMonster);
else if (QuestStatusSpaceMonster >= SpecialEvent.StatusSpaceMonsterDestroyed)
NewsAddEvent(NewsEvent.SpaceMonsterKilled);
break;
case SpecialEventType.WildGetsOut:
if (Commander.Ship.WildOnBoard)
NewsAddEvent(NewsEvent.WildGetsOut);
break;
}
}
}
public NewsEvent NewsLatestEvent()
{
return (NewsEvent)NewsEvents[NewsEvents.Count - 1];
}
public void NewsReplaceEvent(NewsEvent oldEvent, NewsEvent newEvent)
{
if (NewsEvents.IndexOf(oldEvent) >= 0)
NewsEvents.Remove(oldEvent);
NewsEvents.Add(newEvent);
}
public void NewsResetEvents()
{
NewsEvents.Clear();
}
private void NormalDeparture(int fuel)
{
Commander.Cash -= (MercenaryCosts + InsuranceCosts + WormholeCosts);
Commander.Ship.Fuel -= fuel;
Commander.PayInterest();
IncDays(1, ParentWindow);
}
private bool PlaceShipyards()
{
bool goodUniverse = true;
ArrayList systemIdList = new ArrayList();
for (int system = 0; system < Universe.Length; system++)
{
if (Universe[system].TechLevel == TechLevel.HiTech)
systemIdList.Add(system);
}
if (systemIdList.Count < Consts.Shipyards.Length)
goodUniverse = false;
else
{
// Assign the shipyards to High-Tech systems.
for (int shipyard = 0; shipyard < Consts.Shipyards.Length; shipyard++)
Universe[(int)systemIdList[Functions.GetRandom(systemIdList.Count)]].ShipyardId = (ShipyardId)shipyard;
}
return goodUniverse;
}
private bool PlaceSpecialEvents()
{
bool goodUniverse = true;
int system;
Universe[(int)StarSystemId.Baratas].SpecialEventType = SpecialEventType.DragonflyBaratas;
Universe[(int)StarSystemId.Melina].SpecialEventType = SpecialEventType.DragonflyMelina;
Universe[(int)StarSystemId.Regulas].SpecialEventType = SpecialEventType.DragonflyRegulas;
Universe[(int)StarSystemId.Zalkon].SpecialEventType = SpecialEventType.DragonflyDestroyed;
Universe[(int)StarSystemId.Daled].SpecialEventType = SpecialEventType.ExperimentStopped;
Universe[(int)StarSystemId.Gemulon].SpecialEventType = SpecialEventType.GemulonRescued;
Universe[(int)StarSystemId.Japori].SpecialEventType = SpecialEventType.JaporiDelivery;
Universe[(int)StarSystemId.Devidia].SpecialEventType = SpecialEventType.JarekGetsOut;
Universe[(int)StarSystemId.Utopia].SpecialEventType = SpecialEventType.MoonRetirement;
Universe[(int)StarSystemId.Nix].SpecialEventType = SpecialEventType.ReactorDelivered;
Universe[(int)StarSystemId.Acamar].SpecialEventType = SpecialEventType.SpaceMonsterKilled;
Universe[(int)StarSystemId.Kravat].SpecialEventType = SpecialEventType.WildGetsOut;
Universe[(int)StarSystemId.Endor].SpecialEventType = SpecialEventType.SculptureDelivered;
Universe[(int)StarSystemId.Galvon].SpecialEventType = SpecialEventType.Princess;
Universe[(int)StarSystemId.Centauri].SpecialEventType = SpecialEventType.PrincessCentauri;
Universe[(int)StarSystemId.Inthara].SpecialEventType = SpecialEventType.PrincessInthara;
Universe[(int)StarSystemId.Qonos].SpecialEventType = SpecialEventType.PrincessQonos;
// Assign a wormhole location endpoint for the Scarab.
for (system = 0; system < Wormholes.Length &&
Universe[Wormholes[system]].SpecialEventType != SpecialEventType.NA; system++);
if (system < Wormholes.Length)
Universe[Wormholes[system]].SpecialEventType = SpecialEventType.ScarabDestroyed;
else
goodUniverse = false;
// Find a Hi-Tech system without a special event.
if (goodUniverse)
{
for (system = 0; system < Universe.Length &&
!(Universe[system].SpecialEventType == SpecialEventType.NA &&
Universe[system].TechLevel == TechLevel.HiTech); system++);
if (system < Universe.Length)
Universe[system].SpecialEventType = SpecialEventType.ArtifactDelivery;
else
goodUniverse = false;
}
// Find the closest system at least 70 parsecs away from Nix that doesn't already have a special event.
if (goodUniverse && !FindDistantSystem(StarSystemId.Nix, SpecialEventType.Reactor))
goodUniverse = false;
// Find the closest system at least 70 parsecs away from Gemulon that doesn't already have a special event.
if (goodUniverse && !FindDistantSystem(StarSystemId.Gemulon, SpecialEventType.Gemulon))
goodUniverse = false;
// Find the closest system at least 70 parsecs away from Daled that doesn't already have a special event.
if (goodUniverse && !FindDistantSystem(StarSystemId.Daled, SpecialEventType.Experiment))
goodUniverse = false;
// Find the closest system at least 70 parsecs away from Endor that doesn't already have a special event.
if (goodUniverse && !FindDistantSystem(StarSystemId.Endor, SpecialEventType.Sculpture))
goodUniverse = false;
// Assign the rest of the events randomly.
if (goodUniverse)
{
for (int i = 0; i < Consts.SpecialEvents.Length; i++)
{
for (int j = 0; j < Consts.SpecialEvents[i].Occurrence; j++)
{
do
{
system = Functions.GetRandom(Universe.Length);
}
while (Universe[system].SpecialEventType != SpecialEventType.NA);
Universe[system].SpecialEventType = Consts.SpecialEvents[i].Type;
}
}
}
return goodUniverse;
}
public void RecalculateBuyPrices(StarSystem system)
{
for (int i = 0; i < Consts.TradeItems.Length; i++)
{
if (!system.ItemTraded(Consts.TradeItems[i]))
_priceCargoBuy[i] = 0;
else
{
_priceCargoBuy[i] = _priceCargoSell[i];
if (Commander.PoliceRecordScore < Consts.PoliceRecordScoreDubious)
_priceCargoBuy[i] = _priceCargoBuy[i] * 100 / 90;
// BuyPrice = SellPrice + 1 to 12% (depending on trader skill (minimum is 1, max 12))
_priceCargoBuy[i] = _priceCargoBuy[i] * (103 + Consts.MaxSkill - Commander.Ship.Trader) / 100;
if (_priceCargoBuy[i] <= _priceCargoSell[i])
_priceCargoBuy[i] = _priceCargoSell[i] + 1;
}
}
}
// *************************************************************************
// After erasure of police record, selling prices must be recalculated
// *************************************************************************
public void RecalculateSellPrices(StarSystem system)
{
for (int i = 0; i < Consts.TradeItems.Length; i++)
_priceCargoSell[i] = _priceCargoSell[i] * 100 / 90;
}
public void ResetVeryRareEncounters()
{
VeryRareEncounters.Clear();
VeryRareEncounters.Add(VeryRareEncounter.MarieCeleste);
VeryRareEncounters.Add(VeryRareEncounter.CaptainAhab);
VeryRareEncounters.Add(VeryRareEncounter.CaptainConrad);
VeryRareEncounters.Add(VeryRareEncounter.CaptainHuie);
VeryRareEncounters.Add(VeryRareEncounter.BottleOld);
VeryRareEncounters.Add(VeryRareEncounter.BottleGood);
}
public void SelectNextSystemWithinRange(bool forward)
{
int[] dest = Destinations;
if (dest.Length > 0)
{
int index = Array.IndexOf(dest, (int)WarpSystemId);
if (index < 0)
index = forward ? 0 : dest.Length - 1;
else
index = (dest.Length + index + (forward ? 1 : -1)) % dest.Length;
if (Functions.WormholeExists(Commander.CurrentSystem, Universe[dest[index]]))
{
SelectedSystemId = Commander.CurrentSystemId;
TargetWormhole = true;
}
else
SelectedSystemId = (StarSystemId)dest[index];
}
}
public void ShowNewspaper()
{
if (!PaidForNewspaper)
{
int cost = (int)Difficulty + 1;
if (Commander.Cash < cost)
FormAlert.Alert(AlertType.ArrivalIFNewspaper, ParentWindow, Functions.Multiples(cost, "credit"));
else if (Options.NewsAutoPay || FormAlert.Alert(AlertType.ArrivalBuyNewspaper, ParentWindow,
Functions.Multiples(cost, "credit")) == DialogResult.Yes)
{
Commander.Cash -= cost;
PaidForNewspaper = true;
ParentWindow.UpdateAll();
}
}
if (PaidForNewspaper)
FormAlert.Alert(AlertType.Alert, ParentWindow, NewspaperHead, NewspaperText);
}
public override Hashtable Serialize()
{
Hashtable hash = base.Serialize();
hash.Add("_version", "2.00");
hash.Add("_universe", ArrayToArrayList(_universe));
hash.Add("_commander", _commander.Serialize());
hash.Add("_wormholes", _wormholes);
hash.Add("_mercenaries", ArrayToArrayList(_mercenaries));
hash.Add("_dragonfly", _dragonfly.Serialize());
hash.Add("_scarab", _scarab.Serialize());
hash.Add("_scorpion", _scorpion.Serialize());
hash.Add("_spaceMonster", _spaceMonster.Serialize());
hash.Add("_opponent", _opponent.Serialize());
hash.Add("_chanceOfTradeInOrbit", _chanceOfTradeInOrbit);
hash.Add("_clicks", _clicks);
hash.Add("_raided", _raided);
hash.Add("_inspected", _inspected);
hash.Add("_tribbleMessage", _tribbleMessage);
hash.Add("_arrivedViaWormhole", _arrivedViaWormhole);
hash.Add("_paidForNewspaper", _paidForNewspaper);
hash.Add("_litterWarning", _litterWarning);
hash.Add("_newsEvents", ArrayListToIntArray(_newsEvents));
hash.Add("_difficulty", (int)_difficulty);
hash.Add("_cheatEnabled", _cheatEnabled);
hash.Add("_autoSave", _autoSave);
hash.Add("_easyEncounters", _easyEncounters);
hash.Add("_endStatus", (int)_endStatus);
hash.Add("_encounterType", (int)_encounterType);
hash.Add("_selectedSystemId", (int)_selectedSystemId);
hash.Add("_warpSystemId", (int)_warpSystemId);
hash.Add("_trackedSystemId", (int)_trackedSystemId);
hash.Add("_targetWormhole", _targetWormhole);
hash.Add("_priceCargoBuy", _priceCargoBuy);
hash.Add("_priceCargoSell", _priceCargoSell);
hash.Add("_questStatusArtifact", _questStatusArtifact);
hash.Add("_questStatusDragonfly", _questStatusDragonfly);
hash.Add("_questStatusExperiment", _questStatusExperiment);
hash.Add("_questStatusGemulon", _questStatusGemulon);
hash.Add("_questStatusJapori", _questStatusJapori);
hash.Add("_questStatusJarek", _questStatusJarek);
hash.Add("_questStatusMoon", _questStatusMoon);
hash.Add("_questStatusPrincess", _questStatusPrincess);
hash.Add("_questStatusReactor", _questStatusReactor);
hash.Add("_questStatusScarab", _questStatusScarab);
hash.Add("_questStatusSculpture", _questStatusSculpture);
hash.Add("_questStatusSpaceMonster", _questStatusSpaceMonster);
hash.Add("_questStatusWild", _questStatusWild);
hash.Add("_fabricRipProbability", _fabricRipProbability);
hash.Add("_justLootedMarie", _justLootedMarie);
hash.Add("_canSuperWarp", _canSuperWarp);
hash.Add("_chanceOfVeryRareEncounter", _chanceOfVeryRareEncounter);
hash.Add("_veryRareEncounters", ArrayListToIntArray(_veryRareEncounters));
hash.Add("_options", _options.Serialize());
return hash;
}
// Returns true if an encounter occurred.
public bool Travel()
{
// if timespace is ripped, we may switch the warp system here.
if (QuestStatusExperiment == SpecialEvent.StatusExperimentPerformed && FabricRipProbability > 0 &&
(FabricRipProbability == Consts.FabricRipInitialProbability || Functions.GetRandom(100) < FabricRipProbability))
{
FormAlert.Alert(AlertType.SpecialTimespaceFabricRip, ParentWindow);
SelectedSystemId = (StarSystemId)Functions.GetRandom(Universe.Length);
}
bool uneventful = true;
Raided = false;
Inspected = false;
LitterWarning = false;
Clicks = Consts.StartClicks;
while (Clicks > 0)
{
Commander.Ship.PerformRepairs();
if (DetermineEncounter())
{
uneventful = false;
FormEncounter form = new FormEncounter();
form.ShowDialog(ParentWindow);
ParentWindow.UpdateStatusBar();
switch (form.Result)
{
case EncounterResult.Arrested:
Clicks = 0;
Arrested();
break;
case EncounterResult.EscapePod:
Clicks = 0;
EscapeWithPod();
break;
case EncounterResult.Killed:
throw new GameEndException(GameEndType.Killed);
}
}
Clicks--;
}
return !uneventful;
}
public void Warp(bool viaSingularity)
{
if (Commander.Debt > Consts.DebtTooLarge)
FormAlert.Alert(AlertType.DebtTooLargeGrounded, ParentWindow);
else if (Commander.Cash < MercenaryCosts)
FormAlert.Alert(AlertType.LeavingIFMercenaries, ParentWindow);
else if (Commander.Cash < MercenaryCosts + InsuranceCosts)
FormAlert.Alert(AlertType.LeavingIFInsurance, ParentWindow);
else if (Commander.Cash < MercenaryCosts + InsuranceCosts + WormholeCosts)
FormAlert.Alert(AlertType.LeavingIFWormholeTax, ParentWindow);
else
{
bool wildOk = true;
// if Wild is aboard, make sure ship is armed!
if (Commander.Ship.WildOnBoard && !Commander.Ship.HasWeapon(WeaponType.BeamLaser, false))
{
if (FormAlert.Alert(AlertType.WildWontStayAboardLaser, ParentWindow, Commander.CurrentSystem.Name) ==
DialogResult.Cancel)
wildOk = false;
else
{
FormAlert.Alert(AlertType.WildLeavesShip, ParentWindow, Commander.CurrentSystem.Name);
QuestStatusWild = SpecialEvent.StatusWildNotStarted;
}
}
if (wildOk)
{
ArrivedViaWormhole = Functions.WormholeExists(Commander.CurrentSystem, WarpSystem);
if (viaSingularity)
NewsAddEvent(NewsEvent.ExperimentArrival);
else
NormalDeparture(viaSingularity || ArrivedViaWormhole ? 0 :
Functions.Distance(Commander.CurrentSystem, WarpSystem));
Commander.CurrentSystem.CountDown = CountDownStart;
NewsResetEvents();
CalculatePrices(WarpSystem);
if (Travel())
{
// Clicks will be -1 if we were arrested or used the escape pod.
/*
if (Clicks == 0)
FormAlert.Alert(AlertType.TravelArrival, ParentWindow);
*/
}
else
FormAlert.Alert(AlertType.TravelUneventfulTrip, ParentWindow);
Arrival();
}
}
}
public void WarpDirect()
{
_warpSystemId = SelectedSystemId;
Commander.CurrentSystem.CountDown = CountDownStart;
NewsResetEvents();
CalculatePrices(WarpSystem);
Arrival();
}
#endregion
#region Properties
public static Game CurrentGame
{
get
{
return _game;
}
set
{
_game = value;
}
}
public bool ArrivedViaWormhole
{
get
{
return _arrivedViaWormhole;
}
set
{
_arrivedViaWormhole = value;
}
}
public bool AutoSave
{
get
{
return _autoSave;
}
set
{
_autoSave = value;
}
}
public bool CanSuperWarp
{
get
{
return _canSuperWarp;
}
set
{
_canSuperWarp = value;
}
}
public int ChanceOfTradeInOrbit
{
get
{
return _chanceOfTradeInOrbit;
}
set
{
_chanceOfTradeInOrbit = value;
}
}
public int ChanceOfVeryRareEncounter
{
get
{
return _chanceOfVeryRareEncounter;
}
set
{
_chanceOfVeryRareEncounter = value;
}
}
public bool CheatEnabled
{
get
{
return _cheatEnabled;
}
set
{
_cheatEnabled = value;
}
}
public int Clicks
{
get
{
return _clicks;
}
set
{
_clicks = value;
}
}
public Commander Commander
{
get
{
return _commander;
}
}
public int CountDownStart
{
get
{
return (int)Difficulty + 3;
}
}
public int CurrentCosts
{
get
{
return InsuranceCosts + InterestCosts + MercenaryCosts + WormholeCosts;
}
}
public int[] Destinations
{
get
{
ArrayList list = new ArrayList();
for (int i = 0; i < Universe.Length; i++)
if (Universe[i].DestOk)
list.Add(i);
int[] ids = new int[list.Count];
for (int i = 0; i < ids.Length; i++)
ids[i] = (int)list[i];
return ids;
}
}
public Difficulty Difficulty
{
get
{
return _difficulty;
}
}
public Ship Dragonfly
{
get
{
return _dragonfly;
}
}
public bool EasyEncounters
{
get
{
return _easyEncounters;
}
set
{
_easyEncounters = value;
}
}
public bool EncounterContinueFleeing
{
get
{
return _encounterContinueFleeing;
}
set
{
_encounterContinueFleeing = value;
}
}
public string EncounterAction
{
get
{
string action = "";
if (OpponentDisabled)
action = Functions.StringVars(Strings.EncounterActionOppDisabled, EncounterShipText);
else if (EncounterOppFleeing)
{
if (EncounterType == EncounterType.PirateSurrender || EncounterType == EncounterType.TraderSurrender)
action = Functions.StringVars(Strings.EncounterActionOppSurrender, EncounterShipText);
else
action = Functions.StringVars(Strings.EncounterActionOppFleeing, EncounterShipText);
}
else
action = Functions.StringVars(Strings.EncounterActionOppAttacks, EncounterShipText);
return action;
}
}
public string EncounterActionInitial
{
get
{
string text = "";
// Set up the fleeing variable initially.
EncounterOppFleeing = false;
switch (EncounterType)
{
case EncounterType.BottleGood:
case EncounterType.BottleOld:
text = Strings.EncounterTextBottle;
break;
case EncounterType.CaptainAhab:
case EncounterType.CaptainConrad:
case EncounterType.CaptainHuie:
text = Strings.EncounterTextFamousCaptain;
break;
case EncounterType.DragonflyAttack:
case EncounterType.PirateAttack:
case EncounterType.PoliceAttack:
case EncounterType.ScarabAttack:
case EncounterType.ScorpionAttack:
case EncounterType.SpaceMonsterAttack:
text = Strings.EncounterTextOpponentAttack;
break;
case EncounterType.DragonflyIgnore:
case EncounterType.PirateIgnore:
case EncounterType.PoliceIgnore:
case EncounterType.ScarabIgnore:
case EncounterType.ScorpionIgnore:
case EncounterType.SpaceMonsterIgnore:
case EncounterType.TraderIgnore:
text = Commander.Ship.Cloaked ? Strings.EncounterTextOpponentNoNotice : Strings.EncounterTextOpponentIgnore;
break;
case EncounterType.MarieCeleste:
text = Strings.EncounterTextMarieCeleste;
break;
case EncounterType.MarieCelestePolice:
text = Strings.EncounterTextPolicePostMarie;
break;
case EncounterType.PirateFlee:
case EncounterType.PoliceFlee:
case EncounterType.TraderFlee:
text = Strings.EncounterTextOpponentFlee;
EncounterOppFleeing = true;
break;
case EncounterType.PoliceInspect:
text = Strings.EncounterTextPoliceInspection;
break;
case EncounterType.PoliceSurrender:
text = Strings.EncounterTextPoliceSurrender;
break;
case EncounterType.TraderBuy:
case EncounterType.TraderSell:
text = Strings.EncounterTextTrader;
break;
case EncounterType.FamousCaptainAttack:
case EncounterType.FamousCaptDisabled:
case EncounterType.PoliceDisabled:
case EncounterType.PirateDisabled:
case EncounterType.PirateSurrender:
case EncounterType.TraderAttack:
case EncounterType.TraderDisabled:
case EncounterType.TraderSurrender:
// These should never be the initial encounter type.
break;
}
return text;
}
}
public bool EncounterCmdrFleeing
{
get
{
return _encounterCmdrFleeing;
}
set
{
_encounterCmdrFleeing = value;
}
}
public bool EncounterCmdrHit
{
get
{
return _encounterCmdrHit;
}
set
{
_encounterCmdrHit = value;
}
}
public bool EncounterContinueAttacking
{
get
{
return _encounterContinueAttacking;
}
set
{
_encounterContinueAttacking = value;
}
}
public int EncounterImageIndex
{
get
{
int encounterImage = -1;
switch (EncounterType)
{
case EncounterType.BottleGood:
case EncounterType.BottleOld:
case EncounterType.CaptainAhab:
case EncounterType.CaptainConrad:
case EncounterType.CaptainHuie:
case EncounterType.MarieCeleste:
encounterImage = Consts.EncounterImgSpecial;
break;
case EncounterType.DragonflyAttack:
case EncounterType.DragonflyIgnore:
case EncounterType.ScarabAttack:
case EncounterType.ScarabIgnore:
case EncounterType.ScorpionAttack:
case EncounterType.ScorpionIgnore:
encounterImage = Consts.EncounterImgPirate;
break;
case EncounterType.MarieCelestePolice:
case EncounterType.PoliceAttack:
case EncounterType.PoliceFlee:
case EncounterType.PoliceIgnore:
case EncounterType.PoliceInspect:
case EncounterType.PoliceSurrender:
encounterImage = Consts.EncounterImgPolice;
break;
case EncounterType.PirateAttack:
case EncounterType.PirateFlee:
case EncounterType.PirateIgnore:
if (Opponent.Type == ShipType.Mantis)
encounterImage = Consts.EncounterImgAlien;
else
encounterImage = Consts.EncounterImgPirate;
break;
case EncounterType.SpaceMonsterAttack:
case EncounterType.SpaceMonsterIgnore:
encounterImage = Consts.EncounterImgAlien;
break;
case EncounterType.TraderBuy:
case EncounterType.TraderFlee:
case EncounterType.TraderIgnore:
case EncounterType.TraderSell:
encounterImage = Consts.EncounterImgTrader;
break;
case EncounterType.FamousCaptainAttack:
case EncounterType.FamousCaptDisabled:
case EncounterType.PoliceDisabled:
case EncounterType.PirateDisabled:
case EncounterType.PirateSurrender:
case EncounterType.TraderAttack:
case EncounterType.TraderDisabled:
case EncounterType.TraderSurrender:
// These should never be the initial encounter type.
break;
}
return encounterImage;
}
}
public bool EncounterOppFleeing
{
get
{
return _encounterOppFleeing;
}
set
{
_encounterOppFleeing = value;
}
}
public bool EncounterOppFleeingPrev
{
get
{
return _encounterOppFleeingPrev;
}
set
{
_encounterOppFleeingPrev = value;
}
}
public bool EncounterOppHit
{
get
{
return _encounterOppHit;
}
set
{
_encounterOppHit = value;
}
}
public string EncounterShipText
{
get
{
string shipText = Opponent.Name;
switch (EncounterType)
{
case EncounterType.FamousCaptainAttack:
case EncounterType.FamousCaptDisabled:
shipText = Strings.EncounterShipCaptain;
break;
case EncounterType.PirateAttack:
case EncounterType.PirateDisabled:
case EncounterType.PirateFlee:
case EncounterType.PirateSurrender:
shipText = Opponent.Type == ShipType.Mantis ? Strings.EncounterShipMantis : Strings.EncounterShipPirate;
break;
case EncounterType.PoliceAttack:
case EncounterType.PoliceDisabled:
case EncounterType.PoliceFlee:
shipText = Strings.EncounterShipPolice;
break;
case EncounterType.TraderAttack:
case EncounterType.TraderDisabled:
case EncounterType.TraderFlee:
case EncounterType.TraderSurrender:
shipText = Strings.EncounterShipTrader;
break;
default:
break;
}
return shipText;
}
}
public string EncounterText
{
get
{
string cmdrStatus = "";
string oppStatus = "";
if (EncounterCmdrFleeing)
cmdrStatus = Functions.StringVars(Strings.EncounterActionCmdrChased, EncounterShipText);
else if (EncounterOppHit)
cmdrStatus = Functions.StringVars(Strings.EncounterActionOppHit, EncounterShipText);
else
cmdrStatus = Functions.StringVars(Strings.EncounterActionOppMissed, EncounterShipText);
if (EncounterOppFleeingPrev)
oppStatus = Functions.StringVars(Strings.EncounterActionOppChased, EncounterShipText);
else if (EncounterCmdrHit)
oppStatus = Functions.StringVars(Strings.EncounterActionCmdrHit, EncounterShipText);
else
oppStatus = Functions.StringVars(Strings.EncounterActionCmdrMissed, EncounterShipText);
return cmdrStatus + Environment.NewLine + oppStatus;
}
}
public string EncounterTextInitial
{
get
{
string encounterPretext = "";
switch (EncounterType)
{
case EncounterType.BottleGood:
case EncounterType.BottleOld:
encounterPretext = Strings.EncounterPretextBottle;
break;
case EncounterType.DragonflyAttack:
case EncounterType.DragonflyIgnore:
case EncounterType.ScarabAttack:
case EncounterType.ScarabIgnore:
encounterPretext = Strings.EncounterPretextStolen;
break;
case EncounterType.CaptainAhab:
encounterPretext = Strings.EncounterPretextCaptainAhab;
break;
case EncounterType.CaptainConrad:
encounterPretext = Strings.EncounterPretextCaptainConrad;
break;
case EncounterType.CaptainHuie:
encounterPretext = Strings.EncounterPretextCaptainHuie;
break;
case EncounterType.MarieCeleste:
encounterPretext = Strings.EncounterPretextMarie;
break;
case EncounterType.MarieCelestePolice:
case EncounterType.PoliceAttack:
case EncounterType.PoliceFlee:
case EncounterType.PoliceIgnore:
case EncounterType.PoliceInspect:
case EncounterType.PoliceSurrender:
encounterPretext = Strings.EncounterPretextPolice;
break;
case EncounterType.PirateAttack:
case EncounterType.PirateFlee:
case EncounterType.PirateIgnore:
if (Opponent.Type == ShipType.Mantis)
encounterPretext = Strings.EncounterPretextAlien;
else
encounterPretext = Strings.EncounterPretextPirate;
break;
case EncounterType.ScorpionAttack:
case EncounterType.ScorpionIgnore:
encounterPretext = Strings.EncounterPretextScorpion;
break;
case EncounterType.SpaceMonsterAttack:
case EncounterType.SpaceMonsterIgnore:
encounterPretext = Strings.EncounterPretextSpaceMonster;
break;
case EncounterType.TraderBuy:
case EncounterType.TraderFlee:
case EncounterType.TraderIgnore:
case EncounterType.TraderSell:
encounterPretext = Strings.EncounterPretextTrader;
break;
case EncounterType.FamousCaptainAttack:
case EncounterType.FamousCaptDisabled:
case EncounterType.PoliceDisabled:
case EncounterType.PirateDisabled:
case EncounterType.PirateSurrender:
case EncounterType.TraderAttack:
case EncounterType.TraderDisabled:
case EncounterType.TraderSurrender:
// These should never be the initial encounter type.
break;
}
return Functions.StringVars(Strings.EncounterText, new string[]
{
Functions.Multiples(Clicks, Strings.DistanceSubunit),
WarpSystem.Name,
encounterPretext,
Opponent.Name.ToLower()
});
}
}
public EncounterType EncounterType
{
get
{
return _encounterType;
}
set
{
_encounterType = value;
}
}
public GameEndType EndStatus
{
get
{
return _endStatus;
}
set
{
_endStatus = value;
}
}
public int FabricRipProbability
{
get
{
return _fabricRipProbability;
}
set
{
_fabricRipProbability = value;
}
}
public bool Inspected
{
get
{
return _inspected;
}
set
{
_inspected = value;
}
}
public int InsuranceCosts
{
get
{
return Commander.Insurance ? (int)Math.Max(1, Commander.Ship.BaseWorth(true) * Consts.InsRate *
(100 - Commander.NoClaim) / 100) : 0;
}
}
public int InterestCosts
{
get
{
return Commander.Debt > 0 ? (int)Math.Max(1, Commander.Debt * Consts.IntRate) : 0;
}
}
public bool JustLootedMarie
{
get
{
return _justLootedMarie;
}
set
{
_justLootedMarie = value;
}
}
public bool LitterWarning
{
get
{
return _litterWarning;
}
set
{
_litterWarning = value;
}
}
public int MercenaryCosts
{
get
{
int total = 0;
for (int i = 1; i < Commander.Ship.Crew.Length && Commander.Ship.Crew[i] != null; i++)
total += Commander.Ship.Crew[i].Rate;
return total;
}
}
public CrewMember[] Mercenaries
{
get
{
return _mercenaries;
}
}
public ArrayList NewsEvents
{
get
{
return _newsEvents;
}
}
public string NewspaperHead
{
get
{
string[] heads = Strings.NewsMastheads[(int)Commander.CurrentSystem.PoliticalSystemType];
string head = heads[(int)Commander.CurrentSystem.Id % heads.Length];
return Functions.StringVars(head, Commander.CurrentSystem.Name);
}
}
public string NewspaperText
{
get
{
StarSystem curSys = Commander.CurrentSystem;
ArrayList items = new ArrayList();
// We're using the GetRandom2 function so that the same number is generated each time for the same
// "version" of the newspaper. -JAF
Functions.RandSeed((int)curSys.Id, Commander.Days);
for (IEnumerator en = NewsEvents.GetEnumerator(); en.MoveNext();)
items.Add(Functions.StringVars(Strings.NewsEvent[(int)en.Current], new string[] { Commander.Name,
Commander.CurrentSystem.Name, Commander.Ship.Name }));
if (curSys.SystemPressure != SystemPressure.None)
items.Add(Strings.NewsPressureInternal[(int)curSys.SystemPressure]);
if (Commander.PoliceRecordScore <= Consts.PoliceRecordScoreVillain)
{
string baseStr = Strings.NewsPoliceRecordPsychopath[Functions.GetRandom2(
Strings.NewsPoliceRecordPsychopath.Length)];
items.Add(Functions.StringVars(baseStr, Commander.Name, curSys.Name));
}
else if (Commander.PoliceRecordScore >= Consts.PoliceRecordScoreHero)
{
string baseStr = Strings.NewsPoliceRecordHero[Functions.GetRandom2(Strings.NewsPoliceRecordHero.Length)];
items.Add(Functions.StringVars(baseStr, Commander.Name, curSys.Name));
}
// and now, finally, useful news (if any)
// base probability of a story showing up is (50 / MAXTECHLEVEL) * Current Tech Level
// This is then modified by adding 10% for every level of play less than Impossible
bool realNews = false;
int minProbability = Consts.StoryProbability * (int)curSys.TechLevel + 10 * (5 - (int)Difficulty);
for (int i = 0; i < Universe.Length; i++)
{
if (Universe[i].DestOk && Universe[i] != curSys)
{
// Special stories that always get shown: moon, millionaire, shipyard
if (Universe[i].SpecialEventType != SpecialEventType.NA)
{
if (Universe[i].SpecialEventType == SpecialEventType.Moon)
items.Add(Functions.StringVars(Strings.NewsMoonForSale, Universe[i].Name));
else if (Universe[i].SpecialEventType == SpecialEventType.TribbleBuyer)
items.Add(Functions.StringVars(Strings.NewsTribbleBuyer, Universe[i].Name));
}
if (Universe[i].ShipyardId != ShipyardId.NA)
items.Add(Functions.StringVars(Strings.NewsShipyard, Universe[i].Name));
// And not-always-shown stories
if (Universe[i].SystemPressure != SystemPressure.None &&
Functions.GetRandom2(100) <= Consts.StoryProbability * (int)curSys.TechLevel + 10 * (5 - (int)Difficulty))
{
int index = Functions.GetRandom2(Strings.NewsPressureExternal.Length);
string baseStr = Strings.NewsPressureExternal[index];
string pressure = Strings.NewsPressureExternalPressures[(int)Universe[i].SystemPressure];
items.Add(Functions.StringVars(baseStr, pressure, Universe[i].Name));
realNews = true;
}
}
}
// if there's no useful news, we throw up at least one
// headline from our canned news list.
if (!realNews)
{
string[] headlines = Strings.NewsHeadlines[(int)curSys.PoliticalSystemType];
bool[] shown = new bool[headlines.Length];
int toShow = Functions.GetRandom2(headlines.Length);
for (int i = 0; i <= toShow; i++)
{
int index = Functions.GetRandom2(headlines.Length);
if (!shown[index])
{
items.Add(headlines[index]);
shown[index] = true;
}
}
}
return String.Join(Environment.NewLine + Environment.NewLine, Functions.ArrayListToStringArray(items));
}
}
public Ship Opponent
{
get
{
return _opponent;
}
set
{
_opponent = value;
}
}
public bool OpponentDisabled
{
get
{
return _opponentDisabled;
}
set
{
_opponentDisabled = value;
}
}
public GameOptions Options
{
get
{
return _options;
}
}
public bool PaidForNewspaper
{
get
{
return _paidForNewspaper;
}
set
{
_paidForNewspaper = value;
}
}
public SpaceTrader ParentWindow
{
get
{
return _parentWin;
}
set
{
_parentWin = value;
}
}
public int[] PriceCargoBuy
{
get
{
return _priceCargoBuy;
}
}
public int[] PriceCargoSell
{
get
{
return _priceCargoSell;
}
}
public int QuestStatusArtifact
{
get
{
return _questStatusArtifact;
}
set
{
_questStatusArtifact = value;
}
}
public int QuestStatusDragonfly
{
get
{
return _questStatusDragonfly;
}
set
{
_questStatusDragonfly = value;
}
}
public int QuestStatusExperiment
{
get
{
return _questStatusExperiment;
}
set
{
_questStatusExperiment = value;
}
}
public int QuestStatusGemulon
{
get
{
return _questStatusGemulon;
}
set
{
_questStatusGemulon= value;
}
}
public int QuestStatusJapori
{
get
{
return _questStatusJapori;
}
set
{
_questStatusJapori = value;
}
}
public int QuestStatusJarek
{
get
{
return _questStatusJarek;
}
set
{
_questStatusJarek = value;
}
}
public int QuestStatusMoon
{
get
{
return _questStatusMoon;
}
set
{
_questStatusMoon = value;
}
}
public int QuestStatusPrincess
{
get
{
return _questStatusPrincess;
}
set
{
_questStatusPrincess = value;
}
}
public int QuestStatusReactor
{
get
{
return _questStatusReactor;
}
set
{
_questStatusReactor = value;
}
}
public int QuestStatusScarab
{
get
{
return _questStatusScarab;
}
set
{
_questStatusScarab = value;
}
}
public int QuestStatusSculpture
{
get
{
return _questStatusSculpture;
}
set
{
_questStatusSculpture = value;
}
}
public int QuestStatusSpaceMonster
{
get
{
return _questStatusSpaceMonster;
}
set
{
_questStatusSpaceMonster = value;
}
}
public int QuestStatusWild
{
get
{
return _questStatusWild;
}
set
{
_questStatusWild = value;
}
}
public bool Raided
{
get
{
return _raided;
}
set
{
_raided = value;
}
}
public Ship Scarab
{
get
{
return _scarab;
}
}
public int Score
{
get
{
int worth = Commander.Worth < 1000000 ? Commander.Worth : 1000000 + ((Commander.Worth - 1000000) / 10);
int daysMoon = 0;
int modifier = 0;
switch (EndStatus)
{
case GameEndType.Killed:
modifier = 90;
break;
case GameEndType.Retired:
modifier = 95;
break;
case GameEndType.BoughtMoon:
daysMoon = Math.Max(0, ((int)Difficulty + 1) * 100 - Commander.Days);
modifier = 100;
break;
}
return ((int)Difficulty + 1) * modifier * (daysMoon * 1000 + worth) / 250000;
}
}
public Ship Scorpion
{
get
{
return _scorpion;
}
}
public StarSystem SelectedSystem
{
get
{
return (_selectedSystemId == StarSystemId.NA ? null : Universe[(int)_selectedSystemId]);
}
}
public StarSystemId SelectedSystemId
{
get
{
return _selectedSystemId;
}
set
{
_selectedSystemId = value;
_warpSystemId = value;
_targetWormhole = false;
}
}
public string SelectedSystemName
{
set
{
string nameToFind = value;
bool found = false;
for (int i = 0; i < Universe.Length && !found; i++)
{
string name = Universe[i].Name;
if (name.ToLower().IndexOf(nameToFind.ToLower()) >= 0)
{
SelectedSystemId = (StarSystemId)i;
found = true;
}
}
}
}
public Ship SpaceMonster
{
get
{
return _spaceMonster;
}
}
public bool TargetWormhole
{
get
{
return _targetWormhole;
}
set
{
_targetWormhole = value;
if (_targetWormhole)
{
int wormIndex = Array.IndexOf(Wormholes, (int)SelectedSystemId);
_warpSystemId = (StarSystemId)Wormholes[(wormIndex + 1) % Wormholes.Length];
}
}
}
public StarSystem TrackedSystem
{
get
{
return (_trackedSystemId == StarSystemId.NA ? null : Universe[(int)_trackedSystemId]);
}
}
public StarSystemId TrackedSystemId
{
get
{
return _trackedSystemId;
}
set
{
_trackedSystemId = value;
}
}
public bool TribbleMessage
{
get
{
return _tribbleMessage;
}
set
{
_tribbleMessage = value;
}
}
public StarSystem[] Universe
{
get
{
return _universe;
}
}
public ArrayList VeryRareEncounters
{
get
{
return _veryRareEncounters;
}
}
public StarSystem WarpSystem
{
get
{
return (_warpSystemId == StarSystemId.NA ? null : Universe[(int)_warpSystemId]);
}
}
public StarSystemId WarpSystemId
{
get
{
return _warpSystemId;
}
}
public int WormholeCosts
{
get
{
return Functions.WormholeExists(Commander.CurrentSystem, WarpSystem) ?
Consts.WormDist * Commander.Ship.FuelCost : 0;
}
}
public int[] Wormholes
{
get
{
return _wormholes;
}
}
#endregion
}
}