Skip to content

Commit

Permalink
Crew selection logic!
Browse files Browse the repository at this point in the history
  • Loading branch information
fingerboxes committed Jan 24, 2015
1 parent a28ef37 commit d3c7337
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 65 deletions.
Binary file modified GameData/Fingerboxes/Common/Plugins/FingerboxLib.dll
Binary file not shown.
Binary file modified GameData/Fingerboxes/CrewQ/Plugins/CrewQ.dll
Binary file not shown.
148 changes: 132 additions & 16 deletions src/CrewQ/CrewQ.cs
Expand Up @@ -52,7 +52,9 @@ public static CrewQ Instance
}
return _Instance;
}
}
}

private IList<ProtoCrewMember> _assignedCrewBuffer;

private bool _releaseOnce;

Expand All @@ -62,6 +64,8 @@ protected override void Awake()
DontDestroyOnLoad(this);
_Instance = this;

_assignedCrewBuffer = new List<ProtoCrewMember>();

GameEvents.onKerbalRemoved.Add(OnKerbalRemoved);
GameEvents.onLevelWasLoaded.Add(OnLevelWasLoaded);
GameEvents.OnVesselRecoveryRequested.Add(OnVesselRecoveryRequested);
Expand All @@ -71,61 +75,95 @@ protected override void Awake()

protected override void Update()
{
if (_releaseOnce)
if (_releaseOnce && CrewQData.Instance != null)
{
Logging.Debug("Releasing crew once, just in case.");
ReleaseCrew();
if (CrewQData.Instance != null)
{
_releaseOnce = false;
}

_releaseOnce = false;
}
}

void OnVesselRecoveryRequested(Vessel vessel)
{
Logging.Debug("Vessel Recovery Event Recieved");
OnCrewRecovery(vessel.GetVesselCrew(), vessel.missionTime);
}

void OnKerbalRemoved(ProtoCrewMember crewMember)
{
Logging.Debug("Crew removed from Roster: " + crewMember.name);
Logging.Debug("Kerbal Remove Event");
if (CrewQData.Instance != null)
{
CrewQData.Instance.RemoveCrew(crewMember);
Logging.Info("Attempting to remove crew from roster... " + ((CrewQData.Instance.RemoveCrewIfDeadOrFired(crewMember)) ? "Success" : "Failure"));
}
}

void OnLevelWasLoaded(GameScenes scene)
{
Logging.Debug("Scene Loaded Event");
if (scene != GameScenes.EDITOR)
{
// Just in case!
Logging.Debug("Queueing release event");
_releaseOnce = true;
}

Logging.Debug("Clearing _assignedCrewBuffer");
_assignedCrewBuffer.Clear();
}

// Our methods
public void OnCrewRecovery(IEnumerable<ProtoCrewMember> crewMembers, double missionTime)
{
CrewQData settings = CrewQData.Instance;

double scaledVacationTime = missionTime * settings.settingVacationScalar,
minimumVacationTime = Utilities.GetDayLength * settings.settingMinimumVacationDays;
double scaledVacationTime = Planetarium.GetUniversalTime() + missionTime * settings.settingVacationScalar,
minimumVacationTime = Utilities.GetDayLength * settings.settingMinimumVacationDays,
maximumVacationTime = Utilities.GetDayLength * settings.settingMaximumVacationDays;

double vacationTime = (scaledVacationTime > minimumVacationTime) ? scaledVacationTime : minimumVacationTime;
scaledVacationTime.Clamp(minimumVacationTime, maximumVacationTime);

foreach (ProtoCrewMember crewMember in crewMembers)
{
CrewQData.Instance.AddOrUpdateCrew(crewMember, vacationTime);
CrewQData.Instance.AddOrUpdateCrew(crewMember, scaledVacationTime);
}
}

public void ClearAssignedBuffer()
{
_assignedCrewBuffer.Clear();
}

public void RemoveFromBuffer(IEnumerable<ProtoCrewMember> excessCrew)
{
Logging.Debug("Removing from assigned crew buffer");
_assignedCrewBuffer = _assignedCrewBuffer.Except(excessCrew).ToList();

Logging.Debug("Buffer now contains:");
foreach (ProtoCrewMember crewMember in _assignedCrewBuffer)
{
Logging.Debug(crewMember.name);
}
}

