use of com.minecolonies.api.colony.ICitizenData in project minecolonies by Minecolonies.
the class ReproductionManager method trySpawnChild.
/**
* Try to spawn a new citizen as child. Mom / dad entities are required and chosen randomly in this hut. Childs inherit stats from their parents, avergaged +-2 Childs get
* assigned to a free housing slot in the colony to be raised there, if the house has an adult living there the child takes its name and gets raised by it.
*/
public void trySpawnChild() {
// Spawn a child when adults are present
if (colony.canMoveIn() && colony.getCitizenManager().getCurrentCitizenCount() < colony.getCitizenManager().getMaxCitizens() && colony.getCitizenManager().getCurrentCitizenCount() >= Math.min(MIN_SIZE_FOR_REPRO, MinecoloniesAPIProxy.getInstance().getConfig().getServer().initialCitizenAmount.get())) {
if (!checkForBioParents()) {
return;
}
final IBuilding newHome = colony.getBuildingManager().getHouseWithSpareBed();
if (newHome == null) {
return;
}
final LivingBuildingModule module = newHome.getFirstModuleOccurance(LivingBuildingModule.class);
final List<ICitizenData> assignedCitizens = module.getAssignedCitizen();
assignedCitizens.removeIf(ICitizen::isChild);
final ICitizenData newCitizen = colony.getCitizenManager().createAndRegisterCivilianData();
ICitizenData firstParent;
ICitizenData secondParent;
if (!assignedCitizens.isEmpty()) {
firstParent = assignedCitizens.get(random.nextInt(assignedCitizens.size()));
secondParent = firstParent.getPartner();
if (secondParent == null) {
assignedCitizens.removeIf(cit -> cit.getPartner() != null || cit.getName().equals(firstParent.getName()) || cit.isRelatedTo(firstParent));
if (assignedCitizens.size() > 0 && random.nextBoolean()) {
secondParent = assignedCitizens.get(random.nextInt(assignedCitizens.size()));
} else {
final BlockPos altPos = colony.getBuildingManager().getRandomBuilding(b -> b.hasModule(LivingBuildingModule.class) && !b.getPosition().equals(newHome.getPosition()) && BlockPosUtil.getDistance2D(b.getPosition(), newHome.getPosition()) < 50);
if (altPos != null) {
final IBuilding building = colony.getBuildingManager().getBuilding(altPos);
final LivingBuildingModule altModule = building.getFirstModuleOccurance(LivingBuildingModule.class);
final List<ICitizenData> newAssignedCitizens = altModule.getAssignedCitizen();
newAssignedCitizens.removeIf(cit -> cit.isChild() || cit.getPartner() != null || cit.isRelatedTo(firstParent));
if (newAssignedCitizens.size() > 0) {
secondParent = newAssignedCitizens.get(random.nextInt(newAssignedCitizens.size()));
}
}
}
}
} else {
firstParent = null;
secondParent = null;
}
if (secondParent != null) {
firstParent.setPartner(secondParent.getId());
secondParent.setPartner(firstParent.getId());
}
newCitizen.getCitizenSkillHandler().init(colony, firstParent, secondParent, random);
newCitizen.setIsChild(true);
final List<String> possibleSuffixes = new ArrayList<>();
if (firstParent != null) {
newCitizen.addSiblings(firstParent.getChildren().toArray(new Integer[0]));
firstParent.addChildren(newCitizen.getId());
possibleSuffixes.add(firstParent.getTextureSuffix());
}
if (secondParent != null) {
newCitizen.addSiblings(secondParent.getChildren().toArray(new Integer[0]));
secondParent.addChildren(newCitizen.getId());
possibleSuffixes.add(secondParent.getTextureSuffix());
}
newCitizen.setParents(firstParent == null ? "" : firstParent.getName(), secondParent == null ? "" : secondParent.getName());
newCitizen.generateName(random, firstParent == null ? "" : firstParent.getName(), secondParent == null ? "" : secondParent.getName());
module.assignCitizen(newCitizen);
for (final int sibling : newCitizen.getSiblings()) {
final ICitizenData siblingData = colony.getCitizenManager().getCivilian(sibling);
if (siblingData != null) {
siblingData.addSiblings(newCitizen.getId());
}
}
if (possibleSuffixes.contains("_w") && possibleSuffixes.contains("_d")) {
possibleSuffixes.add("_b");
}
if (possibleSuffixes.isEmpty()) {
possibleSuffixes.addAll(SUFFIXES);
}
newCitizen.setSuffix(possibleSuffixes.get(random.nextInt(possibleSuffixes.size())));
final int populationCount = colony.getCitizenManager().getCurrentCitizenCount();
AdvancementUtils.TriggerAdvancementPlayersForColony(colony, playerMP -> AdvancementTriggers.COLONY_POPULATION.trigger(playerMP, populationCount));
MessageUtils.format(MESSAGE_NEW_CHILD_BORN, newCitizen.getName(), colony.getName()).with(TextFormatting.GOLD).sendTo(colony).forManagers();
colony.getCitizenManager().spawnOrCreateCitizen(newCitizen, colony.getWorld(), newHome.getPosition());
colony.getEventDescriptionManager().addEventDescription(new CitizenBornEvent(newHome.getPosition(), newCitizen.getName()));
}
}
use of com.minecolonies.api.colony.ICitizenData in project minecolonies by Minecolonies.
the class ReproductionManager method checkForBioParents.
/**
* Check if there are potential biological parents in the colony.
* (At least one male/female citizen).
* @return true if so.
*/
private boolean checkForBioParents() {
boolean hasMale = false;
boolean hasFemale = false;
for (final ICitizenData data : colony.getCitizenManager().getCitizens()) {
if (data.isFemale()) {
hasFemale = true;
} else {
hasMale = true;
}
if (hasFemale && hasMale) {
return true;
}
}
for (final ICivilianData data : colony.getVisitorManager().getCivilianDataMap().values()) {
if (data.isFemale()) {
hasFemale = true;
} else {
hasMale = true;
}
if (hasFemale && hasMale) {
return true;
}
}
return false;
}
use of com.minecolonies.api.colony.ICitizenData in project minecolonies by Minecolonies.
the class VisitorManager method registerCivilian.
@Override
public void registerCivilian(final AbstractCivilianEntity visitor) {
if (visitor.getCivilianID() == 0 || visitorMap.get(visitor.getCivilianID()) == null) {
visitor.remove();
return;
}
final ICitizenData data = visitorMap.get(visitor.getCivilianID());
final Optional<AbstractEntityCitizen> existingCitizen = data.getEntity();
if (!existingCitizen.isPresent()) {
data.setEntity(visitor);
visitor.setCivilianData(data);
return;
}
if (existingCitizen.get() == visitor) {
return;
}
if (visitor.isAlive()) {
existingCitizen.get().remove();
data.setEntity(visitor);
visitor.setCivilianData(data);
return;
}
visitor.remove();
}
use of com.minecolonies.api.colony.ICitizenData in project minecolonies by Minecolonies.
the class CitizenManager method createAndRegisterCivilianData.
@Override
public ICitizenData createAndRegisterCivilianData() {
// That's needed to prevent bugs when calling IDs that are not used.
for (int i = 1; i <= this.getCurrentCitizenCount() + 1; i++) {
if (this.getCivilian(i) == null) {
topCitizenId = i;
break;
}
}
final CitizenData citizenData = new CitizenData(topCitizenId, colony);
citizenData.initForNewCivilian();
citizens.put(citizenData.getId(), citizenData);
return citizenData;
}
use of com.minecolonies.api.colony.ICitizenData in project minecolonies by Minecolonies.
the class CitizenManager method resurrectCivilianData.
@Override
public ICitizenData resurrectCivilianData(@NotNull final CompoundNBT compoundNBT, final boolean resetId, @NotNull final World world, final BlockPos spawnPos) {
// That's needed to prevent bugs when calling IDs that are not used.
for (int i = 1; i <= this.getCurrentCitizenCount() + 1; i++) {
if (this.getCivilian(i) == null) {
topCitizenId = i;
break;
}
}
if (resetId) {
compoundNBT.putInt(TAG_ID, topCitizenId);
}
final ICitizenData citizenData = deserializeCitizen(compoundNBT);
citizenData.onResurrect();
citizens.put(citizenData.getId(), citizenData);
spawnOrCreateCitizen(citizenData, world, spawnPos);
return citizenData;
}
Aggregations