commit
1eea4b9eaa
567 files changed
+81290
No files matched your search
@@ -0,0 +1,408 @@
|
||||
package com.nonid;
|
||||
|
||||
import com.nonid.api.NonChangeSource;
|
||||
import com.nonid.data.NonEntityProfiles;
|
||||
import com.nonid.network.GenderSelectionPromptS2CPayload;
|
||||
import com.nonid.network.SetPlayerGenderC2SPayload;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents.Load;
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.CowEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
||||
final class NonGenderSystem {
|
||||
private static final String GENDER_TAG_MALE = "gender.male";
|
||||
private static final String GENDER_TAG_FEMALE = "gender.female";
|
||||
private static final String GENDER_TAG_SELECTED = "gender.selected";
|
||||
private static final int DEFAULT_PLAYER_GENDER_MASK = 2;
|
||||
|
||||
private NonGenderSystem() {
|
||||
}
|
||||
|
||||
static void registerMobGenderTags() {
|
||||
ServerEntityEvents.ENTITY_LOAD.register((Load)(entity, world) -> {
|
||||
if (entity instanceof MobEntity) {
|
||||
if (entity.getType() != NeedsOfNature.HORSE_LIQUID_COLLECTOR_ENTITY_TYPE) {
|
||||
if (entity.getType() != NeedsOfNature.PREGNANCY_EGG_ENTITY_TYPE) {
|
||||
Set<String> tags = entity.getCommandTags();
|
||||
boolean hasMale = tags.contains("gender.male");
|
||||
boolean hasFemale = tags.contains("gender.female");
|
||||
if (!hasMale && !hasFemale) {
|
||||
NonConfig.GenderSpawnChances chances = resolveGenderSpawnChances(entity);
|
||||
int roll = world.getRandom().nextInt(100);
|
||||
if (roll < chances.male()) {
|
||||
entity.addCommandTag("gender.male");
|
||||
hasMale = true;
|
||||
} else if (roll < chances.male() + chances.female()) {
|
||||
entity.addCommandTag("gender.female");
|
||||
hasFemale = true;
|
||||
} else {
|
||||
entity.addCommandTag("gender.male");
|
||||
entity.addCommandTag("gender.female");
|
||||
hasMale = true;
|
||||
hasFemale = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof GenderHolder holder) {
|
||||
int mask = 0;
|
||||
if (hasMale) {
|
||||
mask |= 1;
|
||||
}
|
||||
|
||||
if (hasFemale) {
|
||||
mask |= 2;
|
||||
}
|
||||
|
||||
holder.setGenderMask(mask);
|
||||
}
|
||||
|
||||
if (entity instanceof EnergyHolder holder && world instanceof ServerWorld serverWorld) {
|
||||
holder.ensureEnergyInitialized(serverWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void registerCowMilkingGenderGate() {
|
||||
UseEntityCallback.EVENT.register((UseEntityCallback)(player, world, hand, entity, hitResult) -> {
|
||||
NonConfig config = NeedsOfNature.getConfig();
|
||||
if (config == null || !config.femaleCowOnlyMilking()) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
if (entity instanceof CowEntity cow) {
|
||||
if (cow.getType() != EntityType.COW) {
|
||||
return ActionResult.PASS;
|
||||
} else {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
if (!stack.isEmpty() && stack.isOf(Items.BUCKET)) {
|
||||
return (ActionResult)(canCowBeMilked(cow) ? ActionResult.PASS : ActionResult.FAIL);
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void registerPlayerGenderRequests() {
|
||||
ServerPlayNetworking.registerGlobalReceiver(SetPlayerGenderC2SPayload.ID, (payload, context) -> context.server().execute(() -> {
|
||||
ServerPlayerEntity player = context.player();
|
||||
if (player != null) {
|
||||
handleClientGenderRequest(player, payload.mask(), payload.initialSelection());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
static void ensurePlayerGenderInitialized(ServerPlayerEntity player) {
|
||||
if (player != null) {
|
||||
int mask = 0;
|
||||
if (player instanceof GenderHolder holder) {
|
||||
mask = holder.getGenderMask() & 3;
|
||||
}
|
||||
|
||||
if (mask == 0) {
|
||||
mask = resolveGenderMaskFromTags(player);
|
||||
}
|
||||
|
||||
if (mask != 0) {
|
||||
markPlayerGenderSelected(player);
|
||||
}
|
||||
|
||||
if (mask == 0) {
|
||||
NonConfig config = NeedsOfNature.getConfig();
|
||||
if (config.requirePlayerGenderSelectionOnJoin()) {
|
||||
sendGenderSelectionPrompt(player);
|
||||
} else {
|
||||
int var3 = 2;
|
||||
applyPlayerGenderMask(player, var3, true, NonChangeSource.SYSTEM);
|
||||
}
|
||||
} else {
|
||||
applyGenderMask(player, mask);
|
||||
if (NeedsOfNature.getConfig().requirePlayerGenderSelectionOnJoin() && !hasPlayerGenderSelected(player)) {
|
||||
sendGenderSelectionPrompt(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int setPlayerGenderFromCommand(ServerPlayerEntity player, int mask) {
|
||||
return setPlayerGenderFromCommand(player, mask, NonChangeSource.COMMAND);
|
||||
}
|
||||
|
||||
static int setPlayerGenderFromCommand(ServerPlayerEntity player, int mask, NonChangeSource source) {
|
||||
int normalized = normalizeGenderMask(mask);
|
||||
applyPlayerGenderMask(player, normalized, true, source == null ? NonChangeSource.COMMAND : source);
|
||||
return normalized;
|
||||
}
|
||||
|
||||
static void resetPlayerGenderSelection(ServerPlayerEntity player) {
|
||||
if (player != null) {
|
||||
clearPlayerGenderSelectionState(player);
|
||||
sendGenderSelectionPrompt(player);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean canClientChangeGenderFreely() {
|
||||
return NeedsOfNature.getConfig().allowPlayerGenderChangeAnytime();
|
||||
}
|
||||
|
||||
static boolean isStartingGenderAllowed(int mask) {
|
||||
int normalized = normalizeGenderMask(mask);
|
||||
int allowed = NeedsOfNature.getConfig().getAllowedStartingGenderMask();
|
||||
return (allowed & startingGenderChoiceBit(normalized)) != 0;
|
||||
}
|
||||
|
||||
private static void handleClientGenderRequest(ServerPlayerEntity player, int requestedMask, boolean initialSelection) {
|
||||
NonConfig config = NeedsOfNature.getConfig();
|
||||
int normalized = normalizeGenderMask(requestedMask);
|
||||
boolean selected = hasPlayerGenderSelected(player);
|
||||
if (initialSelection) {
|
||||
if (selected && !config.allowPlayerGenderChangeAnytime()) {
|
||||
sendCurrentGenderFeedback(player, "Gender has already been selected on this server.");
|
||||
} else if (!isStartingGenderAllowed(normalized)) {
|
||||
sendGenderSelectionPrompt(player);
|
||||
} else {
|
||||
applyPlayerGenderMask(player, normalized, true, NonChangeSource.JOIN_SELECTION);
|
||||
}
|
||||
} else {
|
||||
if (!config.allowPlayerGenderChangeAnytime()) {
|
||||
if (!selected && config.requirePlayerGenderSelectionOnJoin()) {
|
||||
sendGenderSelectionPrompt(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
sendCurrentGenderFeedback(player, "Gender changes are disabled by this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isStartingGenderAllowed(normalized)) {
|
||||
sendGenderSelectionPrompt(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
applyPlayerGenderMask(player, normalized, true, NonChangeSource.CLIENT_PREFERENCE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyPlayerGenderMask(ServerPlayerEntity player, int mask, boolean markSelected) {
|
||||
applyPlayerGenderMask(player, mask, markSelected, NonChangeSource.SYSTEM);
|
||||
}
|
||||
|
||||
private static void applyPlayerGenderMask(ServerPlayerEntity player, int mask, boolean markSelected, NonChangeSource source) {
|
||||
applyGenderMask(player, mask, source);
|
||||
if (markSelected) {
|
||||
markPlayerGenderSelected(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static void markPlayerGenderSelected(ServerPlayerEntity player) {
|
||||
if (player != null) {
|
||||
player.addCommandTag("gender.selected");
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearPlayerGenderSelectionState(ServerPlayerEntity player) {
|
||||
if (player != null) {
|
||||
player.removeCommandTag("gender.selected");
|
||||
player.removeCommandTag("gender.male");
|
||||
player.removeCommandTag("gender.female");
|
||||
if (player instanceof GenderHolder holder) {
|
||||
holder.setGenderMask(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasPlayerGenderSelected(ServerPlayerEntity player) {
|
||||
return player != null && player.getCommandTags().contains("gender.selected");
|
||||
}
|
||||
|
||||
private static void sendGenderSelectionPrompt(ServerPlayerEntity player) {
|
||||
if (player != null) {
|
||||
NonConfig config = NeedsOfNature.getConfig();
|
||||
ServerPlayNetworking.send(
|
||||
player,
|
||||
new GenderSelectionPromptS2CPayload(
|
||||
config.getAllowedStartingGenderMask(), currentOrDefaultPlayerMask(player), !config.allowPlayerGenderChangeAnytime()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendCurrentGenderFeedback(ServerPlayerEntity player, String message) {
|
||||
if (player != null) {
|
||||
player.sendMessage(Text.literal("[NoN] " + message), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static int currentOrDefaultPlayerMask(ServerPlayerEntity player) {
|
||||
if (player instanceof GenderHolder holder) {
|
||||
int mask = holder.getGenderMask() & 3;
|
||||
if (mask != 0) {
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
return firstAllowedStartingMask(NeedsOfNature.getConfig().getAllowedStartingGenderMask());
|
||||
}
|
||||
|
||||
private static int firstAllowedStartingMask(int allowedMask) {
|
||||
int allowed = allowedMask & 3;
|
||||
if ((allowedMask & 2) != 0) {
|
||||
return 2;
|
||||
} else if ((allowedMask & 1) != 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return (allowedMask & 4) != 0 ? 3 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
private static int startingGenderChoiceBit(int genderMask) {
|
||||
return switch (genderMask & 3) {
|
||||
case 1 -> 1;
|
||||
case 2 -> 2;
|
||||
case 3 -> 4;
|
||||
default -> 2;
|
||||
};
|
||||
}
|
||||
|
||||
private static int normalizeGenderMask(int mask) {
|
||||
int normalized = mask & 3;
|
||||
return normalized == 0 ? 2 : normalized;
|
||||
}
|
||||
|
||||
static NonConfig.GenderSpawnChances resolveGenderSpawnChances(Entity entity) {
|
||||
return NonEntityProfiles.resolve(entity).genderSpawn();
|
||||
}
|
||||
|
||||
static Map<String, NonConfig.GenderSpawnChances> resolveEffectiveGenderSpawnMap() {
|
||||
return NonEntityProfiles.resolveEffectiveGenderSpawnMap();
|
||||
}
|
||||
|
||||
static boolean hasMaleTag(Entity entity) {
|
||||
return entity != null && entity.getCommandTags().contains("gender.male");
|
||||
}
|
||||
|
||||
static boolean hasFemaleTag(Entity entity) {
|
||||
return entity != null && entity.getCommandTags().contains("gender.female");
|
||||
}
|
||||
|
||||
static boolean isOnlyMale(Entity entity) {
|
||||
return entity instanceof GenderHolder holder ? (holder.getGenderMask() & 3) == 1 : false;
|
||||
}
|
||||
|
||||
static boolean hasMaleGender(Entity entity) {
|
||||
if (entity instanceof GenderHolder holder) {
|
||||
int mask = holder.getGenderMask() & 3;
|
||||
if (mask != 0) {
|
||||
return (mask & 1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
return hasMaleTag(entity);
|
||||
}
|
||||
|
||||
static boolean hasFemaleGender(Entity entity) {
|
||||
if (entity instanceof GenderHolder holder) {
|
||||
int mask = holder.getGenderMask() & 3;
|
||||
if (mask != 0) {
|
||||
return (mask & 2) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
return hasFemaleTag(entity);
|
||||
}
|
||||
|
||||
static NonLiquidTankType getLiquidTankType(Entity entity) {
|
||||
return isOnlyMale(entity) ? NonLiquidTankType.A : NonLiquidTankType.V;
|
||||
}
|
||||
|
||||
static void applyGenderMask(Entity entity, int mask) {
|
||||
applyGenderMask(entity, mask, NonChangeSource.SYSTEM);
|
||||
}
|
||||
|
||||
static boolean isOnlyFemale(Entity entity) {
|
||||
return entity == null ? false : hasFemaleGender(entity) && !hasMaleGender(entity);
|
||||
}
|
||||
|
||||
static void applyGenderMask(Entity entity, int mask, NonChangeSource source) {
|
||||
if (entity != null) {
|
||||
int beforeMask = entity instanceof GenderHolder existingHolder ? existingHolder.getGenderMask() & 3 : 0;
|
||||
int normalizedMask = mask & 3;
|
||||
if (normalizedMask == 0) {
|
||||
normalizedMask = 2;
|
||||
}
|
||||
|
||||
entity.removeCommandTag("gender.male");
|
||||
entity.removeCommandTag("gender.female");
|
||||
if ((normalizedMask & 1) != 0) {
|
||||
entity.addCommandTag("gender.male");
|
||||
}
|
||||
|
||||
if ((normalizedMask & 2) != 0) {
|
||||
entity.addCommandTag("gender.female");
|
||||
}
|
||||
|
||||
if (entity instanceof GenderHolder holder) {
|
||||
holder.setGenderMask(normalizedMask);
|
||||
}
|
||||
|
||||
if (normalizedMask == 1 && entity instanceof ServerPlayerEntity player) {
|
||||
if (NonMessSystem.normalizeMaleOnlyMess(player, false)) {
|
||||
NonMessSystem.broadcastMessState(player);
|
||||
}
|
||||
|
||||
NeedsOfNature.clearPregnancyState(player, true);
|
||||
}
|
||||
|
||||
if (entity instanceof ServerPlayerEntity player && (beforeMask & 3) != (normalizedMask & 3)) {
|
||||
NonApiInternals.fireGenderChanged(player, normalizedMask, source == null ? NonChangeSource.SYSTEM : source);
|
||||
NonPregnancyConceptionSystem.syncState(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canCowBeMilked(CowEntity cow) {
|
||||
if (cow == null) {
|
||||
return true;
|
||||
} else {
|
||||
return cow instanceof GenderHolder holder ? holder.hasGender(2) : cow.getCommandTags().contains("gender.female");
|
||||
}
|
||||
}
|
||||
|
||||
private static int resolveGenderMaskFromTags(Entity entity) {
|
||||
if (entity == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Set<String> tags = entity.getCommandTags();
|
||||
int mask = 0;
|
||||
if (tags.contains("gender.male")) {
|
||||
mask |= 1;
|
||||
}
|
||||
|
||||
if (tags.contains("gender.female")) {
|
||||
mask |= 2;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user