Skip to content

Commit

Permalink
Merge branch '1.19.4' into 1.20.1
Browse files Browse the repository at this point in the history
# Conflicts:
#	common/src/main/java/net/mca/entity/interaction/VillagerCommandHandler.java
#	common/src/main/java/net/mca/mixin/MixinPlayerEntity.java
#	fabric/src/main/java/net/mca/fabric/MCAFabric.java
#	forge/src/main/java/net/mca/forge/ForgeBusEvents.java
#	quilt/src/main/java/net/mca/quilt/MCAQuilt.java
  • Loading branch information
Luke100000 committed Sep 10, 2023
2 parents c0e75a1 + ab98001 commit 557d04a
Show file tree
Hide file tree
Showing 119 changed files with 1,539 additions and 1,307 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ out
*.iws
*.iml
.idea
*.env

# gradle
build
Expand Down
20 changes: 20 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# 7.5.8

* AI performance improvements
* Dropped babies in the inventory no longer end up in the backrooms
* Inverted marriage slider as this is more what people expect
* Fixed large players receiving damage on the ceiling
* Married adventurers no longer despawn
* Added a procreation cooldown (3 in-game days by default)
* Added attack-text cooldown
* Fixed trait influenced gender preferences
* Added gender override config flag for players

# 7.5.7

* Fixed a crash

# 7.5.6

* Added missing loot tables for some headstones

# 7.5.5