public void AddToBuffer(IEnumerable<ProtoCrewMember> assignedCrew)
{
Logging.Debug("Adding to assigned crew buffer");
_assignedCrewBuffer = _assignedCrewBuffer.Union(assignedCrew).ToList();

Logging.Debug("Buffer now contains:");
foreach (ProtoCrewMember crewMember in _assignedCrewBuffer)
{
Logging.Debug(crewMember.name);
}
}

public void SuppressCrew()
{
if (CrewQData.Instance != null && CrewQData.Instance.settingVacationHardlock)
{
foreach (ProtoCrewMember crewMember in CrewQData.Instance.VacationingCrew)
foreach (ProtoCrewMember crewMember in CrewQData.Instance.VacationingCrewRoster)
{
Logging.Debug("Hiding crew member: " + crewMember.name);
crewMember.rosterStatus = VACATION;
Expand All @@ -137,17 +175,95 @@ public void ReleaseCrew()
{
if (CrewQData.Instance != null)
{
foreach (ProtoCrewMember crewMember in CrewQData.Instance.VacationingCrew)
foreach (ProtoCrewMember crewMember in CrewQData.Instance.VacationingCrewRoster)
{
Logging.Debug("Unhiding: " + crewMember.name);
crewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available;
}
}
}

public IEnumerable<ProtoCrewMember> GetCrewForPart(Part part, bool Veteran = false)
public IEnumerable<ProtoCrewMember> GetCrewForPart(Part part, bool veteran = false)
{
ProtoCrewMember[] crewBuffer = new ProtoCrewMember[part.CrewCapacity];

string[] crewSequence = new string[] { "Pilot", "Engineer", "Scientist" };

for (int i = 0; i < part.CrewCapacity; i++)
{
int selector;
if (i < crewSequence.Length)
{
selector = i;
}
else
{
selector = new System.Random().Next(0, crewSequence.Length);
}
if (veteran)
{
crewBuffer[i] = GetExperiencedCrewMember(crewSequence[selector]);
}
else
{
crewBuffer[i] = GetCrewMember(crewSequence[selector]);
}
}

return crewBuffer;
}

private IEnumerable<ProtoCrewMember> GetRosterByJobTitle(string jobTitle)
{
IEnumerable<ProtoCrewMember> crewRoster = null;

if (CrewQData.Instance != null)
{
CrewQData data = CrewQData.Instance;

switch (jobTitle)
{
case "Pilot":
crewRoster = data.AvailablePilotRoster.Except(_assignedCrewBuffer);
break;
case "Engineer":
crewRoster = data.AvailableEngineerRoster.Except(_assignedCrewBuffer);
break;
case "Scientist":
crewRoster = data.AvailableScientistRoster.Except(_assignedCrewBuffer);
break;
default:
crewRoster = data.AvailableCrewRoster.Except(_assignedCrewBuffer);
break;
}
}

return crewRoster;
}

private ProtoCrewMember GetCrewMember(string jobTitle)
{
Logging.Debug("Getting a crew member...");
ProtoCrewMember selectedCrew = null;
if (CrewQData.Instance != null)
{
IEnumerable<ProtoCrewMember> crewRoster = GetRosterByJobTitle(jobTitle).OrderBy(x => x.experienceLevel).ToList().TakePercent(25);
selectedCrew = crewRoster.RandomElement(new System.Random());
}
return selectedCrew;
}

private ProtoCrewMember GetExperiencedCrewMember(string jobTitle)
{
return null;
Logging.Debug("Getting an experienced crew member...");
ProtoCrewMember selectedCrew = null;
if (CrewQData.Instance != null)
{
IEnumerable<ProtoCrewMember> crewRoster = GetRosterByJobTitle(jobTitle);
crewRoster = crewRoster.GroupBy(x => x.experienceLevel).OrderByDescending(x => x.Key).FirstOrDefault();
selectedCrew = crewRoster.RandomElement(new System.Random());
}
return selectedCrew;
}
}
}
51 changes: 28 additions & 23 deletions src/CrewQ/CrewQData.cs
Expand Up @@ -85,24 +85,16 @@ public IEnumerable<ProtoCrewMember> CrewRoster

if (settingVacationHardlock)
{
return crewRoster.Except(VacationingCrew);
return crewRoster.Except(VacationingCrewRoster);
}
else
{
return crewRoster;
}
}
}

