use of com.minecolonies.api.entity.citizen.AbstractEntityCitizen in project minecolonies by ldtteam.
the class EntityAIWorkHealer method decide.
/**
* Decide what to do next. Check if all patients are up date, else update their states. Then check if there is any patient we can cure or request things for.
*
* @return the next state to go to.
*/
private IAIState decide() {
if (walkToBuilding()) {
return DECIDE;
}
final BuildingHospital hospital = getOwnBuilding();
for (final AbstractEntityCitizen citizen : WorldUtil.getEntitiesWithinBuilding(world, AbstractEntityCitizen.class, getOwnBuilding(), cit -> cit.getCitizenDiseaseHandler().isSick())) {
hospital.checkOrCreatePatientFile(citizen.getCivilianID());
}
for (final Patient patient : hospital.getPatients()) {
final ICitizenData data = hospital.getColony().getCitizenManager().getCivilian(patient.getId());
if (data == null || !data.getEntity().isPresent() || (data.getEntity().isPresent() && !data.getEntity().get().getCitizenDiseaseHandler().isSick())) {
hospital.removePatientFile(patient);
continue;
}
final EntityCitizen citizen = (EntityCitizen) data.getEntity().get();
final String diseaseName = citizen.getCitizenDiseaseHandler().getDisease();
@Nullable final Disease disease = diseaseName.isEmpty() ? null : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName);
if (patient.getState() == Patient.PatientState.NEW) {
this.currentPatient = patient;
return REQUEST_CURE;
}
if (patient.getState() == Patient.PatientState.REQUESTED) {
if (disease == null) {
this.currentPatient = patient;
return CURE;
}
if (testRandomCureChance()) {
this.currentPatient = patient;
return FREE_CURE;
}
if (!InventoryUtils.isItemHandlerFull(citizen.getInventoryCitizen())) {
if (hasCureInInventory(disease, worker.getInventoryCitizen()) || hasCureInInventory(disease, getOwnBuilding().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseGet(null))) {
this.currentPatient = patient;
return CURE;
}
final ImmutableList<IRequest<? extends Stack>> list = getOwnBuilding().getOpenRequestsOfType(worker.getCitizenData().getId(), TypeToken.of(Stack.class));
final ImmutableList<IRequest<? extends Stack>> completed = getOwnBuilding().getCompletedRequestsOfType(worker.getCitizenData(), TypeToken.of(Stack.class));
for (final ItemStack cure : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName).getCure()) {
if (!InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), cure::sameItem)) {
if (InventoryUtils.getItemCountInItemHandler(getOwnBuilding().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseGet(null), stack -> stack.sameItem(cure)) >= cure.getCount()) {
needsCurrently = new Tuple<>(stack -> stack.sameItem(cure), cure.getCount());
return GATHERING_REQUIRED_MATERIALS;
}
boolean hasCureRequested = false;
for (final IRequest<? extends Stack> request : list) {
if (request.getRequest().getStack().sameItem(cure)) {
hasCureRequested = true;
break;
}
}
for (final IRequest<? extends Stack> request : completed) {
if (request.getRequest().getStack().sameItem(cure)) {
hasCureRequested = true;
break;
}
}
if (!hasCureRequested) {
patient.setState(Patient.PatientState.NEW);
break;
}
}
}
} else {
data.triggerInteraction(new StandardInteraction(new TranslationTextComponent(PATIENT_FULL_INVENTORY), ChatPriority.BLOCKING));
}
}
if (patient.getState() == Patient.PatientState.TREATED) {
if (disease == null) {
this.currentPatient = patient;
return CURE;
}
if (!hasCureInInventory(disease, citizen.getInventoryCitizen())) {
patient.setState(Patient.PatientState.NEW);
return DECIDE;
}
}
}
for (final PlayerEntity player : WorldUtil.getEntitiesWithinBuilding(world, PlayerEntity.class, getOwnBuilding(), player -> player.getHealth() < player.getMaxHealth() - 10 - (2 * getOwnBuilding().getBuildingLevel()))) {
playerToHeal = player;
return CURE_PLAYER;
}
final ICitizenData data = getOwnBuilding().getColony().getCitizenManager().getRandomCitizen();
if (data.getEntity().isPresent() && data.getEntity().get().getHealth() < 10.0 && BlockPosUtil.getDistance2D(data.getEntity().get().blockPosition(), getOwnBuilding().getPosition()) < getOwnBuilding().getBuildingLevel() * 40) {
remotePatient = data;
return WANDER;
}
return DECIDE;
}
use of com.minecolonies.api.entity.citizen.AbstractEntityCitizen in project minecolonies by ldtteam.
the class EventHandler method onEntityConverted.
/**
* Gets called when a Hoglin, Pig, Piglin, Villager, or ZombieVillager gets converted to something else.
*
* @param event the event to handle.
*/
@SubscribeEvent
public static void onEntityConverted(@NotNull final LivingConversionEvent.Pre event) {
LivingEntity entity = event.getEntityLiving();
if (entity instanceof ZombieVillagerEntity && event.getOutcome() == EntityType.VILLAGER) {
final World world = entity.getCommandSenderWorld();
final IColony colony = IColonyManager.getInstance().getIColony(world, entity.blockPosition());
if (colony != null && colony.hasBuilding("tavern", 1, false)) {
event.setCanceled(true);
if (ForgeEventFactory.canLivingConvert(entity, ModEntities.VISITOR, null)) {
IVisitorData visitorData = (IVisitorData) colony.getVisitorManager().createAndRegisterCivilianData();
BlockPos tavernPos = colony.getBuildingManager().getRandomBuilding(b -> !b.getModules(TavernBuildingModule.class).isEmpty());
IBuilding tavern = colony.getBuildingManager().getBuilding(tavernPos);
visitorData.setHomeBuilding(tavern);
visitorData.setBedPos(tavernPos);
tavern.getModules(TavernBuildingModule.class).forEach(mod -> mod.getExternalCitizens().add(visitorData.getId()));
int recruitLevel = world.random.nextInt(10 * tavern.getBuildingLevel()) + 15;
List<com.minecolonies.api.util.Tuple<Item, Integer>> recruitCosts = IColonyManager.getInstance().getCompatibilityManager().getRecruitmentCostsWeights();
visitorData.getCitizenSkillHandler().init(recruitLevel);
colony.getVisitorManager().spawnOrCreateCivilian(visitorData, world, entity.blockPosition(), false);
colony.getEventDescriptionManager().addEventDescription(new VisitorSpawnedEvent(entity.blockPosition(), visitorData.getName()));
if (visitorData.getEntity().isPresent()) {
AbstractEntityCitizen visitorEntity = visitorData.getEntity().get();
for (EquipmentSlotType slotType : EquipmentSlotType.values()) {
ItemStack itemstack = entity.getItemBySlot(slotType);
if (slotType.getType() == EquipmentSlotType.Group.ARMOR && !itemstack.isEmpty()) {
visitorEntity.setItemSlot(slotType, itemstack);
}
}
}
if (!entity.isSilent()) {
world.levelEvent((PlayerEntity) null, 1027, entity.blockPosition(), 0);
}
entity.remove();
Tuple<Item, Integer> cost = recruitCosts.get(world.random.nextInt(recruitCosts.size()));
visitorData.setRecruitCosts(new ItemStack(cost.getA(), (int) (recruitLevel * 3.0 / cost.getB())));
visitorData.triggerInteraction(new RecruitmentInteraction(new TranslationTextComponent("com.minecolonies.coremod.gui.chat.recruitstorycured", visitorData.getName().split(" ")[0]), ChatPriority.IMPORTANT));
}
}
}
}
use of com.minecolonies.api.entity.citizen.AbstractEntityCitizen in project minecolonies by ldtteam.
the class MinecoloniesAdvancedPathNavigate method moveToTree.
@Override
public TreePathResult moveToTree(final BlockPos startRestriction, final BlockPos endRestriction, final double speed, final List<ItemStorage> excludedTrees, final int dyntreesize, final IColony colony) {
@NotNull final BlockPos start = AbstractPathJob.prepareStart(ourEntity);
final BlockPos buildingPos = ((AbstractEntityCitizen) mob).getCitizenColonyHandler().getWorkBuilding().getPosition();
final BlockPos furthestRestriction = BlockPosUtil.getFurthestCorner(start, startRestriction, endRestriction);
final PathJobFindTree job = new PathJobFindTree(CompatibilityUtils.getWorldFromEntity(mob), start, buildingPos, startRestriction, endRestriction, furthestRestriction, excludedTrees, dyntreesize, colony, ourEntity);
return (TreePathResult) setPathJob(job, null, speed, true);
}
use of com.minecolonies.api.entity.citizen.AbstractEntityCitizen in project minecolonies by ldtteam.
the class CitizenData method initEntityValues.
/**
* Initializes the entities values from citizen data.
*/
@Override
public void initEntityValues() {
if (!getEntity().isPresent()) {
return;
}
final AbstractEntityCitizen citizen = getEntity().get();
citizen.setCitizenId(getId());
citizen.getCitizenColonyHandler().setColonyId(getColony().getID());
citizen.setIsChild(isChild());
citizen.setCustomName(new StringTextComponent(getName()));
citizen.getAttribute(Attributes.MAX_HEALTH).setBaseValue(BASE_MAX_HEALTH);
citizen.setFemale(isFemale());
citizen.setTextureId(getTextureId());
citizen.getEntityData().set(DATA_COLONY_ID, colony.getID());
citizen.getEntityData().set(DATA_CITIZEN_ID, citizen.getCivilianID());
citizen.getEntityData().set(DATA_IS_FEMALE, citizen.isFemale() ? 1 : 0);
citizen.getEntityData().set(DATA_TEXTURE, citizen.getTextureId());
citizen.getEntityData().set(DATA_TEXTURE_SUFFIX, getTextureSuffix());
citizen.getEntityData().set(DATA_IS_ASLEEP, isAsleep());
citizen.getEntityData().set(DATA_IS_CHILD, isChild());
citizen.getEntityData().set(DATA_BED_POS, getBedPos());
citizen.getEntityData().set(DATA_JOB, getJob() == null ? "" : getJob().getJobRegistryEntry().getRegistryName().toString());
citizen.getEntityData().set(DATA_STYLE, colony.getTextureStyleId());
citizen.getCitizenExperienceHandler().updateLevel();
setLastPosition(citizen.blockPosition());
citizen.getCitizenJobHandler().onJobChanged(citizen.getCitizenJobHandler().getColonyJob());
applyResearchEffects();
applyItemModifiers(citizen);
markDirty();
}
use of com.minecolonies.api.entity.citizen.AbstractEntityCitizen in project minecolonies by ldtteam.
the class RecipeStorage method fullfillRecipeAndCopy.
/**
* Check for space, remove items, and insert crafted items, returning a copy of the crafted items.
*
* @param context loot context
* @param handlers the handlers to use
* @return copy of the crafted items if successful, null on failure
*/
@Override
public List<ItemStack> fullfillRecipeAndCopy(final LootContext context, final List<IItemHandler> handlers, boolean doInsert) {
if (!checkForFreeSpace(handlers) || !canFullFillRecipe(1, Collections.emptyMap(), handlers.toArray(new IItemHandler[0]))) {
return null;
}
final AbstractEntityCitizen citizen = (AbstractEntityCitizen) context.getParamOrNull(LootParameters.THIS_ENTITY);
for (final ItemStorage storage : getCleanedInput()) {
final ItemStack stack = storage.getItemStack();
int amountNeeded = storage.getAmount();
if (amountNeeded == 0) {
break;
}
for (final IItemHandler handler : handlers) {
int slotOfStack = InventoryUtils.findFirstSlotInItemHandlerNotEmptyWith(handler, itemStack -> !ItemStackUtils.isEmpty(itemStack) && ItemStackUtils.compareItemStacksIgnoreStackSize(itemStack, stack, false, !storage.ignoreNBT()));
while (slotOfStack != -1 && amountNeeded > 0) {
if (citizen != null && ItemStackUtils.compareItemStackListIgnoreStackSize(tools, stack, false, !storage.ignoreNBT()) && ItemStackUtils.getDurability(handler.getStackInSlot(slotOfStack)) > 0) {
ItemStack toDamage = handler.extractItem(slotOfStack, 1, false);
if (!ItemStackUtils.isEmpty(toDamage)) {
// The 4 parameter inner call from forge is for adding a callback to alter the damage caused,
// but unlike its description does not actually damage the item(despite the same function name). So used to just calculate the damage.
toDamage.hurtAndBreak(toDamage.getItem().damageItem(stack, 1, citizen, item -> item.broadcastBreakEvent(Hand.MAIN_HAND)), citizen, item -> item.broadcastBreakEvent(Hand.MAIN_HAND));
}
if (!ItemStackUtils.isEmpty(toDamage)) {
handler.insertItem(slotOfStack, toDamage, false);
}
amountNeeded -= stack.getCount();
} else {
final int count = ItemStackUtils.getSize(handler.getStackInSlot(slotOfStack));
final ItemStack extractedStack = handler.extractItem(slotOfStack, amountNeeded, false).copy();
// Deletes some items, but hey.
if (ItemStackUtils.isEmpty(extractedStack)) {
handler.insertItem(slotOfStack, extractedStack, false);
return null;
}
amountNeeded -= count;
if (amountNeeded > 0) {
slotOfStack = InventoryUtils.findFirstSlotInItemHandlerNotEmptyWith(handler, itemStack -> !ItemStackUtils.isEmpty(itemStack) && ItemStackUtils.compareItemStacksIgnoreStackSize(itemStack, stack, false, !storage.ignoreNBT()));
}
}
}
// stop looping handlers if we have what we need
if (amountNeeded <= 0) {
break;
}
}
if (amountNeeded > 0) {
return null;
}
}
return insertCraftedItems(handlers, getPrimaryOutput(), context, doInsert);
}
Aggregations