use of com.minecolonies.coremod.colony.buildings.workerbuildings.BuildingHospital 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.coremod.colony.buildings.workerbuildings.BuildingHospital in project minecolonies by ldtteam.
the class EntityAISickTask method cure.
/**
* Cure the citizen.
*/
private void cure() {
final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenDiseaseHandler().getDisease());
if (disease != null) {
for (final ItemStack cure : disease.getCure()) {
final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, stack -> stack.sameItem(cure));
if (slot != -1) {
citizenData.getInventory().extractItem(slot, 1, false);
}
}
}
if (usedBed != null) {
final BlockPos hospitalPos = citizen.getCitizenColonyHandler().getColony().getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
final IColony colony = citizen.getCitizenColonyHandler().getColony();
final IBuilding hospital = colony.getBuildingManager().getBuilding(hospitalPos);
((BuildingHospital) hospital).registerPatient(usedBed, 0);
usedBed = null;
citizen.getCitizenData().setBedPos(BlockPos.ZERO);
}
citizen.setItemInHand(Hand.MAIN_HAND, ItemStack.EMPTY);
citizenData.markDirty();
citizen.getCitizenDiseaseHandler().cure();
citizen.setHealth(citizen.getMaxHealth());
reset();
}
use of com.minecolonies.coremod.colony.buildings.workerbuildings.BuildingHospital in project minecolonies by ldtteam.
the class EntityAISickTask method waitForCure.
/**
* Stay in bed while waiting to be cured.
*
* @return the next state to go to.
*/
private DiseaseState waitForCure() {
final IColony colony = citizenData.getColony();
placeToPath = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
if (placeToPath == null) {
return SEARCH_HOSPITAL;
}
final DiseaseState state = checkForCure();
if (state == APPLY_CURE) {
return APPLY_CURE;
} else if (state == IDLE) {
reset();
return IDLE;
}
if (citizen.getRandom().nextInt(10000) < CHANCE_FOR_RANDOM_CURE) {
cure();
return IDLE;
}
if (citizen.getCitizenSleepHandler().isAsleep()) {
final BlockPos hospital = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
if (hospital != null) {
final IBuilding building = colony.getBuildingManager().getBuilding(hospital);
if (building instanceof BuildingHospital && !((BuildingHospital) building).getBedList().contains(citizen.getCitizenSleepHandler().getBedLocation())) {
citizen.getCitizenSleepHandler().onWakeUp();
}
}
}
if (!citizen.getCitizenSleepHandler().isAsleep() && BlockPosUtil.getDistance2D(placeToPath, citizen.blockPosition()) > MINIMUM_DISTANCE_TO_HOSPITAL) {
return GO_TO_HOSPITAL;
}
if (!citizen.getCitizenSleepHandler().isAsleep()) {
return FIND_EMPTY_BED;
}
return WAIT_FOR_CURE;
}
use of com.minecolonies.coremod.colony.buildings.workerbuildings.BuildingHospital in project minecolonies by ldtteam.
the class EntityAISickTask method findEmptyBed.
/**
* Find an empty bed to ly in.
*
* @return the next state to go to.
*/
private DiseaseState findEmptyBed() {
// Finding bed
if (usedBed == null && citizen.getCitizenData() != null) {
this.usedBed = citizen.getCitizenData().getBedPos();
if (citizen.getCitizenData().getBedPos().equals(BlockPos.ZERO)) {
this.usedBed = null;
}
}
final BlockPos hospitalPos = citizen.getCitizenColonyHandler().getColony().getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
final IColony colony = citizen.getCitizenColonyHandler().getColony();
final IBuilding hospital = colony.getBuildingManager().getBuilding(hospitalPos);
if (hospital instanceof BuildingHospital) {
if (usedBed != null && !((BuildingHospital) hospital).getBedList().contains(usedBed)) {
usedBed = null;
}
if (usedBed == null) {
for (final BlockPos pos : ((BuildingHospital) hospital).getBedList()) {
final World world = citizen.level;
BlockState state = world.getBlockState(pos);
if (state.getBlock().is(BlockTags.BEDS) && !state.getValue(BedBlock.OCCUPIED) && state.getValue(BedBlock.PART).equals(BedPart.HEAD) && world.isEmptyBlock(pos.above())) {
usedBed = pos;
((BuildingHospital) hospital).registerPatient(usedBed, citizen.getCivilianID());
return FIND_EMPTY_BED;
}
}
if (usedBed == null) {
return WAIT_FOR_CURE;
}
}
if (citizen.isWorkerAtSiteWithMove(usedBed, 3)) {
waitingTicks++;
if (!citizen.getCitizenSleepHandler().trySleep(usedBed)) {
((BuildingHospital) hospital).registerPatient(usedBed, 0);
citizen.getCitizenData().setBedPos(BlockPos.ZERO);
usedBed = null;
}
}
}
if (waitingTicks > GOING_TO_BED_ATTEMPTS) {
waitingTicks = 0;
return WAIT_FOR_CURE;
}
return FIND_EMPTY_BED;
}
use of com.minecolonies.coremod.colony.buildings.workerbuildings.BuildingHospital in project minecolonies by Minecolonies.
the class EntityAISickTask method waitForCure.
/**
* Stay in bed while waiting to be cured.
*
* @return the next state to go to.
*/
private DiseaseState waitForCure() {
final IColony colony = citizenData.getColony();
placeToPath = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
if (placeToPath == null) {
return SEARCH_HOSPITAL;
}
final DiseaseState state = checkForCure();
if (state == APPLY_CURE) {
return APPLY_CURE;
} else if (state == IDLE) {
reset();
return IDLE;
}
if (citizen.getRandom().nextInt(10000) < CHANCE_FOR_RANDOM_CURE) {
cure();
return IDLE;
}
if (citizen.getCitizenSleepHandler().isAsleep()) {
final BlockPos hospital = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class);
if (hospital != null) {
final IBuilding building = colony.getBuildingManager().getBuilding(hospital);
if (building instanceof BuildingHospital && !((BuildingHospital) building).getBedList().contains(citizen.getCitizenSleepHandler().getBedLocation())) {
citizen.getCitizenSleepHandler().onWakeUp();
}
}
}
if (!citizen.getCitizenSleepHandler().isAsleep() && BlockPosUtil.getDistance2D(placeToPath, citizen.blockPosition()) > MINIMUM_DISTANCE_TO_HOSPITAL) {
return GO_TO_HOSPITAL;
}
if (!citizen.getCitizenSleepHandler().isAsleep()) {
return FIND_EMPTY_BED;
}
return WAIT_FOR_CURE;
}
Aggregations