public IEnumerable<ProtoCrewMember> VacationingCrew
{
get
{
return _CrewList.Where(x => x.IsOnVacation).Select(x => x.ProtoCrewReference).ToArray();
}
}

public IEnumerable<ProtoCrewMember> AvailableCrew
public IEnumerable<ProtoCrewMember> AvailableCrewRoster
{
get
{
Expand All @@ -112,32 +104,40 @@ public IEnumerable<ProtoCrewMember> AvailableCrew
}
else
{
return CrewRoster.Except(VacationingCrew);
}
return CrewRoster.Except(VacationingCrewRoster);
}
}
}

public IEnumerable<ProtoCrewMember> AvailableScientists
public IEnumerable<ProtoCrewMember> VacationingCrewRoster
{
get
{
return _CrewList.Where(x => x.IsOnVacation).Select(x => x.ProtoCrewReference).ToArray();
}
}

public IEnumerable<ProtoCrewMember> AvailableScientistRoster
{
get
{
return AvailableCrew.Where(x => x.experienceTrait.Title == "Scientist");
return AvailableCrewRoster.Where(x => x.experienceTrait.Title == "Scientist");
}
}

public IEnumerable<ProtoCrewMember> AvailableEngineers
public IEnumerable<ProtoCrewMember> AvailableEngineerRoster
{
get
{
return AvailableCrew.Where(x => x.experienceTrait.Title == "Engineer");
return AvailableCrewRoster.Where(x => x.experienceTrait.Title == "Engineer");
}
}

public IEnumerable<ProtoCrewMember> AvailablePilots
public IEnumerable<ProtoCrewMember> AvailablePilotRoster
{
get
{
return AvailableCrew.Where(x => x.experienceTrait.Title == "Pilot");
return AvailableCrewRoster.Where(x => x.experienceTrait.Title == "Pilot");
}
}

Expand Down Expand Up @@ -191,13 +191,20 @@ public void AddOrUpdateCrew(ProtoCrewMember inputProtoCrewReference, double inpu
}
}

public void RemoveCrew(ProtoCrewMember inputProtoCrewReference)

// We don't actually ever want remove crew who DO stuff. It isn't as if this list will ever get super-huge.
public bool RemoveCrewIfDeadOrFired(ProtoCrewMember inputProtoCrewReference)
{
CrewNode existingCrewNode = _CrewList.FirstOrDefault(x => x.ProtoCrewReference == inputProtoCrewReference);

if (existingCrewNode != null)
if (existingCrewNode != null && HighLogic.CurrentGame.CrewRoster.Crew.Contains(inputProtoCrewReference))
{
_CrewList.Remove(existingCrewNode);
return true;
}
else
{
return false;
}
}

Expand All @@ -214,7 +221,6 @@ public double GetVacationTime(ProtoCrewMember protoCrewMember)
}
}


// The idea here is that we always want to be dealing with ProtoCrewMember outside of this file.
// By making our data available as extension methods, that sort of makes life easier.
public static class CrewQExtensions
Expand All @@ -233,7 +239,7 @@ public static double GetVacationTime(this ProtoCrewMember protoCrewMember)

public static bool IsOnVacation(this ProtoCrewMember protoCrewMember)
{
if (CrewQData.Instance != null && CrewQData.Instance.VacationingCrew.Contains(protoCrewMember))
if (CrewQData.Instance != null && CrewQData.Instance.VacationingCrewRoster.Contains(protoCrewMember))
{
return true;
}
Expand All @@ -244,7 +250,6 @@ public static bool IsOnVacation(this ProtoCrewMember protoCrewMember)
}
}


// Our storage node type.
class CrewNode
{
Expand Down
2 changes: 0 additions & 2 deletions src/CrewQ/Interface/EditorModule.cs
Expand Up @@ -77,8 +77,6 @@ protected override void OnUpdate()
{
cleanedRoot = false;
}

CMAssignmentDialog.Instance.RefreshCrewLists(CMAssignmentDialog.Instance.GetManifest(), true, true);
}

protected bool CheckRoot(ShipConstruct ship)
Expand Down

0 comments on commit d3c7337

Please sign in to comment.