using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace RJW_Genes
{
internal class HiveUtility
{
///
/// Checks for existance of the RJW-Gene `queen`, if the pawn is spawned and if the pawn has reached adulthood.
/// Despite the naming, a Queen can also be male.
///
/// The pawn that could be an Adult Queen
/// Whether the pawn is an adult queen.
public static bool IsAdultQueen(Pawn pawn)
{
if (pawn == null || !pawn.Spawned)
return false;
if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_queen))
{
return pawn.ageTracker.Adult;
}
return false;
}
public static int QueensOnMap() => GetQueensOnMap().Count;
///
/// Checks for all pawns on the Players Home Map if they are an adult queen.
/// Adultness is determined by Base-Game Logic, Queen is determined by the rjw_genes_queen GeneDefOf (Not Xenotype).
///
/// A list of queens on the players HomeMap
public static List GetQueensOnMap()
{
Map map = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First();
if (map != null)
{
List playersPawns = map.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer);
return playersPawns.FindAll(pawn => pawn.Spawned && IsAdultQueen(pawn));
}
// Fallback: Something is wrong with Map
return new List();
}
///
/// Checks if the pawn is on the players home map.
///
/// Reason is that drones should only be punished for absence of queen if they are on the map and there is no queen.
/// If they are on a mission, transport-pod etc. they should not get boni or mali.
///
/// The pawn for which to check map-presence.
/// True if the pawn is on the home-map, False otherwise.
public static bool PawnIsOnHomeMap(Pawn pawn)
{
Map homeMap = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First();
return
homeMap != null && pawn != null
&& pawn.Spawned
&& pawn.Map == homeMap;
}
///
/// Returns the Xenotype of a pawn if the pawn has a xenotype with the queen gene.
/// Null otherwise.
///
///
/// A xenotype with a queen gene, or null.
public static XenotypeDef TryGetQueenXenotype(Pawn pawn)
{
if (pawn == null)
return null;
if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_queen))
{
var potentialXenotype = pawn.genes.Xenotype;
if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_queen))
{
return potentialXenotype;
}
}
return null;
}
///
/// Returns the Xenotype of a pawn if the pawn has a xenotype with the drone gene.
/// Null otherwise.
///
///
/// A xenotype with a drone gene, or null.
public static XenotypeDef TryGetDroneXenotype(Pawn pawn)
{
if (pawn == null)
return null;
if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_drone))
{
var potentialXenotype = pawn.genes.Xenotype;
if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_drone))
{
return potentialXenotype;
}
}
return null;
}
///
/// Looks up the Queen-WorkerMappings and returns a cleaned / updated dictionary.
///
/// This method takes care of genes maybe not existing (from other mods) or misspellings etc.
/// Prints a bigger piece of information when debug printing is enabled.
///
/// A mapping which Queen-Xenotypes should produce which worker genes.
public static Dictionary> GetQueenWorkerMappings()
{
Dictionary> dict = new Dictionary>();
IEnumerable mappingDefs = DefDatabase.AllDefs;
// Dev-Note: I first a nice lambda here, but I used nesting in favour of logging.
foreach (QueenWorkerMappingDef mappingDef in mappingDefs)
{
if (mappingDef.defName == "rjw_genes_default_worker_genes")
{
// Do nothing, there is no lookup but this entry is fine and should not log a warning.
continue;
}
XenotypeDef queenDef = DefDatabase.GetNamed(mappingDef.queenXenotype);
if (queenDef != null)
{
List workerGenes = new List();
foreach (string geneName in mappingDef.workerGenes)
{
GeneDef workerGene = DefDatabase.GetNamed(geneName);
if (workerGene != null)
workerGenes.Add(workerGene);
else if(RJW_Genes_Settings.rjw_genes_detailed_debug)
ModLog.Warning($"Could not look up Gene {geneName} for {mappingDef.queenXenotype}.");
}
dict.Add(queenDef, workerGenes);
}
else {
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
ModLog.Warning($"Did not find a matching xenotype for {mappingDef.queenXenotype}! Defaulting to rjw_genes_default_worker_genes.");
}
}
return dict;
}
///
/// Looks up the default genes for any queen offspring that has no other definition for it.
/// This is done by looking for the mapping with *exactly* defName rjw_genes_default_worker_genes.
///
/// The idea is that players can edit the default types, but that this is a protected keyword.
///
/// A list of genes for workers that do not have specific mappings defined.
public static List LookupDefaultWorkerGenes()
{
IEnumerable mappingDefs = DefDatabase.AllDefs;
List workerGenes = new List();
var defaultMapping = mappingDefs.First(m => m.defName == "rjw_genes_default_worker_genes");
if (defaultMapping == null)
{
ModLog.Error("Did not find default worker genes for queen-offspring! Please make sure you did not rename the 'rjw_genes_default_worker_genes'.");
return workerGenes;
}
foreach (string geneName in defaultMapping.workerGenes)
{
GeneDef workerGene = DefDatabase.GetNamed(geneName);
if (workerGene != null)
workerGenes.Add(workerGene);
else if (RJW_Genes_Settings.rjw_genes_detailed_debug)
ModLog.Warning($"Could not look up gene {geneName} for rjw_genes_default_worker_genes.");
}
return workerGenes;
}
public static IEnumerable getQueenXenotypes()
{
return DefDatabase.AllDefs.Where(type => type.genes.Contains(GeneDefOf.rjw_genes_queen));
}
public static IEnumerable getDroneXenotypes()
{
return DefDatabase.AllDefs.Where(type => type.genes.Contains(GeneDefOf.rjw_genes_drone));
}
public static HiveOffspringChanceDef LookupDefaultHiveInheritanceChances()
{
IEnumerable offspringChanceDefs = DefDatabase.AllDefs;
List workerGenes = new List();
var defaultChance = offspringChanceDefs.First(m => m.defName == "rjw_genes_default_hive_offspring_chances");
if (defaultChance == null)
ModLog.Warning("Did not find `rjw_genes_default_hive_offspring_chances`. Someone likely changed the defname!");
return defaultChance;
}
public static HiveOffspringChanceDef LookupHiveInheritanceChances(XenotypeDef queenDef)
{
IEnumerable offspringChanceDefs = DefDatabase.AllDefs;
return offspringChanceDefs.FirstOrFallback(t => t.queenXenotype == queenDef.defName, LookupDefaultHiveInheritanceChances());
}
}
}