* Fixed server crash
Expand Down
8 changes: 5 additions & 3 deletions common/src/main/java/net/mca/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,17 @@ public static Config getInstance() {
public boolean enableVillagerMailingPlayers = true;
public boolean allowBodyCustomizationInDestiny = true;
public boolean allowTraitCustomizationInDestiny = true;
public boolean enableGenderCheckForPlayers = true;

public float zombieBiteInfectionChance = 0.05f;
public float infectionChanceDecreasePerLevel = 0.25f;
public int infectionTime = 72000;

//villager behavior
public float twinBabyChance = 0.02f;
public float marriageHeartsRequirement = 100;
public float engagementHeartsRequirement = 50;
public float bouquetHeartsRequirement = 10;
public int marriageHeartsRequirement = 100;
public int engagementHeartsRequirement = 50;
public int bouquetHeartsRequirement = 10;
public int babyItemGrowUpTime = 24000;
public int villagerMaxAgeTime = 384000;
public int villagerMaxHealth = 20;
Expand Down Expand Up @@ -95,6 +96,7 @@ public static Config getInstance() {
public float coloredHairChance = 0.02f;
public int heartsRequiredToAutoSpawnGravestone = 10;
public boolean useSmarterDoorAI = false;
public int procreationCooldown = 72000;

//tracker
public boolean trackVillagerPosition = true;
Expand Down
2 changes: 1 addition & 1 deletion common/src/main/java/net/mca/client/SpeechManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private void speak(String phrase, UUID sender) {
float gene = villager.getGenetics().getGene(Genetics.VOICE_TONE);
int tone = Math.min(9, (int)Math.floor(gene * 10.0f));

Identifier sound = new Identifier("mca_voices", "%s/%s_%d".formatted(phrase, villager.getGenetics().getGender().binary().getStrName(), tone).toLowerCase(Locale.ROOT));
Identifier sound = new Identifier("mca_voices", "%s/%s_%d".formatted(phrase, villager.getGenetics().getGender().binary().getDataName(), tone).toLowerCase(Locale.ROOT));

if (client.world != null && client.player != null) {
Collection<Identifier> keys = client.getSoundManager().getKeys();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void render(Data entity, float tickDelta, MatrixStack matrices, VertexCon

y += 5;

drawText(text, text.wrapLines(Text.translatable("block.mca.tombstone.footer." + entity.getGender().binary().getStrName()), maxLineWidth), y, matrices, vertexConsumers, light);
drawText(text, text.wrapLines(Text.translatable("block.mca.tombstone.footer." + entity.getGender().binary().getDataName()), maxLineWidth), y, matrices, vertexConsumers, light);

matrices.pop();
}
Expand Down
10 changes: 4 additions & 6 deletions common/src/main/java/net/mca/client/render/layer/FaceLayer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.mca.client.render.layer;

import net.mca.MCA;
import net.mca.client.model.CommonVillagerModel;
import net.mca.entity.ai.Genetics;
import net.mca.entity.ai.Traits;
Expand Down Expand Up @@ -39,12 +40,9 @@ public Identifier getSkin(T villager) {
int time = villager.age / 2 + (int) (CommonVillagerModel.getVillager(villager).getGenetics().getGene(Genetics.HEMOGLOBIN) * 65536);
boolean blink = time % 50 == 1 || time % 57 == 1 || villager.isSleeping() || villager.isDead();
boolean hasHeterochromia = variant.equals("normal") && CommonVillagerModel.getVillager(villager).getTraits().hasTrait(Traits.Trait.HETEROCHROMIA);
String gender = CommonVillagerModel.getVillager(villager).getGenetics().getGender().getDataName();
String blinkTexture = blink ? "_blink" : (hasHeterochromia ? "_hetero" : "");

return cached(String.format("mca:skins/face/%s/%s/%d%s.png",
variant,
CommonVillagerModel.getVillager(villager).getGenetics().getGender().getStrName(),
index,
blink ? "_blink" : (hasHeterochromia ? "_hetero" : "")
), Identifier::new);
return cached("skins/face/" + variant + "/" + gender + "/" + index + blinkTexture + ".png", MCA::locate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public SkinLayer(FeatureRendererContext<T, M> renderer, M model) {
public Identifier getSkin(T villager) {
Genetics genetics = getVillager(villager).getGenetics();
int skin = (int) Math.min(4, Math.max(0, genetics.getGene(Genetics.SKIN) * 5));
return cached(String.format("%s:skins/skin/%s/%d.png", MCA.MOD_ID, genetics.getGender().getStrName(), skin), Identifier::new);
return cached("skins/skin/" + genetics.getGender().getDataName() + "/" + skin + ".png", MCA::locate);
}

@Override
Expand Down
27 changes: 21 additions & 6 deletions common/src/main/java/net/mca/entity/VillagerEntityMCA.java
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,9 @@ public final boolean damage(DamageSource source, float damageAmount) {
// TODO: Verify the `isUnblockable` replacement for 1.19.4, ensure same behavior
if (!Config.getInstance().canHurtBabies && !source.isIn(DamageTypeTags.BYPASSES_SHIELD) && getAgeState() == AgeState.BABY) {
if (source.getAttacker() instanceof PlayerEntity) {
sendEventMessage(Text.translatable("villager.baby_hit"));
if (requestCooldown()) {
sendEventMessage(Text.translatable("villager.baby_hit"));
}
}
return super.damage(source, 0.0f);
}
Expand All @@ -578,10 +580,12 @@ public final boolean damage(DamageSource source, float damageAmount) {
if (getWorld().getTime() - lastHit > 40) {
lastHit = getWorld().getTime();
if (!isGuard() || getSmallBounty() == 0) {
if (getHealth() < getMaxHealth() / 2) {
sendChatMessage(player, "villager.badly_hurt");
} else {
sendChatMessage(player, "villager.hurt");
if (requestCooldown()) {
if (getHealth() < getMaxHealth() / 2) {
sendChatMessage(player, "villager.badly_hurt");
} else {
sendChatMessage(player, "villager.hurt");
}
}
}
}
Expand Down Expand Up @@ -659,6 +663,17 @@ && getProfession() != ProfessionsMCA.GUARD.get()
return super.damage(source, damageAmount);
}

long lastCooldown = 0L;

private boolean requestCooldown() {
if (getWorld().getTime() - lastCooldown > 100) {
lastCooldown = getWorld().getTime();
return true;
} else {
return false;
}
}

public boolean isGuard() {
return getProfession() == ProfessionsMCA.GUARD.get() || getProfession() == ProfessionsMCA.ARCHER.get();
}
Expand Down Expand Up @@ -1455,7 +1470,7 @@ public static DefaultAttributeContainer.Builder createVillagerAttributes() {

private void tickDespawnDelay() {
if (this.despawnDelay > 0 && !this.hasCustomer() && --this.despawnDelay == 0) {
if (getVillagerBrain().getMemories().values().stream().anyMatch(m -> random.nextInt(100) < m.getHearts())) {
if (getRelationships().getPartner().isPresent() || getVillagerBrain().getMemories().values().stream().anyMatch(m -> random.nextInt(Config.getInstance().marriageHeartsRequirement) < m.getHearts())) {
setProfession(VillagerProfession.NONE);
setDespawnDelay(0);
} else {
Expand Down
23 changes: 17 additions & 6 deletions common/src/main/java/net/mca/entity/VillagerLike.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

public interface VillagerLike<E extends Entity & VillagerLike<E>> extends CTrackedEntity<E>, VillagerDataContainer, Infectable, Messenger {
Expand Down Expand Up @@ -139,16 +140,26 @@ default boolean hasCustomSkin() {
}
}

default boolean canBeAttractedTo(VillagerLike<?> other) {
if (getTraits().eitherHaveTrait(Traits.Trait.HOMOSEXUAL, other)) {
return getTraits().hasSameTrait(Traits.Trait.HOMOSEXUAL, other) && getGenetics().getGender() == other.getGenetics().getGender();
/**
* @param villager the villager to check
* @return the set of "valid" genders
*/
default Set<Gender> getAttractedGenderSet(VillagerLike<?> villager) {
if (villager.getTraits().hasTrait(Traits.Trait.BISEXUAL)) {
return Set.of(Gender.MALE, Gender.FEMALE, Gender.NEUTRAL);
} else if (villager.getTraits().hasTrait(Traits.Trait.HOMOSEXUAL)) {
return Set.of(villager.getGenetics().getGender(), Gender.NEUTRAL);
} else {
return Set.of(villager.getGenetics().getGender().opposite(), Gender.NEUTRAL);
}
return getTraits().hasSameTrait(Traits.Trait.BISEXUAL, other)
|| getGenetics().getGender().isMutuallyAttracted(other.getGenetics().getGender());
}

default boolean canBeAttractedTo(VillagerLike<?> other) {
return getAttractedGenderSet(this).contains(other.getGenetics().getGender()) && getAttractedGenderSet(other).contains(getGenetics().getGender());
}

default boolean canBeAttractedTo(PlayerSaveData other) {
return canBeAttractedTo(toVillager(other));
return !Config.getInstance().enableGenderCheckForPlayers || canBeAttractedTo(toVillager(other));
}

default Hand getDominantHand() {
Expand Down
34 changes: 21 additions & 13 deletions common/src/main/java/net/mca/entity/ai/BreedableRelationship.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
public class BreedableRelationship extends Relationship<VillagerEntityMCA> {

private static final CDataParameter<Boolean> IS_PROCREATING = CParameter.create("isProcreating", false);
private static final CDataParameter<Integer> LAST_PROCREATION = CParameter.create("lastProcreation", 0);

public static <E extends Entity> CDataManager.Builder<E> createTrackedData(CDataManager.Builder<E> builder) {
return Relationship.createTrackedData(builder)
.addAll(IS_PROCREATING)
.addAll(IS_PROCREATING, LAST_PROCREATION)
.add(Pregnancy::createTrackedData);
}

Expand All @@ -52,9 +53,16 @@ public boolean isProcreating() {
return entity.getTrackedValue(IS_PROCREATING);
}

public void startProcreating() {
public boolean mayProcreateAgain(long time) {
int intTime = (int) time;
int delta = intTime - entity.getTrackedValue(LAST_PROCREATION);
return delta < 0 || delta > Config.getInstance().procreationCooldown;
}

public void startProcreating(long time) {
procreateTick = 60;
entity.setTrackedValue(IS_PROCREATING, true);
entity.setTrackedValue(LAST_PROCREATION, (int) time);
}

public void tick(int age) {
Expand Down Expand Up @@ -105,32 +113,32 @@ private Optional<GiftType> handleDynamicGift(ItemStack stack) {
if (stack.getItem() instanceof SwordItem sword) {
//swords
float satisfaction = sword.getAttackDamage();
satisfaction = (float)(Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int)satisfaction, MCA.locate("swords")));
satisfaction = (float) (Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int) satisfaction, MCA.locate("swords")));
} else if (stack.getItem() instanceof RangedWeaponItem ranged) {
//ranged weapons
float satisfaction = ranged.getRange();
satisfaction = (float)(Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int)satisfaction, MCA.locate("archery")));
satisfaction = (float) (Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int) satisfaction, MCA.locate("archery")));
} else if (stack.getItem() instanceof ToolItem tool) {
//tools
float satisfaction = tool.getMaterial().getMiningSpeedMultiplier();
satisfaction = (float)(Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int)satisfaction, MCA.locate(
satisfaction = (float) (Math.pow(satisfaction, 1.25) * 2);
return Optional.of(new GiftType(stack.getItem(), (int) satisfaction, MCA.locate(
stack.getItem() instanceof AxeItem ? "swords" :
stack.getItem() instanceof HoeItem ? "hoes" :
stack.getItem() instanceof ShovelItem ? "shovels" :
"pickaxes"
)));
} else if (stack.getItem() instanceof ArmorItem armor) {
//armor
int satisfaction = (int)(Math.pow(armor.getProtection(), 1.25) * 1.5 + armor.getMaterial().getToughness() * 5);
int satisfaction = (int) (Math.pow(armor.getProtection(), 1.25) * 1.5 + armor.getMaterial().getToughness() * 5);
return Optional.of(new GiftType(stack.getItem(), satisfaction, MCA.locate("armor")));
} else if (stack.getItem().isFood()) {
//food
FoodComponent component = stack.getItem().getFoodComponent();
if (component != null) {
int satisfaction = (int)(component.getHunger() + component.getSaturationModifier() * 3);
int satisfaction = (int) (component.getHunger() + component.getSaturationModifier() * 3);
return Optional.of(new GiftType(stack.getItem(), satisfaction, MCA.locate("food")));
}
}
Expand All @@ -150,7 +158,7 @@ private void acceptGift(ItemStack stack, GiftType gift, ServerPlayerEntity playe

// desaturation
int occurrences = getGiftSaturation().get(stack);
int penalty = (int)(occurrences * Config.getInstance().giftDesaturationFactor * Math.pow(Math.max(satisfaction, 0.0), Config.getInstance().giftDesaturationExponent));
int penalty = (int) (occurrences * Config.getInstance().giftDesaturationFactor * Math.pow(Math.max(satisfaction, 0.0), Config.getInstance().giftDesaturationExponent));
if (penalty != 0) {
analysis.add("desaturation", -penalty);
}
Expand Down Expand Up @@ -179,7 +187,7 @@ private void acceptGift(ItemStack stack, GiftType gift, ServerPlayerEntity playe
}

//modify mood and hearts
entity.getVillagerBrain().modifyMoodValue((int)(desaturatedSatisfaction * Config.getInstance().giftMoodEffect + Config.getInstance().baseGiftMoodEffect * MathHelper.sign(desaturatedSatisfaction)));
entity.getVillagerBrain().modifyMoodValue((int) (desaturatedSatisfaction * Config.getInstance().giftMoodEffect + Config.getInstance().baseGiftMoodEffect * MathHelper.sign(desaturatedSatisfaction)));
CriterionMCA.HEARTS_CRITERION.trigger(player, memory.getHearts(), desaturatedSatisfaction, "gift");
memory.modHearts(desaturatedSatisfaction);
}
Expand All @@ -193,7 +201,7 @@ private boolean handleSpecialCaseGift(ServerPlayerEntity player, ItemStack stack
Item item = stack.getItem();

if (item instanceof SpecialCaseGift) {
if (((SpecialCaseGift)item).handle(player, entity)) {
if (((SpecialCaseGift) item).handle(player, entity)) {
stack.decrement(1);
}
return true;
Expand Down
12 changes: 6 additions & 6 deletions common/src/main/java/net/mca/entity/ai/GPT3.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class GPT3 {
private static final Map<UUID, UUID> lastInteraction = new HashMap<>();

public static String translate(String phrase) {
return phrase.replaceAll("_", " ").toLowerCase(Locale.ROOT).replace("mca.", "");
return phrase.replace("_", " ").toLowerCase(Locale.ROOT).replace("mca.", "");
}

public record Answer(String answer, String error) {
Expand All @@ -52,8 +52,8 @@ public static Answer request(String encodedURL) {

// parse json
JsonObject map = JsonParser.parseString(body).getAsJsonObject();
String answer = map.has("answer") ? map.get("answer").getAsString().trim().replace("\n", "") : "";
String error = map.has("error") ? map.get("error").getAsString().trim().replace("\n", "") : null;
String answer = map.has("answer") ? map.get("answer").getAsString().trim().replace("\n", " ") : "";
String error = map.has("error") ? map.get("error").getAsString().trim().replace("\n", " ") : null;

return new Answer(answer, error);
} catch (Exception e) {
Expand All @@ -76,9 +76,9 @@ public static Optional<String> answer(ServerPlayerEntity player, VillagerEntityM
lastInteraction.put(player.getUuid(), villager.getUuid());

// remember phrase
List<String> pastDialogue = memory.computeIfAbsent(villager.getUuid(), (key) -> new LinkedList<>());
int MEMORY = MIN_MEMORY + Math.min(5, Config.getInstance().villagerChatAIIntelligence) * (MAX_MEMORY - MIN_MEMORY) / 5;
while (pastDialogue.stream().mapToInt(v -> (v.length() / 4)).sum() > MEMORY) {
List<String> pastDialogue = memory.computeIfAbsent(villager.getUuid(), key -> new LinkedList<>());
int memory = MIN_MEMORY + Math.min(5, Config.getInstance().villagerChatAIIntelligence) * (MAX_MEMORY - MIN_MEMORY) / 5;
while (pastDialogue.stream().mapToInt(v -> (v.length() / 4)).sum() > memory) {
pastDialogue.remove(0);
}
pastDialogue.add("$player: " + msg);
Expand Down
8 changes: 4 additions & 4 deletions common/src/main/java/net/mca/entity/ai/Pregnancy.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public VillagerEntityMCA createChild(Gender gender, VillagerEntityMCA partner) {

// advancement
child.getRelationships().getFamily(2, 0)
.filter(e -> e instanceof ServerPlayerEntity)
.filter(ServerPlayerEntity.class::isInstance)
.map(ServerPlayerEntity.class::cast)
.forEach(CriterionMCA.FAMILY::trigger);

Expand All @@ -128,7 +128,7 @@ public VillagerEntityMCA createChild(Gender gender) {

private Optional<VillagerEntityMCA> getFather() {
return mother.getRelationships().getPartner()
.filter(father -> father instanceof VillagerEntityMCA)
.filter(VillagerEntityMCA.class::isInstance)
.map(VillagerEntityMCA.class::cast);
}

Expand All @@ -140,8 +140,8 @@ public void procreate(Entity spouse) {
int count = areTwins ? 2 : 1;

// advancement
if (spouse instanceof ServerPlayerEntity) {
CriterionMCA.BABY_CRITERION.trigger((ServerPlayerEntity)spouse, count);
if (spouse instanceof ServerPlayerEntity player) {
CriterionMCA.BABY_CRITERION.trigger(player, count);
}

long seed = random.nextLong();
Expand Down
Loading

0 comments on commit 557d04a

Please sign in to comment.