button = buttonList.stream().filter(
(b) -> b instanceof GuiButtonEx && ((GuiButtonEx) b).getApiButton().getIdentifier().equals(id)).findFirst();
return button.map(guiButton -> (GuiButtonEx) guiButton);
}
}
================================================
FILE: src/main/java/mca/api/types/APIButton.java
================================================
package mca.api.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumConstraint;
import net.minecraft.entity.player.EntityPlayer;
import java.util.List;
/**
* APIButton is a button defined in assets/mca/api/gui/*
*
* These buttons are dynamically attached to a GuiScreen and include additional instruction/constraints for building
* and processing interactions.
*/
@AllArgsConstructor
public class APIButton {
@Getter private int id; // numeric id
@Getter private String identifier; // string identifier for the button in the .lang file
@Getter private int x; // x position
@Getter private int y; // y position
@Getter private int width; // button width
@Getter private int height; // button height
@Getter private boolean notifyServer; // whether the button press is sent to the server for processing
@Getter private boolean targetServer; // whether the button is processed by the villager or the server itself
private String constraints; // list of EnumConstraints separated by a pipe character |
@Getter private boolean isInteraction; // whether the button is an interaction that generates a response and boosts/decreases hearts
public List getConstraints() {
return EnumConstraint.fromStringList(constraints);
}
/**
* Determines if the given villager and player match the constraints for this button, allowing the action to be performed
*
* @param villager Instance of the EntityVillagerMCA the button would perform the action on
* @param player Instance of the EntityPlayer performing the action
* @return boolean whether the button is valid for a constraint
*/
public boolean isValidForConstraint(EntityVillagerMCA villager, EntityPlayer player) {
List constraints = getConstraints();
if (constraints.contains(EnumConstraint.ADULTS) && !villager.isChild()) {
return true;
} else if (constraints.contains(EnumConstraint.SPOUSE) && villager.isMarriedTo(player.getUniqueID())) {
return true;
} else if (constraints.contains(EnumConstraint.NOT_SPOUSE) && !villager.isMarriedTo(player.getUniqueID())) {
return true;
} else if (constraints.contains(EnumConstraint.FAMILY) && (villager.playerIsParent(player) || villager.isMarriedTo(player.getUniqueID()))){
return true;
} else if (constraints.contains(EnumConstraint.NOT_FAMILY) && !(villager.playerIsParent(player) || villager.isMarriedTo(player.getUniqueID()))) {
return true;
} else if (constraints.isEmpty()) {
return true;
}
return false;
}
}
================================================
FILE: src/main/java/mca/api/types/Gift.java
================================================
package mca.api.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.core.MCA;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
@AllArgsConstructor
@Getter
public class Gift {
private String type;
private String name;
private int value;
/**
* Used for verifying if a given gift exists in the game's registries.
* @return True if the item/block exists.
*/
public boolean exists() {
if (getType().equals("block")) {
return Block.getBlockFromName(getName()) != null;
} else if (getType().equals("item")) {
return Item.getByNameOrId(getName()) != null;
} else {
MCA.getLog().warn("Could not process gift '" + getName() + "'- bad type name of '" + getType() + "'. Must be 'item' or 'block'");
return false;
}
}
}
================================================
FILE: src/main/java/mca/api/types/SkinsGroup.java
================================================
package mca.api.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.enums.EnumGender;
@AllArgsConstructor
public class SkinsGroup {
private String gender;
@Getter private String profession;
@Getter private String[] paths;
public EnumGender getGender() {
return EnumGender.byName(gender);
}
}
================================================
FILE: src/main/java/mca/blocks/BlockVillagerSpawner.java
================================================
package mca.blocks;
import com.google.common.base.Optional;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Random;
public class BlockVillagerSpawner extends Block {
public BlockVillagerSpawner() {
super(Material.IRON);
setTickRandomly(true);
setBlockUnbreakable();
}
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random random) {
super.updateTick(world, pos, state, random);
int nearbyVillagers = world.getEntitiesWithinAABB(EntityVillagerMCA.class, new AxisAlignedBB(pos).expand(32D, 32D, 32D)).size();
if (nearbyVillagers < MCA.getConfig().villagerSpawnerCap) {
int yMod = 0;
// Start from the current point possible and count up until air is hit. This allows the spawner to
// be placed anywhere below ground and still spawn a villager on a top level.
while (pos.getY() + yMod < 256) {
BlockPos current = pos.add(0, yMod, 0);
BlockPos above = pos.add(0, yMod + 1, 0);
if (world.isAirBlock(current) && world.isAirBlock(above)) {
EntityVillagerMCA villager = new EntityVillagerMCA(world, Optional.absent(), Optional.absent());
villager.setPosition(current.getX(), current.getY(), current.getZ());
world.spawnEntity(villager);
break;
}
yMod++;
}
}
world.scheduleUpdate(pos, this, MCA.getConfig().villagerSpawnerRateMinutes * 72000);
}
}
================================================
FILE: src/main/java/mca/client/MCAGuiFactory.java
================================================
package mca.client;
import mca.client.gui.GuiConfigPage;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.IModGuiFactory;
import java.util.Set;
public class MCAGuiFactory implements IModGuiFactory
{
@Override
public void initialize(Minecraft minecraftInstance) {}
@Override
public GuiScreen createConfigGui(GuiScreen screen) {
return new GuiConfigPage(screen);
}
@Override
public Set runtimeGuiCategories() {
return null;
}
@Override
public boolean hasConfigGui() {
return true;
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiConfigPage.java
================================================
package mca.client.gui;
import mca.core.MCA;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.IConfigElement;
import java.util.List;
public class GuiConfigPage extends GuiConfig {
public GuiConfigPage(GuiScreen parent) {
this(parent,
MCA.getConfig().getCategories(),
MCA.MODID, false, false, GuiConfig.getAbridgedConfigPath(MCA.getConfig().getInstance().toString()));
}
public GuiConfigPage(GuiScreen parentScreen, List configElements, String modID, boolean allRequireWorldRestart, boolean allRequireMcRestart, String title) {
super(parentScreen, configElements, modID, allRequireWorldRestart, allRequireMcRestart, title);
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiInteract.java
================================================
package mca.client.gui;
import mca.api.API;
import mca.client.gui.component.GuiButtonEx;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.ParentData;
import mca.entity.data.PlayerHistory;
import mca.enums.EnumMarriageState;
import mca.enums.EnumMoveState;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
import java.util.Optional;
@SideOnly(Side.CLIENT)
public class GuiInteract extends GuiScreen {
private static final ResourceLocation ICON_TEXTURES = new ResourceLocation("mca:textures/gui.png");
private static boolean displaySuccessChance;
private final EntityVillagerMCA villager;
private final EntityPlayer player;
private boolean inGiftMode;
private int timeSinceLastClick;
private int marriedIconU = 0;
private int engagedIconU = 64;
private int notMarriedIconU = 16;
private int parentsIconU = 32;
private int giftIconU = 48;
private int redHeartIconU = 80;
private int blackHeartIconU = 96;
private int goldHeartIconU = 112;
private int mouseX;
private int mouseY;
// Tracks which page we're on in the GUI for sending button events
private String activeKey;
public GuiInteract(EntityVillagerMCA villager, EntityPlayer player) {
super();
this.villager = villager;
this.player = player;
this.activeKey = "main";
}
@Override
public void initGui() {
drawMainButtonMenu();
}
@Override
public void onGuiClosed() {
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
public void updateScreen() {
if (timeSinceLastClick < 100) {
timeSinceLastClick++;
}
}
@Override
public void drawScreen(int i, int j, float f) {
super.drawScreen(i, j, f);
drawIcons();
drawTextPopups();
mouseX = Mouse.getEventX() * width / mc.displayWidth;
mouseY = height - Mouse.getEventY() * height / mc.displayHeight - 1;
}
@Override
public void handleMouseInput() throws IOException {
super.handleMouseInput();
if (Mouse.getEventDWheel() < 0) {
player.inventory.currentItem = player.inventory.currentItem == 8 ? 0 : player.inventory.currentItem + 1;
} else if (Mouse.getEventDWheel() > 0) {
player.inventory.currentItem = player.inventory.currentItem == 0 ? 8 : player.inventory.currentItem - 1;
}
}
@Override
protected void mouseClicked(int posX, int posY, int button) throws IOException {
super.mouseClicked(posX, posY, button);
// Right mouse button
if (inGiftMode && button == 1) NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction(activeKey, "gui.button.gift", villager.getUniqueID()));
}
@Override
protected void keyTyped(char keyChar, int keyCode) {
// Hotkey to leave gift mode
if (keyCode == Keyboard.KEY_ESCAPE) {
if (inGiftMode) {
inGiftMode = false;
enableAllButtons();
} else {
this.mc.displayGuiScreen(null);
}
} else if (keyCode == Keyboard.KEY_LCONTROL) {
displaySuccessChance = !displaySuccessChance;
} else {
try {
int intInput = Integer.parseInt(String.valueOf(keyChar));
if (intInput > 0) {
player.inventory.currentItem = intInput - 1;
}
} catch (NumberFormatException ignored) {
// When a non numeric character is entered.
}
}
}
private void drawIcons() {
PlayerHistory history = villager.getPlayerHistoryFor(player.getUniqueID());
EnumMarriageState marriageState = EnumMarriageState.byId(villager.get(EntityVillagerMCA.MARRIAGE_STATE));
int marriageIconU =
marriageState == EnumMarriageState.MARRIED ? marriedIconU :
marriageState == EnumMarriageState.ENGAGED ? engagedIconU :
notMarriedIconU;
int heartIconU =
history.getHearts() < 0 ? blackHeartIconU :
history.getHearts() >= 100 ? goldHeartIconU :
redHeartIconU;
GL11.glPushMatrix();
{
GL11.glColor3f(255.0F, 255.0F, 255.0F);
GL11.glScalef(2.0F, 2.0F, 2.0F);
this.mc.getTextureManager().bindTexture(ICON_TEXTURES);
this.drawTexturedModalRect(5, 15, heartIconU, 0, 16, 16);
this.drawTexturedModalRect(5, 30, marriageIconU, 0, 16, 16);
if (canDrawParentsIcon()) this.drawTexturedModalRect(5, 45, parentsIconU, 0, 16, 16);
if (canDrawGiftIcon()) this.drawTexturedModalRect(5, 60, giftIconU, 0, 16, 16);
}
GL11.glPopMatrix();
}
private void drawTextPopups() {
EnumMarriageState marriageState = EnumMarriageState.byId(villager.get(EntityVillagerMCA.MARRIAGE_STATE));
String marriageInfo;
if (hoveringOverHeartsIcon()) {
int hearts = villager.getPlayerHistoryFor(player.getUniqueID()).getHearts();
this.drawHoveringText(hearts + " hearts", 35, 55);
}
if (hoveringOverMarriageIcon()) {
String spouseName = villager.get(EntityVillagerMCA.SPOUSE_NAME);
if (marriageState == EnumMarriageState.MARRIED) marriageInfo = MCA.getLocalizer().localize("gui.interact.label.married", spouseName);
else if (marriageState == EnumMarriageState.ENGAGED) marriageInfo = MCA.getLocalizer().localize("gui.interact.label.engaged", spouseName);
else marriageInfo = MCA.getLocalizer().localize("gui.interact.label.notmarried");
this.drawHoveringText(marriageInfo, 35, 85);
}
if (canDrawParentsIcon() && hoveringOverParentsIcon()) {
ParentData data = ParentData.fromNBT(villager.get(EntityVillagerMCA.PARENTS));
this.drawHoveringText(MCA.getLocalizer().localize("gui.interact.label.parents", data.getParent1Name(), data.getParent2Name()), 35, 115);
}
if (canDrawGiftIcon() && hoveringOverGiftIcon()) this.drawHoveringText(MCA.getLocalizer().localize("gui.interact.label.gift"), 35, 145);
}
private boolean hoveringOverHeartsIcon() {
return mouseX <= 32 && mouseX >= 16 && mouseY >= 32 && mouseY <= 48;
}
private boolean hoveringOverMarriageIcon() {
return mouseX <= 32 && mouseX >= 16 && mouseY >= 66 && mouseY <= 81;
}
private boolean hoveringOverParentsIcon() {
return mouseX <= 32 && mouseX >= 16 && mouseY >= 100 && mouseY <= 115;
}
private boolean hoveringOverGiftIcon() {
return mouseX <= 32 && mouseX >= 16 && mouseY >= 124 && mouseY <= 148;
}
private boolean canDrawParentsIcon() {
ParentData data = ParentData.fromNBT(villager.get(EntityVillagerMCA.PARENTS));
return !data.getParent1UUID().equals(Constants.ZERO_UUID) &&
!data.getParent2UUID().equals(Constants.ZERO_UUID);
}
private boolean canDrawGiftIcon() {
return villager.getPlayerHistoryFor(player.getUniqueID()).isGiftPresent();
}
protected void actionPerformed(GuiButton button) {
GuiButtonEx btn = (GuiButtonEx) button;
String id = btn.getApiButton().getIdentifier();
if (timeSinceLastClick <= 2) {
return; /* Prevents click-throughs on Mojang's button system */
}
timeSinceLastClick = 0;
/* Progression to different GUIs */
if (id.equals("gui.button.interact")) {
activeKey = "interact";
drawInteractButtonMenu();
return;
} else if (id.equals("gui.button.work")) {
activeKey = "work";
drawWorkButtonMenu();
return;
} else if (id.equals("gui.button.backarrow")) {
drawMainButtonMenu();
activeKey = "main";
return;
} else if (id.equals("gui.button.location")) {
activeKey = "location";
drawLocationButtonMenu();
return;
}
/* Anything that should notify the server is handled here */
else if (btn.getApiButton().isNotifyServer()) {
NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction(activeKey, id, villager.getUniqueID()));
} else if (id.equals("gui.button.gift")) {
this.inGiftMode = true;
disableAllButtons();
return;
}
this.mc.displayGuiScreen(null);
}
private void drawMainButtonMenu() {
buttonList.clear();
API.addButtons("main", villager, player, this);
EnumMoveState moveState = EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE));
if (moveState == EnumMoveState.FOLLOW) disableButton("gui.button.follow");
else if (moveState == EnumMoveState.STAY) disableButton("gui.button.stay");
else if (moveState == EnumMoveState.MOVE) disableButton("gui.button.move");
}
private void drawInteractButtonMenu() {
buttonList.clear();
API.addButtons("interact", villager, player, this);
}
private void drawWorkButtonMenu() {
buttonList.clear();
API.addButtons("work", villager, player, this);
}
private void drawLocationButtonMenu() {
buttonList.clear();
API.addButtons("location", villager, player, this);
}
private void disableButton(String id) {
Optional b = API.getButton(id, this);
b.ifPresent(guiButtonEx -> guiButtonEx.enabled = false);
}
private void enableAllButtons() {
buttonList.forEach((b) -> b.enabled = true);
}
private void disableAllButtons() {
buttonList.forEach((b) -> b.enabled = false);
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiNameBaby.java
================================================
package mca.client.gui;
import mca.api.API;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.items.ItemBaby;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import java.io.IOException;
@SideOnly(Side.CLIENT)
public class GuiNameBaby extends GuiScreen {
private final EntityPlayer player;
private GuiTextField babyNameTextField;
private GuiButton doneButton;
private GuiButton randomButton;
private ItemBaby baby;
public GuiNameBaby(EntityPlayer player, ItemStack babyStack) {
super();
this.player = player;
if (babyStack.getItem() instanceof ItemBaby) this.baby = (ItemBaby) babyStack.getItem();
}
@Override
public void updateScreen() {
super.updateScreen();
if (babyNameTextField != null) {
babyNameTextField.updateCursorCounter();
doneButton.enabled = !babyNameTextField.getText().isEmpty();
}
}
@Override
public void initGui() {
Keyboard.enableRepeatEvents(true);
buttonList.clear();
buttonList.add(doneButton = new GuiButton(1, width / 2 - 40, height / 2 - 10, 80, 20, MCA.getLocalizer().localize("gui.button.done")));
buttonList.add(randomButton = new GuiButton(2, width / 2 + 105, height / 2 - 60, 60, 20, MCA.getLocalizer().localize("gui.button.random")));
babyNameTextField = new GuiTextField(3, fontRenderer, width / 2 - 100, height / 2 - 60, 200, 20);
babyNameTextField.setMaxStringLength(32);
if (this.baby == null) this.mc.displayGuiScreen(null);
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
protected void actionPerformed(GuiButton button) {
if (button == doneButton) {
NetMCA.INSTANCE.sendToServer(new NetMCA.BabyName(babyNameTextField.getText().trim()));
mc.displayGuiScreen(null);
} else if (button == randomButton) {
babyNameTextField.setText(API.getRandomName(baby.getGender()));
}
}
@Override
protected void keyTyped(char c, int i) {
babyNameTextField.textboxKeyTyped(c, i);
}
@Override
protected void mouseClicked(int clickX, int clickY, int clicked) throws IOException {
super.mouseClicked(clickX, clickY, clicked);
babyNameTextField.mouseClicked(clickX, clickY, clicked);
}
@Override
public void drawScreen(int sizeX, int sizeY, float offset) {
drawDefaultBackground();
drawString(fontRenderer, MCA.getLocalizer().localize("gui.title.namebaby"), width / 2 - 100, height / 2 - 70, 0xa0a0a0);
babyNameTextField.drawTextBox();
super.drawScreen(sizeX, sizeY, offset);
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiStaffOfLife.java
================================================
package mca.client.gui;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@SideOnly(Side.CLIENT)
public class GuiStaffOfLife extends GuiScreen {
private Map villagerData;
private GuiButton reviveButton;
private GuiButton nameButton;
private GuiButton backButton;
private GuiButton nextButton;
private GuiButton closeButton;
private EntityVillagerMCA dummy;
private EntityPlayer player;
// selection fields
private int index = 0;
private List keys = new ArrayList<>();
public GuiStaffOfLife(EntityPlayer player) {
super();
this.player = player;
}
@Override
public void initGui() {
NetMCA.INSTANCE.sendToServer(new NetMCA.SavedVillagersRequest());
buttonList.clear();
buttonList.add(backButton = new GuiButton(1, width / 2 - 123, height / 2 + 65, 20, 20, "<<"));
buttonList.add(nextButton = new GuiButton(2, width / 2 + 103, height / 2 + 65, 20, 20, ">>"));
buttonList.add(nameButton = new GuiButton(3, width / 2 - 100, height / 2 + 65, 200, 20, ""));
buttonList.add(reviveButton = new GuiButton(4, width / 2 - 100, height / 2 + 90, 60, 20, MCA.getLocalizer().localize("gui.button.revive")));
buttonList.add(closeButton = new GuiButton(5, width / 2 + 40, height / 2 + 90, 60, 20, MCA.getLocalizer().localize("gui.button.exit")));
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
protected void actionPerformed(GuiButton guibutton) {
if (guibutton == reviveButton) {
NetMCA.INSTANCE.sendToServer(new NetMCA.ReviveVillager(UUID.fromString(keys.get(index))));
mc.displayGuiScreen(null);
} else if (guibutton == backButton) selectData(index - 1);
else if (guibutton == nextButton) selectData(index + 1);
else if (guibutton == closeButton) mc.displayGuiScreen(null);
}
@Override
public void drawScreen(int sizeX, int sizeY, float offset) {
drawDefaultBackground();
drawDummy();
drawCenteredString(fontRenderer, MCA.getLocalizer().localize("gui.title.staffoflife"), width / 2, height / 2 - 110, 0xffffff);
super.drawScreen(sizeX, sizeY, offset);
}
public void setVillagerData(Map data) {
villagerData = data;
if (data.size() > 0) {
dummy = new EntityVillagerMCA(player.world);
keys.addAll(data.keySet());
selectData(0);
} else {
nameButton.displayString = "No villagers found.";
backButton.enabled = false;
nextButton.enabled = false;
nameButton.enabled = false;
reviveButton.enabled = false;
}
}
private void updateDummy(NBTTagCompound nbt) {
dummy.readEntityFromNBT(nbt);
dummy.setHealth(20.0F);
}
private void selectData(int i) {
if (i < 0) i = keys.size() - 1;
else if (i > keys.size() - 1) i = 0;
index = i;
updateDummy(villagerData.get(keys.get(index)));
nameButton.displayString = dummy.getDisplayName().getUnformattedText();
}
private void drawDummy() {
int posX = width / 2;
int posY = height / 2 + 45;
if (dummy != null) GuiInventory.drawEntityOnScreen(posX, posY, 60, 0, 0, dummy);
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiVillagerEditor.java
================================================
package mca.client.gui;
import mca.api.API;
import mca.api.types.APIButton;
import mca.client.gui.component.GuiButtonEx;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.io.IOException;
@SideOnly(Side.CLIENT)
public class GuiVillagerEditor extends GuiScreen {
private final EntityVillagerMCA villager;
private final EntityPlayer player;
private GuiTextField nameTextField;
private GuiTextField professionTextField;
private GuiTextField textureTextField;
public GuiVillagerEditor(EntityVillagerMCA EntityHuman, EntityPlayer player) {
super();
this.player = player;
villager = EntityHuman;
}
@Override
public void updateScreen() {
super.updateScreen();
nameTextField.updateCursorCounter();
professionTextField.updateCursorCounter();
textureTextField.updateCursorCounter();
}
@Override
public void initGui() {
Keyboard.enableRepeatEvents(true);
drawEditorGui();
nameTextField = new GuiTextField(1, fontRenderer, width / 2 - 205, height / 2 - 95, 150, 20);
nameTextField.setMaxStringLength(32);
nameTextField.setText(villager.get(EntityVillagerMCA.VILLAGER_NAME));
professionTextField = new GuiTextField(2, fontRenderer, width / 2 - 190, height / 2 + 10, 250, 20);
professionTextField.setMaxStringLength(64);
professionTextField.setText(villager.getVanillaCareer().getName());
textureTextField = new GuiTextField(3, fontRenderer, width / 2 - 190, height / 2 - 15, 250, 20);
textureTextField.setMaxStringLength(128);
textureTextField.setText(villager.get(EntityVillagerMCA.TEXTURE));
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
@Override
protected void actionPerformed(GuiButton guiButton) {
APIButton btn = ((GuiButtonEx) guiButton).getApiButton();
if (btn.isNotifyServer()) {
NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction("editor", btn.getIdentifier(), villager.getUniqueID()));
} else if (btn.getIdentifier().equals("gui.button.done")) {
mc.displayGuiScreen(null);
} else if (btn.getIdentifier().equals("gui.button.copyuuid")) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(villager.getUniqueID().toString()), null);
Minecraft.getMinecraft().player.sendChatMessage("Villager UUID copied to clipboard.");
} else if (btn.getIdentifier().equals("gui.button.profession.set")) {
String profession = professionTextField.getText();
NetMCA.INSTANCE.sendToServer(new NetMCA.SetProfession(villager.getUniqueID(), profession));
new java.util.Timer().schedule(new java.util.TimerTask() {
@Override
public void run() {
NetMCA.INSTANCE.sendToServer(new NetMCA.CareerRequest(villager.getUniqueID()));
}
},500
);
} else if (btn.getIdentifier().contains("gui.button.texture")) {
String texture = btn.getIdentifier().endsWith(".set") ? textureTextField.getText() : API.getRandomSkin(villager);
NetMCA.INSTANCE.sendToServer(new NetMCA.SetTexture(villager.getUniqueID(), texture));
textureTextField.setText(texture);
}
}
@Override
protected void keyTyped(char c, int i) {
if (i == Keyboard.KEY_ESCAPE) {
Minecraft.getMinecraft().displayGuiScreen(null);
} else {
if (nameTextField.textboxKeyTyped(c, i)) {
String text = nameTextField.getText().trim();
NetMCA.INSTANCE.sendToServer(new NetMCA.SetName(text, villager.getUniqueID()));
}
textureTextField.textboxKeyTyped(c, i);
professionTextField.textboxKeyTyped(c, i);
drawEditorGui();
}
}
@Override
protected void mouseClicked(int clickX, int clickY, int clicked) throws IOException {
super.mouseClicked(clickX, clickY, clicked);
nameTextField.mouseClicked(clickX, clickY, clicked);
professionTextField.mouseClicked(clickX, clickY, clicked);
textureTextField.mouseClicked(clickX, clickY, clicked);
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
private void drawEditorGui() {
buttonList.clear();
API.addButtons("editor", villager, player, this);
}
@Override
public void drawScreen(int sizeX, int sizeY, float offset) {
drawGradientRect(0, 0, width, height, -1072689136, -804253680);
drawString(fontRenderer, "Name:", width / 2 - 205, height / 2 - 110, 0xffffff);
drawCenteredString(fontRenderer, MCA.getLocalizer().localize("gui.title.editor"), width / 2, height / 2 - 110, 0xffffff);
nameTextField.drawTextBox();
professionTextField.drawTextBox();
textureTextField.drawTextBox();
super.drawScreen(sizeX, sizeY, offset);
}
}
================================================
FILE: src/main/java/mca/client/gui/GuiWhistle.java
================================================
package mca.client.gui;
import lombok.NonNull;
import mca.core.forge.NetMCA;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.lang3.StringUtils;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
import static mca.entity.EntityVillagerMCA.*;
@SideOnly(Side.CLIENT)
public class GuiWhistle extends GuiScreen {
private EntityVillagerMCA dummyHuman;
private List villagerDataList;
private GuiButton selectionLeftButton;
private GuiButton selectionRightButton;
private GuiButton villagerNameButton;
private GuiButton callButton;
private GuiButton exitButton;
private int loadingAnimationTicks;
private int selectedIndex;
@Override
public void updateScreen() {
super.updateScreen();
if (loadingAnimationTicks != -1) {
loadingAnimationTicks++;
}
if (loadingAnimationTicks >= 20) {
loadingAnimationTicks = 0;
}
}
@Override
public void initGui() {
buttonList.clear();
buttonList.add(selectionLeftButton = new GuiButton(1, width / 2 - 123, height / 2 + 65, 20, 20, "<<"));
buttonList.add(selectionRightButton = new GuiButton(2, width / 2 + 103, height / 2 + 65, 20, 20, ">>"));
buttonList.add(villagerNameButton = new GuiButton(3, width / 2 - 100, height / 2 + 65, 200, 20, ""));
buttonList.add(callButton = new GuiButton(4, width / 2 - 100, height / 2 + 90, 60, 20, MCA.getLocalizer().localize("gui.button.call")));
buttonList.add(exitButton = new GuiButton(6, width / 2 + 40, height / 2 + 90, 60, 20, MCA.getLocalizer().localize("gui.button.exit")));
NetMCA.INSTANCE.sendToServer(new NetMCA.GetFamily());
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
protected void actionPerformed(GuiButton guibutton) {
if (guibutton == exitButton) {
Minecraft.getMinecraft().displayGuiScreen(null);
}
if (villagerDataList != null && villagerDataList.size() > 0) {
NBTTagCompound data = villagerDataList.get(selectedIndex - 1);
if (guibutton == selectionLeftButton) {
if (selectedIndex == 1) {
selectedIndex = villagerDataList.size();
}
else {
selectedIndex--;
}
}
else if (guibutton == selectionRightButton) {
if (selectedIndex == villagerDataList.size()) {
selectedIndex = 1;
}
else {
selectedIndex++;
}
}
else if (guibutton == callButton) {
NetMCA.INSTANCE.sendToServer(new NetMCA.CallToPlayer(data.getUniqueId("uuid")));
Minecraft.getMinecraft().displayGuiScreen(null);
}
villagerNameButton.displayString = data.getString("name");
updateDummyVillagerWithData(data);
}
}
@Override
public void drawScreen(int sizeX, int sizeY, float offset) {
drawDefaultBackground();
drawCenteredString(fontRenderer, MCA.getLocalizer().localize("gui.title.whistle"), width / 2, height / 2 - 110, 0xffffff);
if (loadingAnimationTicks != -1) {
drawString(fontRenderer, "Loading" + StringUtils.repeat(".", loadingAnimationTicks % 10), width / 2 - 20, height / 2 - 10, 0xffffff);
}
else {
if (villagerDataList.size() == 0) {
drawCenteredString(fontRenderer, "No family members could be found in the area.", width / 2, height / 2 + 50, 0xffffff);
}
else {
drawCenteredString(fontRenderer, selectedIndex + " / " + villagerDataList.size(), width / 2, height / 2 + 50, 0xffffff);
}
}
if (dummyHuman != null) {
drawDummyVillager();
}
super.drawScreen(sizeX, sizeY, offset);
}
private void drawDummyVillager() {
final int posX = width / 2;
int posY = height / 2 + 45;
net.minecraft.client.gui.inventory.GuiInventory.drawEntityOnScreen(posX, posY, 75, 0, 0, dummyHuman);
}
public void setVillagerDataList(@NonNull List dataList) {
this.villagerDataList = dataList;
this.loadingAnimationTicks = -1;
this.selectedIndex = 1;
try {
NBTTagCompound firstData = dataList.get(0);
villagerNameButton.displayString = firstData.getString("name");
dummyHuman = new EntityVillagerMCA(Minecraft.getMinecraft().world);
updateDummyVillagerWithData(firstData);
}
catch (IndexOutOfBoundsException e) {
callButton.enabled = false;
}
}
private void updateDummyVillagerWithData(NBTTagCompound nbt) {
dummyHuman.set(VILLAGER_NAME, nbt.getString("name"));
dummyHuman.set(TEXTURE, nbt.getString("texture"));
dummyHuman.set(GIRTH, nbt.getFloat("girth"));
dummyHuman.set(TALLNESS, nbt.getFloat("tallness"));
dummyHuman.set(IS_INFECTED, nbt.getBoolean("infected"));
dummyHuman.set(AGE_STATE, nbt.getInteger("ageState"));
}
}
================================================
FILE: src/main/java/mca/client/gui/component/GuiButtonEx.java
================================================
package mca.client.gui.component;
import lombok.Getter;
import mca.api.types.APIButton;
import mca.core.MCA;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
public class GuiButtonEx extends GuiButton {
@Getter private APIButton apiButton;
public GuiButtonEx(GuiScreen gui, APIButton apiButton) {
super(apiButton.getId(), (gui.width / 2) + apiButton.getX(), (gui.height / 2) + apiButton.getY(), apiButton.getWidth(), apiButton.getHeight(), MCA.getLocalizer().localize(apiButton.getIdentifier()));
this.apiButton = apiButton;
}
}
================================================
FILE: src/main/java/mca/client/model/ModelGrimReaper.java
================================================
package mca.client.model;
import mca.entity.EntityGrimReaper;
import mca.enums.EnumReaperAttackState;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
public class ModelGrimReaper extends ModelBiped {
private ModelRenderer head;
private ModelRenderer rightArm;
private ModelRenderer leftLeg;
private ModelRenderer cowl;
private ModelRenderer chest;
private ModelRenderer leftArm;
private ModelRenderer rightLeg;
private ModelRenderer cowlPreAttack;
private ModelRenderer rightArmPreAttack;
private ModelRenderer leftLegPreAttack;
private ModelRenderer headPreAttack;
private ModelRenderer chestPreAttack;
private ModelRenderer leftArmPreAttack;
private ModelRenderer rightLegPreAttack;
private ModelRenderer scytheHandlePreAttack;
private ModelRenderer scytheHeadPreAttack;
private ModelRenderer cowlPostAttack;
private ModelRenderer rightArmPostAttack;
private ModelRenderer leftLegPostAttack;
private ModelRenderer headPostAttack;
private ModelRenderer chestPostAttack;
private ModelRenderer leftArmPostAttack;
private ModelRenderer rightLegPostAttack;
private ModelRenderer scytheHandlePostAttack;
private ModelRenderer scytheHeadPostAttack;
private ModelRenderer cowlBlock;
private ModelRenderer rightArmBlock;
private ModelRenderer leftLegBlock;
private ModelRenderer headBlock;
private ModelRenderer chestBlock;
private ModelRenderer leftArmBlock;
private ModelRenderer rightLegBlock;
private ModelRenderer scytheHandleBlock;
private ModelRenderer scytheHeadBlock;
private ModelRenderer cowlRest;
private ModelRenderer rightArmRest;
private ModelRenderer leftLegRest;
private ModelRenderer chestRest;
private ModelRenderer leftArmRest;
private ModelRenderer rightLegRest;
private ModelRenderer scytheHandleRest;
private ModelRenderer scytheHeadRest;
private ModelRenderer headRest;
public ModelGrimReaper() {
this.textureWidth = 64;
this.textureHeight = 64;
this.leftLeg = new ModelRenderer(this, 0, 16);
this.leftLeg.mirror = true;
this.leftLeg.setRotationPoint(1.9F, 12.0F, 0.0F);
this.leftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.leftArm = new ModelRenderer(this, 40, 16);
this.leftArm.mirror = true;
this.leftArm.setRotationPoint(5.0F, 2.0F, 0.0F);
this.leftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.rightLeg = new ModelRenderer(this, 0, 16);
this.rightLeg.setRotationPoint(-1.9F, 12.0F, 0.0F);
this.rightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.chest = new ModelRenderer(this, 16, 16);
this.chest.setRotationPoint(0.0F, 0.0F, 0.0F);
this.chest.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);
this.cowl = new ModelRenderer(this, 0, 0);
this.cowl.setRotationPoint(0.0F, 0.0F, 0.0F);
this.cowl.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);
this.head = new ModelRenderer(this, 32, 0);
this.head.setRotationPoint(0.0F, 0.0F, 0.0F);
this.head.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);
this.rightArm = new ModelRenderer(this, 40, 16);
this.rightArm.setRotationPoint(-5.0F, 2.0F, 0.0F);
this.rightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.leftArmPreAttack = new ModelRenderer(this, 40, 16);
this.leftArmPreAttack.mirror = true;
this.leftArmPreAttack.setRotationPoint(5.0F, 2.0F, 0.0F);
this.leftArmPreAttack.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftArmPreAttack, -2.276432943376204F, -1.9577358219620393F, 0.136659280431156F);
this.cowlPreAttack = new ModelRenderer(this, 32, 0);
this.cowlPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.cowlPreAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);
this.setRotateAngle(cowlPreAttack, -0.27314402793711257F, 0.18203784098300857F, 0.0F);
this.rightLegPreAttack = new ModelRenderer(this, 0, 16);
this.rightLegPreAttack.setRotationPoint(-1.9F, 12.0F, 0.0F);
this.rightLegPreAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightLegPreAttack, 0.22759093446006054F, -0.22759093446006054F, 0.0F);
this.leftLegPreAttack = new ModelRenderer(this, 0, 16);
this.leftLegPreAttack.mirror = true;
this.leftLegPreAttack.setRotationPoint(1.9F, 12.0F, 0.0F);
this.leftLegPreAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftLegPreAttack, 0.31869712141416456F, -0.22759093446006054F, 0.0F);
this.chestPreAttack = new ModelRenderer(this, 16, 16);
this.chestPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.chestPreAttack.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);
this.setRotateAngle(chestPreAttack, 0.0F, -0.22759093446006054F, 0.0F);
this.scytheHandlePreAttack = new ModelRenderer(this, 36, 32);
this.scytheHandlePreAttack.setRotationPoint(7.0F, -12.4F, 17.2F);
this.scytheHandlePreAttack.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);
this.setRotateAngle(scytheHandlePreAttack, -1.0471975511965976F, -0.36425021489121656F, 0.0F);
this.rightArmPreAttack = new ModelRenderer(this, 40, 16);
this.rightArmPreAttack.setRotationPoint(-5.0F, 2.0F, 0.0F);
this.rightArmPreAttack.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightArmPreAttack, -0.6373942428283291F, 2.1399481958702475F, 0.0F);
this.headPreAttack = new ModelRenderer(this, 0, 0);
this.headPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.headPreAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);
this.setRotateAngle(headPreAttack, -0.27314402793711257F, 0.18203784098300857F, 0.0F);
this.scytheHeadPreAttack = new ModelRenderer(this, 0, 32);
this.scytheHeadPreAttack.setRotationPoint(7.8F, -11.8F, 17.5F);
this.scytheHeadPreAttack.addBox(0.0F, 0.0F, 0.0F, 16, 16, 0, 0.0F);
this.setRotateAngle(scytheHeadPreAttack, -1.0471975511965976F, -0.36425021489121656F, 0.0F);
this.chestPostAttack = new ModelRenderer(this, 16, 16);
this.chestPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.chestPostAttack.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);
this.setRotateAngle(chestPostAttack, 0.5918411493512771F, 0.5918411493512771F, 0.0F);
this.leftArmPostAttack = new ModelRenderer(this, 40, 16);
this.leftArmPostAttack.mirror = true;
this.leftArmPostAttack.setRotationPoint(5.0F, 2.0F, 0.0F);
this.leftArmPostAttack.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftArmPostAttack, -0.7740535232594852F, 1.0927506446736497F, 0.136659280431156F);
this.cowlPostAttack = new ModelRenderer(this, 32, 0);
this.cowlPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.cowlPostAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);
this.setRotateAngle(cowlPostAttack, 0.7740535232594852F, 0.7285004297824331F, 0.0F);
this.scytheHeadPostAttack = new ModelRenderer(this, 0, 32);
this.scytheHeadPostAttack.setRotationPoint(0.8F, 8.9F, -24.0F);
this.scytheHeadPostAttack.addBox(0.0F, 0.0F, 0.0F, 16, 16, 0, 0.0F);
this.setRotateAngle(scytheHeadPostAttack, -1.6235052702051254F, 2.9543188248508017F, -0.27314402793711257F);
this.scytheHandlePostAttack = new ModelRenderer(this, 37, 32);
this.scytheHandlePostAttack.setRotationPoint(-4.3F, 9.0F, 6.7F);
this.scytheHandlePostAttack.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);
this.setRotateAngle(scytheHandlePostAttack, 1.5025539530419183F, 2.9595548126067843F, -0.36425021489121656F);
this.rightLegPostAttack = new ModelRenderer(this, 0, 16);
this.rightLegPostAttack.setRotationPoint(2.0F, 10.0F, 6.6F);
this.rightLegPostAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightLegPostAttack, 0.5462880558742251F, 0.5918411493512771F, -0.091106186954104F);
this.headPostAttack = new ModelRenderer(this, 0, 0);
this.headPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);
this.headPostAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);
this.setRotateAngle(headPostAttack, 0.7740535232594852F, 0.7285004297824331F, 0.0F);
this.leftLegPostAttack = new ModelRenderer(this, 0, 16);
this.leftLegPostAttack.mirror = true;
this.leftLegPostAttack.setRotationPoint(5.4F, 9.8F, 4.6F);
this.leftLegPostAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftLegPostAttack, 0.5009094953223726F, 0.6829473363053812F, -0.045553093477052F);
this.rightArmPostAttack = new ModelRenderer(this, 40, 16);
this.rightArmPostAttack.setRotationPoint(-5.0F, 1.7F, 3.3F);
this.rightArmPostAttack.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightArmPostAttack, -1.593485607070823F, 2.5497515042385164F, 0.0F);
this.cowlBlock = new ModelRenderer(this, 32, 0);
this.cowlBlock.setRotationPoint(0.0F, 0.0F, 0.0F);
this.cowlBlock.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);
this.setRotateAngle(cowlBlock, 0.091106186954104F, 0.0F, 0.0F);
this.leftLegBlock = new ModelRenderer(this, 0, 16);
this.leftLegBlock.mirror = true;
this.leftLegBlock.setRotationPoint(1.9F, 12.0F, 0.0F);
this.leftLegBlock.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftLegBlock, -0.136659280431156F, 0.045553093477052F, 0.0F);
this.headBlock = new ModelRenderer(this, 0, 0);
this.headBlock.setRotationPoint(0.0F, 0.0F, 0.0F);
this.headBlock.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);
this.setRotateAngle(headBlock, 0.136659280431156F, 0.0F, 0.0F);
this.rightArmBlock = new ModelRenderer(this, 40, 16);
this.rightArmBlock.setRotationPoint(-5.0F, 2.0F, 0.0F);
this.rightArmBlock.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightArmBlock, -1.2292353921796064F, 0.0F, 1.8668041679331349F);
this.scytheHandleBlock = new ModelRenderer(this, 36, 32);
this.scytheHandleBlock.setRotationPoint(-18.5F, -3.7F, -10.1F);
this.scytheHandleBlock.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);
this.setRotateAngle(scytheHandleBlock, 1.2292353921796064F, 1.5481070465189704F, 0.0F);
this.rightLegBlock = new ModelRenderer(this, 0, 16);
this.rightLegBlock.setRotationPoint(-1.9F, 12.0F, 0.0F);
this.rightLegBlock.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightLegBlock, -0.136659280431156F, 0.091106186954104F, 0.0F);
this.chestBlock = new ModelRenderer(this, 16, 16);
this.chestBlock.setRotationPoint(0.0F, 0.0F, 1.0F);
this.chestBlock.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);
this.setRotateAngle(chestBlock, -0.091106186954104F, 0.091106186954104F, 0.0F);
this.leftArmBlock = new ModelRenderer(this, 40, 16);
this.leftArmBlock.mirror = true;
this.leftArmBlock.setRotationPoint(5.0F, 2.0F, 0.0F);
this.leftArmBlock.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftArmBlock, -1.5025539530419183F, 0.40980330836826856F, 0.136659280431156F);
this.scytheHeadBlock = new ModelRenderer(this, 0, 32);
this.scytheHeadBlock.setRotationPoint(-18.5F, -3.7F, -10.1F);
this.scytheHeadBlock.addBox(0.0F, 0.0F, 0.5F, 16, 16, 0, 0.0F);
this.setRotateAngle(scytheHeadBlock, 1.2292353921796064F, 1.5481070465189704F, 0.0F);
this.rightArmRest = new ModelRenderer(this, 40, 16);
this.rightArmRest.setRotationPoint(-5.0F, 2.0F, 0.0F);
this.rightArmRest.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightArmRest, 0.091106186954104F, -0.045553093477052F, 0.4553564018453205F);
this.rightLegRest = new ModelRenderer(this, 0, 16);
this.rightLegRest.setRotationPoint(-1.9F, 12.0F, 0.0F);
this.rightLegRest.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(rightLegRest, 0.045553093477052F, 0.091106186954104F, 0.0F);
this.leftArmRest = new ModelRenderer(this, 40, 16);
this.leftArmRest.mirror = true;
this.leftArmRest.setRotationPoint(5.0F, 2.0F, 0.0F);
this.leftArmRest.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftArmRest, -1.6845917940249266F, -1.5481070465189704F, 0.9560913642424937F);
this.chestRest = new ModelRenderer(this, 16, 16);
this.chestRest.setRotationPoint(0.0F, 0.0F, 0.1F);
this.chestRest.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);
this.setRotateAngle(chestRest, 0.0F, 0.091106186954104F, 0.0F);
this.leftLegRest = new ModelRenderer(this, 0, 16);
this.leftLegRest.mirror = true;
this.leftLegRest.setRotationPoint(1.9F, 12.0F, 0.0F);
this.leftLegRest.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);
this.setRotateAngle(leftLegRest, 0.045553093477052F, 0.045553093477052F, 0.0F);
this.headRest = new ModelRenderer(this, 0, 0);
this.headRest.setRotationPoint(0.0F, 0.0F, 0.0F);
this.headRest.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);
this.setRotateAngle(headRest, 1.0927506446736497F, 0.0F, 0.03159045946109736F);
this.scytheHeadRest = new ModelRenderer(this, 0, 32);
this.scytheHeadRest.setRotationPoint(-0.1F, -7.3F, -11.7F);
this.scytheHeadRest.addBox(0.0F, 0.0F, 0.5F, 16, 16, 0, 0.0F);
this.setRotateAngle(scytheHeadRest, 0.091106186954104F, 1.2747884856566583F, 0.091106186954104F);
this.cowlRest = new ModelRenderer(this, 32, 0);
this.cowlRest.setRotationPoint(0.0F, 0.0F, 0.0F);
this.cowlRest.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);
this.setRotateAngle(cowlRest, 1.0471975511965976F, 0.0F, 0.0F);
this.scytheHandleRest = new ModelRenderer(this, 36, 32);
this.scytheHandleRest.setRotationPoint(-1.0F, 7.0F, -10.1F);
this.scytheHandleRest.addBox(0.5F, -15.5F, 0.5F, 1, 31, 1, 0.0F);
this.setRotateAngle(scytheHandleRest, 0.091106186954104F, 1.2747884856566583F, 0.091106186954104F);
}
@Override
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
EntityGrimReaper reaper = (EntityGrimReaper) entity;
if (reaper.getAttackState() == EnumReaperAttackState.PRE) {
this.leftLegPreAttack.render(f5);
this.leftArmPreAttack.render(f5);
this.rightLegPreAttack.render(f5);
this.chestPreAttack.render(f5);
this.cowlPreAttack.render(f5);
this.headPreAttack.render(f5);
this.rightArmPreAttack.render(f5);
this.scytheHandlePreAttack.render(f5);
this.scytheHeadPreAttack.render(f5);
} else if (reaper.getAttackState() == EnumReaperAttackState.POST) {
this.leftLegPostAttack.render(f5);
this.leftArmPostAttack.render(f5);
this.rightLegPostAttack.render(f5);
this.chestPostAttack.render(f5);
this.cowlPostAttack.render(f5);
this.headPostAttack.render(f5);
this.rightArmPostAttack.render(f5);
this.scytheHandlePostAttack.render(f5);
this.scytheHeadPostAttack.render(f5);
} else if (reaper.getAttackState() == EnumReaperAttackState.BLOCK) {
this.cowlBlock.render(f5);
this.leftLegBlock.render(f5);
this.headBlock.render(f5);
this.rightArmBlock.render(f5);
this.scytheHandleBlock.render(f5);
this.rightLegBlock.render(f5);
this.chestBlock.render(f5);
this.leftArmBlock.render(f5);
this.scytheHeadBlock.render(f5);
} else if (reaper.getAttackState() == EnumReaperAttackState.REST) {
GL11.glPushMatrix();
{
double amt = Math.cos(reaper.getFloatingTicks()) / 4;
GL11.glTranslated(0.0D, amt, 0.0D);
this.rightArmRest.render(f5);
this.rightLegRest.render(f5);
this.leftArmRest.render(f5);
this.chestRest.render(f5);
this.leftLegRest.render(f5);
this.cowlRest.render(f5);
GL11.glPushMatrix();
{
double amt2 = Math.cos(reaper.getFloatingTicks()) / 8;
GL11.glTranslated(0.0D, amt2, 0.0D);
this.scytheHeadRest.render(f5);
this.scytheHandleRest.render(f5);
}
GL11.glPopMatrix();
}
GL11.glPopMatrix();
} else {
rightLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);
leftLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);
rightLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);
leftLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);
rightLeg.rotateAngleY = 0.0F;
leftLeg.rotateAngleY = 0.0F;
this.leftLeg.render(f5);
this.leftArm.render(f5);
this.rightLeg.render(f5);
this.chest.render(f5);
this.cowl.render(f5);
this.head.render(f5);
this.rightArm.render(f5);
}
}
public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) {
modelRenderer.rotateAngleX = x;
modelRenderer.rotateAngleY = y;
modelRenderer.rotateAngleZ = z;
}
}
================================================
FILE: src/main/java/mca/client/model/ModelVillagerMCA.java
================================================
package mca.client.model;
import mca.enums.EnumGender;
import org.lwjgl.opengl.GL11;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
public class ModelVillagerMCA extends ModelBiped {
private ModelRenderer breasts;
public ModelVillagerMCA() {
super(0.0F, 0.0F, 64, 64);
breasts = new ModelRenderer(this, 18, 21);
breasts.addBox(-3F, 0F, -1F, 6, 3, 3);
breasts.setRotationPoint(0F, 3.5F, -3F);
breasts.setTextureSize(64, 64);
breasts.mirror = true;
}
@Override
public void render(Entity entity, float swing, float swingAmount, float age, float headYaw, float headPitch, float scale) {
super.render(entity, swing, swingAmount, age, headYaw, headPitch, scale);
EntityVillagerMCA villager = (EntityVillagerMCA)entity;
if (EnumGender.byId(villager.get(EntityVillagerMCA.GENDER)) == EnumGender.FEMALE && !villager.isChild() && villager.getItemStackFromSlot(EntityEquipmentSlot.CHEST) == ItemStack.EMPTY) {
GL11.glPushMatrix();
GL11.glTranslated(0.005D, -0.05D, -0.28D);
GL11.glScaled(1.15D, 1.0D, 1.0D);
GL11.glRotatef(60.0F, 1.0F, 0.0F, 0.0F);
breasts.render(scale);
GL11.glPopMatrix();
}
}
}
================================================
FILE: src/main/java/mca/client/network/ClientMessageQueue.java
================================================
package mca.client.network;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ClientMessageQueue {
private static ConcurrentLinkedQueue scheduledMessages = new ConcurrentLinkedQueue<>();
public static void processScheduledMessages() {
IMessage next = scheduledMessages.poll();
if (next != null) handle(next);
}
public static void add(IMessage msg) {
scheduledMessages.add(msg);
}
private static void handle(IMessage msg) {
if (msg instanceof NetMCA.CareerResponse) handleCareerId((NetMCA.CareerResponse) msg);
else if (msg instanceof NetMCA.InventoryResponse) handleInventory((NetMCA.InventoryResponse) msg);
else MCA.getLog().error("Unexpected message in queue:" + msg.getClass().getName());
}
private static void handleCareerId(NetMCA.CareerResponse msg) {
EntityPlayer player = Minecraft.getMinecraft().player;
try {
Optional villager = getVillagerByUUID(player.getEntityWorld(), msg.getEntityUUID());
if (villager.isPresent()) {
ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, villager.get(), msg.getCareerId(), EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);
}
} catch (ClassCastException e) {
MCA.getLog().error("Failed to cast entity to villager on career ID update.");
} catch (Exception e) {
MCA.getLog().error("Failed to set career ID on villager!", e);
}
}
private static void handleInventory(NetMCA.InventoryResponse msg) {
EntityPlayer player = Minecraft.getMinecraft().player;
if (player != null) {
Optional villager = getVillagerByUUID(player.world, msg.getEntityUUID());
villager.ifPresent(entityVillagerMCA -> entityVillagerMCA.inventory.readInventoryFromNBT(msg.getInventoryNBT().getTagList("inventory", 10)));
}
}
private static Optional getVillagerByUUID(World world, UUID uuid) {
try {
synchronized (world.loadedEntityList) {
return world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(uuid)).map(EntityVillagerMCA.class::cast).findFirst();
}
} catch (ClassCastException ignored) {
MCA.getLog().error("Failed to cast entity with UUID " + uuid.toString() + " to a villager!");
}
return Optional.empty();
}
}
================================================
FILE: src/main/java/mca/client/render/RenderGrimReaper.java
================================================
package mca.client.render;
import mca.client.model.ModelGrimReaper;
import mca.entity.EntityGrimReaper;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderGrimReaper extends RenderBiped {
private static final ResourceLocation TEXTURE = new ResourceLocation("mca:textures/entity/grimreaper.png");
public RenderGrimReaper(RenderManager manager) {
super(manager, new ModelGrimReaper(), 0.5F);
}
@Override
public void doRender(T entity, double posX, double posY, double posZ, float angle, float offsetY) {
super.doRender(entity, posX, posY, posZ, angle, offsetY);
}
@Override
protected void preRenderCallback(T entity, float partialTickTime) {
super.preRenderCallback(entity, partialTickTime);
double scale = 1.3D;
GL11.glScaled(scale, scale, scale);
}
@Override
protected ResourceLocation getEntityTexture(T entity) {
return TEXTURE;
}
}
================================================
FILE: src/main/java/mca/client/render/RenderReaperFactory.java
================================================
package mca.client.render;
import mca.entity.EntityGrimReaper;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraftforge.fml.client.registry.IRenderFactory;
public class RenderReaperFactory implements IRenderFactory {
public static final RenderReaperFactory INSTANCE = new RenderReaperFactory();
@Override
public Render super EntityGrimReaper> createRenderFor(RenderManager manager) {
return new RenderGrimReaper(manager);
}
}
================================================
FILE: src/main/java/mca/client/render/RenderVillagerFactory.java
================================================
package mca.client.render;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraftforge.fml.client.registry.IRenderFactory;
public class RenderVillagerFactory implements IRenderFactory {
public static final RenderVillagerFactory INSTANCE = new RenderVillagerFactory();
@Override
public Render super EntityVillagerMCA> createRenderFor(RenderManager manager) {
return new RenderVillagerMCA(manager);
}
}
================================================
FILE: src/main/java/mca/client/render/RenderVillagerMCA.java
================================================
package mca.client.render;
import mca.client.model.ModelVillagerMCA;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumAgeState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.layers.LayerBipedArmor;
import net.minecraft.client.renderer.entity.layers.LayerHeldItem;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderVillagerMCA extends RenderBiped {
private static final ResourceLocation gui = new ResourceLocation("mca:textures/gui.png");
private static final float LABEL_SCALE = 0.027F;
public RenderVillagerMCA(RenderManager manager) {
super(manager, new ModelVillagerMCA(), 0.5F);
this.addLayer(new LayerBipedArmor(this));
this.addLayer(new LayerHeldItem(this));
}
@Override
protected void preRenderCallback(EntityVillagerMCA villager, float partialTickTime) {
if (villager.isChild()) {
float scaleForAge = EnumAgeState.byId(villager.get(EntityVillagerMCA.AGE_STATE)).getScaleForAge();
GlStateManager.scale(scaleForAge, scaleForAge, scaleForAge);
}
if (villager.isRiding()) {
GlStateManager.translate(0, 0.5, 0);
}
}
@Override
public void renderName(EntityVillagerMCA entity, double x, double y, double z) {
super.renderName(entity, x, y ,z);
if (canRenderName(entity)) {
if (entity.getHealth() < entity.getMaxHealth()) {
renderHealth(entity, x, y, z, (int) entity.getHealth(), (int) entity.getMaxHealth());
}
if (entity.getCurrentActivity() != null) {
double d0 = entity.getDistanceSq(this.renderManager.renderViewEntity);
float f = entity.isSneaking() ? NAME_TAG_RANGE_SNEAK : NAME_TAG_RANGE;
if (d0 < (double) (f * f)) {
this.renderEntityName(entity, x, y - 0.25F, z, "(" + entity.getCurrentActivity() + ")", d0);
}
}
}
}
private void renderHealth(EntityVillagerMCA villager, double posX, double posY, double posZ, int currentHealth, int maxHealth) {
final int redHeartU = 80;
final int darkHeartU = 96;
int heartsDrawn = 0;
float maxHealthF = Math.round((float)maxHealth / 2.0F);
float currentHealthF = Math.round((float)currentHealth / 2.0F);
int heartsMax = Math.round((maxHealthF / maxHealthF) * 10.0F);
int heartsToDraw = Math.round((currentHealthF / maxHealthF) * 10.0F);
for (int i = 0; i < heartsMax; i++) {
int heartU = i < heartsToDraw ? redHeartU : darkHeartU;
heartsDrawn++;
GL11.glPushMatrix();{
GL11.glTranslatef((float) posX + 0.0F, (float) posY + villager.height + 1.0F, (float) posZ);
GL11.glRotatef(-renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
GL11.glScalef(-LABEL_SCALE, -LABEL_SCALE, LABEL_SCALE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glTranslatef(-2.0F, 2.0F, -2.0F);
drawTexturedRectangle(gui, (int)posX + (heartsDrawn * 8) - 45, (int)posY - 4, heartU, 0, 16, 16);
}
GL11.glPopMatrix();
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_LIGHTING);
}
}
@Override
protected ResourceLocation getEntityTexture(EntityVillagerMCA villager) {
return villager.getTextureResourceLocation();
}
@Override
protected boolean canRenderName(EntityVillagerMCA entity) {
float distance = Minecraft.getMinecraft().player.getDistance(entity);
return distance < 5F;
}
public static void drawTexturedRectangle(ResourceLocation texture, int x, int y, int u, int v, int width, int height)
{
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
float f = 0.00390625F;
float f1 = 0.00390625F;
final Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(7, DefaultVertexFormats.POSITION_TEX);
buffer.pos(x + 0, y + height, 0.0D).tex((u + 0) * f, ((v + height) * f1)).endVertex();
buffer.pos(x + width, y + height, 0.0D).tex((u + width) * f, ((v + height) * f1)).endVertex();
buffer.pos(x + width, y + 0, 0.0D).tex((u + width) * f, ((v + 0) * f1)).endVertex();
buffer.pos(x + 0, y + 0, 0.0D).tex((u + 0) * f, ((v + 0) * f1)).endVertex();
tessellator.draw();
}
@Override
protected void renderLivingAt(EntityVillagerMCA entityLiving, double x, double y, double z) {
if (entityLiving.isEntityAlive() && entityLiving.isSleeping()) {
super.renderLivingAt(entityLiving, x + (double)entityLiving.renderOffsetX, y + (double)entityLiving.renderOffsetY, z + (double)entityLiving.renderOffsetZ);
} else {
super.renderLivingAt(entityLiving, x, y, z);
}
}
@Override
protected void applyRotations(EntityVillagerMCA entityLiving, float p_77043_2_, float rotationYaw, float partialTicks) {
if (entityLiving.isSleeping()) {
GlStateManager.rotate(entityLiving.getBedOrientationInDegrees(), 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(this.getDeathMaxRotation(entityLiving), 0.0F, 0.0F, 1.0F);
GlStateManager.rotate(270.0F, 0.0F, 1.0F, 0.0F);
rotationYaw = 180.0f;
}
super.applyRotations(entityLiving, p_77043_2_, rotationYaw, partialTicks);
}
}
================================================
FILE: src/main/java/mca/command/CommandAdminMCA.java
================================================
package mca.command;
import com.google.common.base.Optional;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.minecraft.ItemsMCA;
import mca.entity.EntityGrimReaper;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.PlayerSaveData;
import mca.items.ItemBaby;
import mca.util.Util;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
import java.util.Arrays;
import java.util.UUID;
public class CommandAdminMCA extends CommandBase {
@Override
public String getName() {
return "mca-admin";
}
@Override
public String getUsage(ICommandSender commandSender) {
return "/mca-admin ";
}
@Override
public void execute(MinecraftServer server, ICommandSender commandSender, String[] input) throws CommandException {
try {
if (!MCA.getConfig().enableAdminCommands) {
sendMessage(commandSender, "MCA admin commands have been disabled by the server administrator.");
return;
}
if (input.length == 0) {
throw new WrongUsageException("");
}
final EntityPlayer player = (EntityPlayer) commandSender;
String subcommand = input[0].toLowerCase();
String[] arguments = Arrays.copyOfRange(input, 1, input.length);
MCA.getLog().info(player.getName() + " entered debug command " + Arrays.toString(input));
switch (subcommand) {
case "help": displayHelp(commandSender); break;
case "ffh": forceFullHearts(player); break;
case "fbg": forceBabyGrow(player); break;
case "fcg": forceChildGrow(player); break;
case "clv": clearLoadedVillagers(player);break;
case "inh": incrementHearts(player); break;
case "deh": decrementHearts(player); break;
case "sgr": spawnGrimReaper(player); break;
case "kgr": killGrimReaper(player); break;
case "dpd": dumpPlayerData(player); break;
case "rvd": resetVillagerData(player, arguments); break;
case "rpd": resetPlayerData(player, arguments); break;
case "cve": clearVillagerEditors(player); break;
default: throw new WrongUsageException("");
}
} catch (ClassCastException e) {
throw new CommandException("MCA commands cannot be used through rcon.");
} catch (WrongUsageException e) {
throw new CommandException("Your command was invalid or improperly formatted. Usage: " + getUsage(commandSender));
}
}
private void forceFullHearts(EntityPlayer player) {
for (Entity entity : player.world.loadedEntityList) {
if (entity instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA) entity;
villager.getPlayerHistoryFor(player.getUniqueID()).setHearts(100);
}
}
sendMessage(player, Constants.Color.GREEN + "Forced full hearts on all villagers.");
}
private void forceBabyGrow(EntityPlayer player) {
for (ItemStack stack : player.inventory.mainInventory) {
if (stack.getItem() instanceof ItemBaby) {
stack.getTagCompound().setInteger("age", MCA.getConfig().babyGrowUpTime);
}
}
sendMessage(player, Constants.Color.GREEN + "Forced any held babies to grow up age.");
}
private void forceChildGrow(EntityPlayer player) {
player.world.loadedEntityList.stream()
.filter(e -> e instanceof EntityVillagerMCA && ((EntityVillagerMCA)e).isChild())
.forEach(e -> ((EntityVillagerMCA) e).addGrowth(999999));
sendMessage(player, Constants.Color.GREEN + "Forced any children to grow to adults.");
}
private void clearLoadedVillagers(EntityPlayer player) {
int n = 0;
for (Entity entity : player.world.loadedEntityList) {
if (entity instanceof EntityVillagerMCA) {
entity.setDead();
++n;
}
}
sendMessage(player, Constants.Color.GREEN + "Cleared " + n + " villagers from the world.");
}
private void incrementHearts(EntityPlayer player) {
for (Entity entity : player.world.loadedEntityList) {
if (entity instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA) entity;
villager.getPlayerHistoryFor(player.getUniqueID()).changeHearts(10);
}
}
sendMessage(player, Constants.Color.GREEN + "Increased hearts for all villagers by 10.");
}
private void decrementHearts(EntityPlayer player) {
for (Entity entity : player.world.loadedEntityList) {
if (entity instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA) entity;
villager.getPlayerHistoryFor(player.getUniqueID()).changeHearts(-10);
}
}
sendMessage(player, Constants.Color.GREEN + "Decreased hearts for all villagers by 10.");
}
private void spawnGrimReaper(EntityPlayer player) {
EntityGrimReaper reaper = new EntityGrimReaper(player.world);
reaper.setPosition(player.posX, player.posY, player.posZ);
player.world.spawnEntity(reaper);
}
private void killGrimReaper(EntityPlayer player) {
player.world.loadedEntityList.stream().filter((e) -> e instanceof EntityGrimReaper).forEach((e) -> e.setDead());
}
private void dumpPlayerData(EntityPlayer player) {
PlayerSaveData.get(player).dump(player);
}
private void resetVillagerData(EntityPlayer sender, String[] arguments) {
Optional target = Util.getEntityByUUID(sender.world, UUID.fromString(arguments[0]), EntityVillagerMCA.class);
if (!target.isPresent()) {
sendMessage(sender, "Target villager was not found.");
} else {
target.get().reset();
sendMessage(sender, target.get().getDisplayName().getUnformattedText() + " has been reset successfully.");
}
}
private void resetPlayerData(EntityPlayer sender, String[] arguments) {
Optional target = com.google.common.base.Optional.fromJavaUtil(sender.world.loadedEntityList.stream()
.filter(e -> e instanceof EntityPlayer && e.getName().equals(arguments[0]))
.findFirst());
if (!target.isPresent()) {
sendMessage(sender, "Player not found on the server.");
} else {
PlayerSaveData.get((EntityPlayer)target.get()).reset();
sendMessage(sender, "Player data for " + target.get().getName() + " has been reset successfully.");
sendMessage(target.get(), "Your player data has been reset by " + sender.getName() + ".");
}
}
private void clearVillagerEditors(EntityPlayer sender) {
ItemStack editorStack = new ItemStack(ItemsMCA.VILLAGER_EDITOR);
sender.world.playerEntities.stream().filter(p -> p.inventory.hasItemStack(editorStack)).forEach(p -> {
int i = 0;
while (i < p.inventory.getSizeInventory() - 1) {
if (p.inventory.getStackInSlot(i).getItem() == ItemsMCA.VILLAGER_EDITOR) {
p.inventory.setInventorySlotContents(i, ItemStack.EMPTY);
}
i++;
}
});
sendMessage(sender, "All villager editors cleared from inventories.");
}
@Override
public int getRequiredPermissionLevel() {
return 4;
}
private void sendMessage(ICommandSender commandSender, String message) {
commandSender.sendMessage(new TextComponentString(Constants.Color.GOLD + "[MCA] " + Constants.Format.RESET + message));
}
private void sendMessage(ICommandSender commandSender, String message, boolean noPrefix) {
if (noPrefix) {
commandSender.sendMessage(new TextComponentString(message));
} else {
sendMessage(commandSender, message);
}
}
private void displayHelp(ICommandSender commandSender) {
sendMessage(commandSender, Constants.Color.DARKRED + "--- " + Constants.Color.GOLD + "OP COMMANDS" + Constants.Color.DARKRED + " ---", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin ffh " + Constants.Color.GOLD + " - Force all hearts on all villagers.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin fbg " + Constants.Color.GOLD + " - Force your baby to grow up.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin fcg " + Constants.Color.GOLD + " - Force nearby children to grow.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin clv " + Constants.Color.GOLD + " - Clear all loaded villagers. " + Constants.Color.RED + "(IRREVERSABLE)", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin inh " + Constants.Color.GOLD + " - Increase hearts by 10.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin deh " + Constants.Color.GOLD + " - Decrease hearts by 10.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin kgr " + Constants.Color.GOLD + " - Kill all Grim Reapers in the world.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin dpd " + Constants.Color.GOLD + " - Dumps player data to chat.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin rvd " + Constants.Color.GOLD + " - Resets the given villager.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin rpd " + Constants.Color.GOLD + " - Resets the given player's MCA data.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin cve" + Constants.Color.GOLD + " - Remove all villager editors from the game.", true);
sendMessage(commandSender, Constants.Color.DARKRED + "--- " + Constants.Color.GOLD + "GLOBAL COMMANDS" + Constants.Color.DARKRED + " ---", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca-admin help " + Constants.Color.GOLD + " - Shows this list of commands.", true);
}
}
================================================
FILE: src/main/java/mca/command/CommandMCA.java
================================================
package mca.command;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.MCAServer;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
import java.util.Arrays;
public class CommandMCA extends CommandBase {
@Override
public String getName() {
return "mca";
}
@Override
public String getUsage(ICommandSender commandSender) {
return "/mca ";
}
@Override
public void execute(MinecraftServer server, ICommandSender commandSender, String[] input) throws CommandException {
try {
if (!MCA.getConfig().allowPlayerMarriage) {
sendMessage(commandSender, "MCA commands have been disabled by the server administrator.");
return;
}
if (input.length == 0) {
throw new WrongUsageException("");
}
final EntityPlayer player = (EntityPlayer) commandSender;
String subcommand = input[0].toLowerCase();
String[] arguments = Arrays.copyOfRange(input, 1, input.length);
MCA.getLog().info(player.getName() + " entered command " + Arrays.toString(input));
switch (subcommand) {
case "help":
displayHelp(commandSender);
break;
case "propose":
EntityPlayer target = player.world.getPlayerEntityByName(arguments[0]);
if (target != null) {
MCAServer.get().sendProposal(player, target);
} else {
player.sendMessage(new TextComponentString("Player not found on the server."));
}
break;
case "accept":
target = player.world.getPlayerEntityByName(arguments[0]);
if (target != null) {
MCAServer.get().acceptProposal(player, target);
} else {
player.sendMessage(new TextComponentString("Player not found on the server."));
}
break;
case "proposals":
MCAServer.get().listProposals(player);
break;
case "procreate":
MCAServer.get().procreate(player);
break;
case "separate":
MCAServer.get().endMarriage(player);
break;
case "reject":
target = player.world.getPlayerEntityByName(arguments[0]);
if (target != null) {
MCAServer.get().rejectProposal(player, target);
} else {
player.sendMessage(new TextComponentString("Player not found on the server."));
}
break;
default:
throw new WrongUsageException("");
}
} catch (ClassCastException e) {
throw new CommandException("MCA commands cannot be used through rcon.");
} catch (WrongUsageException e) {
throw new CommandException("Your command was invalid or improperly formatted. Usage: " + getUsage(commandSender));
}
}
@Override
public int getRequiredPermissionLevel() {
return 0;
}
private void sendMessage(ICommandSender commandSender, String message) {
commandSender.sendMessage(new TextComponentString(Constants.Color.GOLD + "[MCA] " + Constants.Format.RESET + message));
}
private void sendMessage(ICommandSender commandSender, String message, boolean noPrefix) {
if (noPrefix) {
commandSender.sendMessage(new TextComponentString(message));
} else {
sendMessage(commandSender, message);
}
}
private void displayHelp(ICommandSender commandSender) {
sendMessage(commandSender, Constants.Color.DARKRED + "--- " + Constants.Color.GOLD + "PLAYER COMMANDS" + Constants.Color.DARKRED + " ---", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca propose " + Constants.Color.GOLD + " - Proposes marriage to the given player.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca proposals " + Constants.Color.GOLD + " - Shows all active proposals.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca accept " + Constants.Color.GOLD + " - Accepts the player's marriage request.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca reject " + Constants.Color.GOLD + " - Rejects the player's marriage request.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca procreate " + Constants.Color.GOLD + " - Starts procreation.", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca separate " + Constants.Color.GOLD + " - Ends your marriage.", true);
sendMessage(commandSender, Constants.Color.DARKRED + "--- " + Constants.Color.GOLD + "GLOBAL COMMANDS" + Constants.Color.DARKRED + " ---", true);
sendMessage(commandSender, Constants.Color.WHITE + " /mca help " + Constants.Color.GOLD + " - Shows this list of commands.", true);
}
}
================================================
FILE: src/main/java/mca/core/Config.java
================================================
package mca.core;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public final class Config implements Serializable {
private transient final Configuration config;
public boolean overwriteOriginalVillagers;
public boolean enableDiminishingReturns;
public boolean enableInfection;
public int infectionChance;
public boolean allowGrimReaper;
public int guardSpawnRate;
public int chanceToHaveTwins;
public int marriageHeartsRequirement;
public int roseGoldSpawnWeight;
public int babyGrowUpTime;
public int childGrowUpTime;
public int villagerSpawnerCap;
public int villagerSpawnerRateMinutes;
public int villagerMaxHealth;
public boolean allowTrading;
public boolean logVillagerDeaths;
public boolean enableRevivals;
public String villagerChatPrefix;
public boolean allowPlayerMarriage;
public boolean enableAdminCommands;
public boolean allowCrashReporting;
public boolean allowUpdateChecking;
public boolean allowRoseGoldGeneration;
public Config(FMLPreInitializationEvent event) {
config = new Configuration(event.getSuggestedConfigurationFile());
addConfigValues();
}
private void addConfigValues() {
overwriteOriginalVillagers = config.get("General", "Overwrite Original Villagers?", true, "Should original villagers be overwritten by MCA villagers?").getBoolean();
enableDiminishingReturns = config.get("General", "Enable Interaction Fatigue?", true, "Should interactions yield diminishing returns over time?").getBoolean();
enableInfection = config.get("General", "Enable Zombie Infection?", true, "Should zombies be able to infect villagers?").getBoolean();
infectionChance = config.get("General", "Chance of Infection", 5, "Chance that a villager will be infected on hit from a zombie. Default is 5 for 5%.").getInt();
allowGrimReaper = config.get("General", "Allow Grim Reaper?", true, "Should the Grim Reaper boss be enabled?").getBoolean();
guardSpawnRate = config.get("General", "Guard Spawn Rate", 6, "How many villagers that should be in a village before a guard spawns.").getInt();
chanceToHaveTwins = config.get("General", "Chance to Have Twins", 2, "Chance that you will have twins. Default is 2 for 2%.").getInt();
marriageHeartsRequirement = config.get("General", "Marriage Hearts Requirement", 100, "Number of hearts required to get married.").getInt();
roseGoldSpawnWeight = config.get("General", "Rose Gold Spawn Weight", 6, "Spawn weights for Rose Gold").getInt();
babyGrowUpTime = config.get("General", "Baby Grow Up Time (Minutes)", 30, "Minutes it takes for a baby to be ready to grow up.").getInt();
childGrowUpTime = config.get("General", "Child Grow Up Time (Minutes)", 60, "Minutes it takes for a child to grow into an adult.").getInt();
villagerSpawnerCap = config.get("General", "Villager Spawner Cap", 5, "Maximum number of villagers that a spawner will create in the area before it stops.").getInt();
villagerSpawnerRateMinutes = config.get("General", "Villager Spawner Rate", 30, "The spawner will spawn 1 villager per this many minutes.").getInt();
allowTrading = config.get("General", "Enable Trading?", true, "Is trading with villagers enabled?").getBoolean();
logVillagerDeaths = config.get("General", "Log Villager Deaths?", true, "Should villager deaths be logged?").getBoolean();
enableRevivals = config.get("General", "Enable Revivals?", true, "Should reviving dead villagers be enabled?").getBoolean();
villagerChatPrefix = config.get("General", "Villager Chat Prefix", "", "Formatting prefix used for all chat with villagers.").getString();
allowPlayerMarriage = config.get("General", "Allow Player Marriage?", true, "Enables or disables player marriage.").getBoolean();
enableAdminCommands = config.get("General", "Enable Admin Commands?", true, "Enables or disables MCA admin commands for ops.").getBoolean();
allowCrashReporting = config.get("General", "Allow Crash Reporting?", true, "If enabled, sends crash reports to MCA developers.").getBoolean();
allowUpdateChecking = config.get("General", "Allow Update Checking?", true, "If enabled, notifies you when an update to MCA is available.").getBoolean();
allowRoseGoldGeneration = config.get("General", "Allow Rose Gold World Generation", true, "If enabled, generates rose gold in your world. If disabled, generates stone instead.").getBoolean();
villagerMaxHealth = config.get("General", "Villager Max Health", 20, "Each villager's maximum health. 1 point equals 1 heart.").getInt();
config.save();
}
public Configuration getInstance() {
return config;
}
public List getCategories() {
List elements = new ArrayList<>();
for (String s : config.getCategoryNames()) {
if (s.equals("server")) continue;
IConfigElement element = new ConfigElement(config.getCategory(s));
elements.addAll(element.getChildElements());
}
return elements;
}
}
================================================
FILE: src/main/java/mca/core/Constants.java
================================================
package mca.core;
import java.util.UUID;
public class Constants {
public static final int GUI_ID_INTERACT = 1;
public static final int GUI_ID_NAMEBABY = 2;
public static final int GUI_ID_INVENTORY = 3;
public static final int GUI_ID_STAFFOFLIFE = 4;
public static final int GUI_ID_VILLAGEREDITOR = 5;
public static final int GUI_ID_GUIDEBOOK = 6;
public static final int GUI_ID_WHISTLE = 7;
public static final UUID ZERO_UUID = new UUID(0, 0);
private static final String SECTION_SIGN = "\u00a7";
public static final int GUI_SCREEN_BUTTON_LIST_FIELD_INDEX = 7;
/**
* All possible font colors
*/
public final class Color {
public static final String BLACK = SECTION_SIGN + "0";
public static final String DARKBLUE = SECTION_SIGN + "1";
public static final String DARKGREEN = SECTION_SIGN + "2";
public static final String DARKAQUA = SECTION_SIGN + "3";
public static final String DARKRED = SECTION_SIGN + "4";
public static final String PURPLE = SECTION_SIGN + "5";
public static final String GOLD = SECTION_SIGN + "6";
public static final String GRAY = SECTION_SIGN + "7";
public static final String DARKGRAY = SECTION_SIGN + "8";
public static final String BLUE = SECTION_SIGN + "9";
public static final String GREEN = SECTION_SIGN + "A";
public static final String AQUA = SECTION_SIGN + "B";
public static final String RED = SECTION_SIGN + "C";
public static final String LIGHTPURPLE = SECTION_SIGN + "D";
public static final String YELLOW = SECTION_SIGN + "E";
public static final String WHITE = SECTION_SIGN + "F";
}
/**
* All possible font formats.
*/
public final class Format {
public static final String OBFUSCATED = SECTION_SIGN + "k";
public static final String BOLD = SECTION_SIGN + "l";
public static final String STRIKE = SECTION_SIGN + "m";
public static final String UNDERLINE = SECTION_SIGN + "n";
public static final String ITALIC = SECTION_SIGN + "o";
public static final String RESET = SECTION_SIGN + "r";
}
}
================================================
FILE: src/main/java/mca/core/Localizer.java
================================================
package mca.core;
import com.google.common.base.Charsets;
import net.minecraft.util.StringUtils;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
public class Localizer {
private Map localizerMap = new HashMap<>();
private static final ArrayList EMPTY_LIST = new ArrayList<>();
public Localizer() {
InputStream inStream = StringUtils.class.getResourceAsStream("/assets/mca/lang/en_us.lang");
try {
List lines = IOUtils.readLines(inStream, Charsets.UTF_8);
for (String line : lines) {
if (line.startsWith("#") || line.isEmpty()) {
continue;
}
String[] split = line.split("\\=");
String key = split[0];
String value = split[1];
localizerMap.put(key, value);
}
} catch (IOException e) {
MCA.getLog().error("Error initializing localizer: " + e);
}
}
public String localize(String key, String... vars) {
ArrayList list = new ArrayList<>();
Collections.addAll(list, vars);
return localize(key, vars != null ? list : EMPTY_LIST);
}
public String localize(String key, ArrayList vars) {
String result = localizerMap.getOrDefault(key, key);
if (result.equals(key)) {
List responses = localizerMap.entrySet().stream().filter(entry -> entry.getKey().contains(key)).map(Map.Entry::getValue).collect(Collectors.toList());
if (responses.size() > 0) result = responses.get(new Random().nextInt(responses.size()));
}
return parseVars(result, vars).replaceAll("\\\\", "");
}
private String parseVars(String str, ArrayList vars) {
int index = 1;
str = str.replaceAll("%Supporter%", MCA.getInstance().getRandomSupporter());
String varString = "%v" + index + "%";
while (str.contains("%v") && index < 10) { // signature of a var being present
try {
str = str.replaceAll(varString, vars.get(index - 1));
} catch (IndexOutOfBoundsException e) {
str = str.replaceAll(varString, "");
MCA.getLog().warn("Failed to replace variable in localized string: " + str);
} finally {
index++;
varString = "%v" + index + "%";
}
}
return str;
}
}
================================================
FILE: src/main/java/mca/core/MCA.java
================================================
package mca.core;
import com.google.gson.Gson;
import mca.api.API;
import mca.command.CommandAdminMCA;
import mca.command.CommandMCA;
import mca.core.forge.EventHooks;
import mca.core.forge.GuiHandler;
import mca.core.forge.NetMCA;
import mca.core.forge.ServerProxy;
import mca.core.minecraft.ItemsMCA;
import mca.core.minecraft.ProfessionsMCA;
import mca.core.minecraft.RoseGoldOreGenerator;
import mca.entity.EntityGrimReaper;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumGender;
import mca.util.Util;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Mod(modid = MCA.MODID, name = MCA.NAME, version = MCA.VERSION, guiFactory = "mca.client.MCAGuiFactory")
public class MCA {
public static final String MODID = "mca";
public static final String NAME = "Minecraft Comes Alive";
public static final String VERSION = "6.0.1";
@SidedProxy(clientSide = "mca.core.forge.ClientProxy", serverSide = "mca.core.forge.ServerProxy")
public static ServerProxy proxy;
public static CreativeTabs creativeTab;
@Mod.Instance
private static MCA instance;
private static Logger logger;
private static Localizer localizer;
private static Config config;
private static long startupTimestamp;
public static String latestVersion = "";
public static boolean updateAvailable = false;
public String[] supporters = new String[0];
public static Logger getLog() {
return logger;
}
public static MCA getInstance() {
return instance;
}
public static Localizer getLocalizer() {
return localizer;
}
public static Config getConfig() {
return config;
}
public static long getStartupTimestamp() {
return startupTimestamp;
}
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
startupTimestamp = new Date().getTime();
instance = this;
logger = event.getModLog();
proxy.registerEntityRenderers();
localizer = new Localizer();
config = new Config(event);
creativeTab = new CreativeTabs("MCA") {
@Override
public ItemStack getTabIconItem() {
return new ItemStack(ItemsMCA.ENGAGEMENT_RING);
}
};
MinecraftForge.EVENT_BUS.register(new EventHooks());
NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());
NetMCA.registerMessages();
if (MCA.getConfig().allowUpdateChecking) {
latestVersion = Util.httpGet("https://minecraftcomesalive.com/api/latest");
if (!latestVersion.equals(VERSION) && !latestVersion.equals("")) {
updateAvailable = true;
MCA.getLog().warn("An update for Minecraft Comes Alive is available: v" + latestVersion);
}
}
supporters = Util.httpGet("https://minecraftcomesalive.com/api/supporters").split(",");
MCA.getLog().info("Loaded " + supporters.length + " supporters.");
}
@EventHandler
public void init(FMLInitializationEvent event) {
GameRegistry.registerWorldGenerator(new RoseGoldOreGenerator(), MCA.getConfig().roseGoldSpawnWeight);
EntityRegistry.registerModEntity(new ResourceLocation(MODID, "EntityVillagerMCA"), EntityVillagerMCA.class, EntityVillagerMCA.class.getSimpleName(), 1120, this, 50, 2, true);
EntityRegistry.registerModEntity(new ResourceLocation(MODID, "GrimReaperMCA"), EntityGrimReaper.class, EntityGrimReaper.class.getSimpleName(), 1121, this, 50, 2, true);
ProfessionsMCA.registerCareers();
proxy.registerModelMeshers();
ItemsMCA.assignCreativeTabs();
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) {
API.init();
}
@EventHandler
public void serverStarting(FMLServerStartingEvent event) {
event.registerServerCommand(new CommandMCA());
event.registerServerCommand(new CommandAdminMCA());
}
@EventHandler
public void serverStopping(FMLServerStoppingEvent event) {
checkForCrashReports();
}
public String getRandomSupporter() {
if (supporters.length > 0) {
return supporters[new Random().nextInt(supporters.length)];
} else {
return API.getRandomName(EnumGender.getRandom());
}
}
public void checkForCrashReports() {
if (MCA.getConfig().allowCrashReporting) {
File crashReportsFolder = new File(System.getProperty("user.dir") + "/crash-reports/");
File[] crashReportFiles = crashReportsFolder.listFiles(File::isFile);
try {
if (crashReportFiles != null) {
Optional newestFile = Arrays.stream(crashReportFiles).max(Comparator.comparingLong(File::lastModified));
if (newestFile.isPresent() && newestFile.get().lastModified() > startupTimestamp) {
// Raw Java for sending the POST request as the HttpClient from Apache libs is not present on servers.
MCA.getLog().warn("Crash detected! Attempting to upload report...");
Map payload = new HashMap<>();
payload.put("minecraft_version", FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion());
payload.put("operating_system", System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version"));
payload.put("java_version", System.getProperty("java.version") + ", " + System.getProperty("java.vendor"));
payload.put("mod_version", MCA.VERSION);
payload.put("body", FileUtils.readFileToString(newestFile.get(), "UTF-8"));
byte[] out = new Gson().toJson(payload).getBytes(StandardCharsets.UTF_8);
URL url = new URL("http://minecraftcomesalive.com/api/crash-reports");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setFixedLengthStreamingMode(out.length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.setRequestProperty("User-Agent", "Minecraft Client " + FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion());
http.connect();
OutputStream os = http.getOutputStream();
os.write(out);
os.flush();
os.close();
if (http.getResponseCode() != 200) {
MCA.getLog().error("Failed to submit crash report. Non-OK response code returned: " + http.getResponseCode());
} else {
MCA.getLog().warn("Crash report submitted successfully.");
}
}
}
} catch (IOException e) {
MCA.getLog().error("An unexpected error occurred while attempting to submit the crash report.", e);
}
}
}
}
================================================
FILE: src/main/java/mca/core/MCAServer.java
================================================
package mca.core;
import mca.core.minecraft.ItemsMCA;
import mca.core.minecraft.VillageHelper;
import mca.entity.EntityGrimReaper;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.PlayerSaveData;
import net.minecraft.entity.Entity;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.FMLCommonHandler;
import java.util.*;
public class MCAServer {
private static MCAServer instance;
// Maps a player's UUID to a list of UUIDs that have proposed to them with /mca propose
private static Map> proposals;
// List of UUIDs that initiated procreation mapped to the time the request expires.
private static Map procreateMap;
private int serverTicks = 0;
private int reaperSummonTicks = 0;
private BlockPos reaperSpawnPos = BlockPos.ORIGIN;
private World reaperSpawnWorld = null;
private MCAServer() {
proposals = new HashMap<>();
procreateMap = new HashMap<>();
}
public static MCAServer get() {
if (instance == null) {
instance = new MCAServer();
}
return instance;
}
public void tick() {
serverTicks++;
if (serverTicks >= 100) {
World overworld = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(0);
VillageHelper.tick(overworld);
serverTicks = 0;
}
if (reaperSummonTicks > 0) {
reaperSummonTicks--;
if (reaperSummonTicks % 20 == 0) { // every second
EntityLightningBolt lightningBolt = new EntityLightningBolt(reaperSpawnWorld, reaperSpawnPos.getX(), reaperSpawnPos.getY(), reaperSpawnPos.getZ(), false);
reaperSpawnWorld.addWeatherEffect(lightningBolt);
}
if (reaperSummonTicks == 0) { // when counter reaches 0
EntityGrimReaper reaper = new EntityGrimReaper(reaperSpawnWorld);
reaper.setPosition(reaperSpawnPos.getX(), reaperSpawnPos.getY(), reaperSpawnPos.getZ());
reaperSpawnWorld.spawnEntity(reaper);
}
}
// Collect all expired procreate requests and remove them.
List removals = new ArrayList<>();
procreateMap.keySet().stream()
.filter((k) -> procreateMap.get(k) < System.currentTimeMillis())
.forEach(removals::add);
removals.forEach(procreateMap::remove);
}
/**
* Returns true if receiver has a proposal from sender.
*
* @param sender Command sender
* @param receiver Player whose name was entered by the sender
* @return boolean
*/
private boolean hasProposalFrom(EntityPlayer sender, EntityPlayer receiver) {
return getProposalsFor(receiver).contains(sender.getUniqueID());
}
/**
* Returns all proposals for the provided player
*
* @param player Player whose proposals should be returned.
* @return List
*/
private List getProposalsFor(EntityPlayer player) {
return proposals.getOrDefault(player.getUniqueID(), new ArrayList<>());
}
/**
* Removes the provided proposer from the target's list of proposals.
*
* @param target Target player who's proposal list will be modified.
* @param proposer The proposer to the target player.
*/
private void removeProposalFor(EntityPlayer target, EntityPlayer proposer) {
List list = getProposalsFor(target);
list.remove(proposer.getUniqueID());
proposals.put(target.getUniqueID(), list);
}
/**
* Lists all proposals for the given player.
*
* @param sender Player whose active proposals will be listed.
*/
public void listProposals(EntityPlayer sender) {
List proposals = getProposalsFor(sender);
if (proposals.size() == 0) {
infoMessage(sender, "You have no active proposals.");
} else {
infoMessage(sender, "You have active proposals from: ");
}
// Send the name of all online players to the command sender.
proposals.forEach((uuid -> {
EntityPlayer player = sender.world.getPlayerEntityByUUID(uuid);
if (player != null) {
infoMessage(sender, "- " + player.getName());
}
}));
}
/**
* Sends a proposal from the sender to the receiver.
*
* @param sender The player sending the proposal.
* @param receiver The player being proposed to.
*/
public void sendProposal(EntityPlayer sender, EntityPlayer receiver) {
// Ensure the sender isn't already married.
if (PlayerSaveData.get(sender).isMarriedOrEngaged()) {
failMessage(sender, "You cannot send a proposal since you are already married or engaged.");
return;
}
// Ensure the sender isn't himself.
if (sender == receiver) {
failMessage(sender, "You cannot propose to yourself.");
return;
}
// Ensure the receiver hasn't already been proposed to by this player.
if (hasProposalFrom(sender, receiver)) {
failMessage(sender, "You have already sent a proposal to " + receiver.getName());
} else {
// Send the proposal messages.
successMessage(sender, "Your proposal to " + receiver.getName() + " has been sent!");
infoMessage(receiver, sender.getName() + " has proposed marriage. To accept, type /mca accept " + sender.getName());
// Add the proposal to the receiver's proposal list.
List list = getProposalsFor(receiver);
list.add(sender.getUniqueID());
proposals.put(receiver.getUniqueID(), list);
}
}
/**
* Rejects and removes a proposal from the receiver to the sender.
*
* @param sender The person rejecting the proposal.
* @param receiver The initial proposer.
*/
public void rejectProposal(EntityPlayer sender, EntityPlayer receiver) {
// Ensure a proposal existed.
if (!hasProposalFrom(receiver, sender)) {
failMessage(sender, receiver.getName() + " hasn't proposed to you.");
} else {
// Notify of the proposal failure and remove it.
successMessage(sender, "Your rejection has been sent.");
failMessage(receiver, sender.getName() + " rejected your proposal.");
removeProposalFor(sender, receiver);
}
}
/**
* Accepts and removes a proposal from the receiver to the sender.
*
* @param sender The person accepting the proposal.
* @param receiver The initial proposer.
*/
public void acceptProposal(EntityPlayer sender, EntityPlayer receiver) {
// Ensure a proposal is active.
if (!hasProposalFrom(receiver, sender)) {
failMessage(sender, receiver.getName() + " hasn't proposed to you.");
} else {
// Notify of acceptance.
successMessage(receiver, sender.getName() + " has accepted your proposal!");
// Set both player datas as married.
PlayerSaveData senderData = PlayerSaveData.get(sender);
PlayerSaveData receiverData = PlayerSaveData.get(receiver);
senderData.marry(receiver.getUniqueID(), receiver.getName());
receiverData.marry(sender.getUniqueID(), sender.getName());
// Send success messages.
successMessage(sender, "You and " + receiver.getName() + " are now married.");
successMessage(receiver, "You and " + sender.getName() + " are now married.");
// Remove the proposal.
removeProposalFor(sender, receiver);
}
}
/**
* Ends the sender's marriage and notifies their spouse if the spouse is online.
*
* @param sender The person ending their marriage.
*/
public void endMarriage(EntityPlayer sender) {
// Retrieve all data instances and an instance of the ex-spouse if they are present.
PlayerSaveData senderData = PlayerSaveData.get(sender);
// Ensure the sender is married
if (!senderData.isMarriedOrEngaged()) {
failMessage(sender, "You are not married.");
return;
}
// Lookup the spouse, if it's a villager, we can't continue
Optional spouse = sender.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(senderData.getSpouseUUID())).findFirst();
if (spouse.isPresent() && spouse.get() instanceof EntityVillagerMCA) {
failMessage(sender, "You cannot use this command when married to a villager.");
return;
}
PlayerSaveData receiverData = PlayerSaveData.getExisting(sender.world, senderData.getSpouseUUID());
// Notify the sender of the success and end both marriages.
successMessage(sender, "Your marriage to " + senderData.getSpouseName() + " has ended.");
senderData.endMarriage();
receiverData.endMarriage();
// Notify the ex if they are online.
spouse.ifPresent(e -> failMessage((EntityPlayer) e, sender.getName() + " has ended their marriage with you."));
}
/**
* Initiates procreation with a married player.
*
* @param sender The person requesting procreation.
*/
public void procreate(EntityPlayer sender) {
// Ensure the sender is married.
PlayerSaveData senderData = PlayerSaveData.get(sender);
if (!senderData.isMarriedOrEngaged()) {
failMessage(sender, "You cannot procreate if you are not married.");
return;
}
// Ensure we don't already have a baby
if (senderData.isBabyPresent()) {
failMessage(sender, "You already have a baby.");
return;
}
// Ensure the spouse is online.
EntityPlayer spouse = sender.world.getPlayerEntityByUUID(senderData.getSpouseUUID());
if (spouse != null) {
// If the spouse is online and has previously sent a procreation request that hasn't expired, we can continue.
// Otherwise we notify the spouse that they must also enter the command.
if (!procreateMap.containsKey(spouse.getUniqueID())) {
procreateMap.put(sender.getUniqueID(), System.currentTimeMillis() + 10000);
infoMessage(spouse, sender.getName() + " has requested procreation. To accept, type /mca procreate within 10 seconds.");
} else {
// On success, add a randomly generated baby to the original requester.
successMessage(sender, "Procreation successful!");
successMessage(spouse, "Procreation successful!");
spouse.addItemStackToInventory(new ItemStack(sender.world.rand.nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));
PlayerSaveData spouseData = PlayerSaveData.get(spouse);
spouseData.setBabyPresent(true);
senderData.setBabyPresent(true);
}
} else {
failMessage(sender, "Your spouse is not present on the server.");
}
}
private void successMessage(EntityPlayer player, String message) {
player.sendMessage(new TextComponentString(Constants.Color.GREEN + message));
}
private void failMessage(EntityPlayer player, String message) {
player.sendMessage(new TextComponentString(Constants.Color.RED + message));
}
private void infoMessage(EntityPlayer player, String message) {
player.sendMessage(new TextComponentString(Constants.Color.YELLOW + message));
}
public void setReaperSpawnPos(World world, BlockPos pos) {
this.reaperSpawnWorld = world;
this.reaperSpawnPos = pos;
}
public void startSpawnReaper() {
this.reaperSummonTicks = 20 * 4; // 3 seconds
}
}
================================================
FILE: src/main/java/mca/core/forge/ClientProxy.java
================================================
package mca.core.forge;
import mca.client.render.RenderReaperFactory;
import mca.client.render.RenderVillagerFactory;
import mca.core.minecraft.BlocksMCA;
import mca.core.minecraft.ItemsMCA;
import mca.entity.EntityGrimReaper;
import mca.entity.EntityVillagerMCA;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
public class ClientProxy extends ServerProxy {
@Override
public void registerEntityRenderers() {
RenderingRegistry.registerEntityRenderingHandler(EntityVillagerMCA.class, RenderVillagerFactory.INSTANCE);
RenderingRegistry.registerEntityRenderingHandler(EntityGrimReaper.class, RenderReaperFactory.INSTANCE);
}
@Override
public void registerModelMeshers() {
ItemsMCA.registerModelMeshers();
BlocksMCA.registerModelMeshers();
}
}
================================================
FILE: src/main/java/mca/core/forge/EventHooks.java
================================================
package mca.core.forge;
import mca.client.network.ClientMessageQueue;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.MCAServer;
import mca.core.minecraft.BlocksMCA;
import mca.core.minecraft.ItemsMCA;
import mca.core.minecraft.ProfessionsMCA;
import mca.core.minecraft.WorldEventListenerMCA;
import mca.entity.EntityVillagerMCA;
import mca.items.ItemBaby;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.world.World;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.LivingDamageEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public class EventHooks {
// Maps a player UUID to the itemstack of their held ItemBaby. Filled when a player dies so the baby is never lost.
public Map limbo = new HashMap<>();
@SubscribeEvent
public void onRegisterItems(RegistryEvent.Register- event) {
ItemsMCA.register(event);
BlocksMCA.registerItemBlocks(event);
GameRegistry.addSmelting(BlocksMCA.ROSE_GOLD_ORE, new ItemStack(ItemsMCA.ROSE_GOLD_INGOT), 5.0F);
}
@SubscribeEvent
public void onRegisterBlocks(RegistryEvent.Register event) {
BlocksMCA.register(event);
}
@SubscribeEvent
public void onWorldLoad(WorldEvent.Load event) {
if (event.getWorld().isRemote) event.getWorld().addEventListener(new WorldEventListenerMCA());
}
@SubscribeEvent
public void onClientTick(TickEvent.ClientTickEvent event) {
ClientMessageQueue.processScheduledMessages();
}
@SubscribeEvent
public void onServerTick(TickEvent.ServerTickEvent event) {
MCAServer.get().tick();
}
@SubscribeEvent
public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (!MCA.updateAvailable) return;
TextComponentString updateMessage = new TextComponentString(Constants.Color.DARKGREEN + "An update for Minecraft Comes Alive is available: v" + MCA.latestVersion);
String updateURLText = Constants.Color.YELLOW + "Click " + Constants.Color.BLUE + Constants.Format.ITALIC + Constants.Format.UNDERLINE + "here" + Constants.Format.RESET + Constants.Color.YELLOW + " to download the update.";
TextComponentString chatComponentUpdate = new TextComponentString(updateURLText);
chatComponentUpdate.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://minecraftcomesalive.com/download"));
chatComponentUpdate.getStyle().setUnderlined(true);
event.player.sendMessage(updateMessage);
event.player.sendMessage(chatComponentUpdate);
MCA.updateAvailable = false;
}
@SubscribeEvent
public void onWorldUnload(WorldEvent.Unload event) {
// Only send crash reports on unloading the overworld. This will never change based on other mods installed
// and ensures only one crash report is sent per instance.
if (!event.getWorld().isRemote && event.getWorld().provider.getDimension() == 0) MCA.getInstance().checkForCrashReports();
}
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event) {
World world = event.getWorld();
Entity entity = event.getEntity();
if (world.isRemote) return;
if (!MCA.getConfig().overwriteOriginalVillagers) return;
if (entity.getClass().equals(EntityVillager.class)) {
EntityVillager originalVillager = (EntityVillager) entity;
originalVillager.setDead();
EntityVillagerMCA newVillager = new EntityVillagerMCA(world, com.google.common.base.Optional.of(originalVillager.getProfessionForge()), com.google.common.base.Optional.absent());
newVillager.setPosition(originalVillager.posX, originalVillager.posY, originalVillager.posZ);
newVillager.finalizeMobSpawn(world.getDifficultyForLocation(newVillager.getPos()), null, false);
newVillager.forcePositionAsHome();
world.spawnEntity(newVillager);
}
}
@SubscribeEvent
public void onEntityInteractSpecific(PlayerInteractEvent.EntityInteractSpecific event) {
if (event.getTarget() instanceof EntityVillagerMCA && event.getEntityPlayer() != null) {
EntityPlayer player = event.getEntityPlayer();
EntityVillagerMCA villager = (EntityVillagerMCA)event.getTarget();
if (villager.getProfessionForge() == ProfessionsMCA.bandit) {
event.setResult(Event.Result.DENY);
} else if (player.getHeldItemMainhand().getItem() == ItemsMCA.VILLAGER_EDITOR) {
player.openGui(MCA.getInstance(), Constants.GUI_ID_VILLAGEREDITOR, player.world, villager.getEntityId(), 0, 0);
event.setResult(Event.Result.ALLOW);
} else {
player.addStat(StatList.TALKED_TO_VILLAGER);
player.openGui(MCA.getInstance(), Constants.GUI_ID_INTERACT, player.world, villager.getEntityId(), 0, 0);
event.setResult(Event.Result.ALLOW);
}
}
}
@SubscribeEvent
public void onEntityDamaged(LivingDamageEvent event) {
if (event.getEntity() instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA)event.getEntity();
Entity source = event.getSource() != null ? event.getSource().getTrueSource() : null;
if (source instanceof EntityLivingBase) {
villager.world.loadedEntityList.stream().filter(e ->
e instanceof EntityVillagerMCA &&
e.getDistance(villager) <= 10.0D &&
((EntityVillagerMCA)e).getProfessionForge() == ProfessionsMCA.guard)
.forEach(e -> ((EntityVillagerMCA) e).setAttackTarget((EntityLivingBase)source));
}
}
}
@SubscribeEvent
public void onItemToss(ItemTossEvent event) {
ItemStack stack = event.getEntityItem().getItem();
if (stack.getItem() instanceof ItemBaby) {
event.getPlayer().addItemStackToInventory(stack);
event.setCanceled(true);
}
}
@SubscribeEvent
public void onPlaceEvent(BlockEvent.PlaceEvent event) {
int x = event.getPos().getX();
int y = event.getPos().getY();
int z = event.getPos().getZ();
Block placedBlock = event.getPlacedBlock().getBlock();
if (placedBlock == Blocks.FIRE && event.getWorld().getBlockState(new BlockPos(x, y - 1, z)).getBlock() == Blocks.EMERALD_BLOCK) {
int totemsFound = 0;
// Check on +/- X and Z for at least 3 totems on fire.
for (int i = 0; i < 4; i++) {
int dX = 0;
int dZ = 0;
if (i == 0 || i == 2) dX = -3;
else dZ = 3;
// Scan upwards to ensure it's obsidian, and on fire.
for (int j = -1; j < 2; j++) {
Block block = event.getWorld().getBlockState(new BlockPos(x + dX, y + j, z + dZ)).getBlock();
if (block != Blocks.OBSIDIAN && block != Blocks.FIRE) break;
// If we made it up to 1 without breaking, make sure the block is fire so that it's a lit totem.
if (j == 1 && block == Blocks.FIRE) totemsFound++;
}
}
if (totemsFound >= 3 && !event.getWorld().isDaytime()) {
MCAServer.get().setReaperSpawnPos(event.getWorld(), new BlockPos(x + 1, y + 10, z + 1));
MCAServer.get().startSpawnReaper();
for (int i = 0; i < 2; i++) event.getWorld().setBlockToAir(new BlockPos(x, y - i, z));
}
}
}
@SubscribeEvent
public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
// When players respawn check to see if their baby was saved in limbo. Add it back to their inventory.
if (limbo.containsKey(event.player.getUniqueID())) {
event.player.inventory.addItemStackToInventory(limbo.get(event.player.getUniqueID()));
limbo.remove(event.player.getUniqueID());
}
}
@SubscribeEvent
public void onLivingDeath(LivingDeathEvent event) {
// If a player dies while holding a baby, remember it until they respawn.
if (event.getEntityLiving() instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer)event.getEntityLiving();
Optional babyStack = player.inventory.mainInventory.stream().filter(s -> s.getItem() instanceof ItemBaby).findFirst();
babyStack.ifPresent(s -> limbo.put(player.getUniqueID(), babyStack.get()));
}
}
@SubscribeEvent
public void onLivingSetTarget(LivingSetAttackTargetEvent event) {
// Mobs shouldn't attack infected villagers. Account for this when they attempt to set their target.
if (event.getEntityLiving() instanceof EntityMob && event.getTarget() instanceof EntityVillagerMCA) {
EntityMob mob = (EntityMob) event.getEntityLiving();
EntityVillagerMCA target = (EntityVillagerMCA) event.getTarget();
if (target.get(EntityVillagerMCA.IS_INFECTED)) {
mob.setAttackTarget(null);
}
}
}
@SubscribeEvent
public void onPlaySoundAtEntityEvent(PlaySoundAtEntityEvent event) {
// Cancel all villager sounds. We unfortunately cannot control on a per entity basis as getEntity() always returns null.
if (FMLCommonHandler.instance().getEffectiveSide() != Side.CLIENT) return;
try {
event.setCanceled(event.getSound().getSoundName().toString().contains("villager"));
} catch (NullPointerException e) {
// throw out potential NPEs due to bad event data. some of these have been reported
}
}
}
================================================
FILE: src/main/java/mca/core/forge/GuiHandler.java
================================================
package mca.core.forge;
import mca.client.gui.*;
import mca.core.Constants;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.gui.GuiScreenBook;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
public class GuiHandler implements IGuiHandler {
@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int entityId, int posY, int posZ) {
switch (guiId) {
case Constants.GUI_ID_INVENTORY:
EntityVillagerMCA villager = (EntityVillagerMCA) world.getEntityByID(entityId);
if (villager == null || villager.inventory == null) return null;
return new ContainerChest(player.inventory, villager.inventory, player);
default:
return null;
}
}
@Override
public Object getClientGuiElement(int guiId, EntityPlayer player, World world, int entityId, int unused1, int unused2) {
switch (guiId) {
case Constants.GUI_ID_INVENTORY:
Entity entity = world.getEntityByID(entityId);
if (entity == null) return null;
return new GuiChest(player.inventory, ((EntityVillagerMCA) entity).inventory);
case Constants.GUI_ID_INTERACT:
return new GuiInteract((EntityVillagerMCA) world.getEntityByID(entityId), player);
case Constants.GUI_ID_NAMEBABY:
return new GuiNameBaby(player, player.inventory.getStackInSlot(player.inventory.currentItem));
case Constants.GUI_ID_STAFFOFLIFE:
return new GuiStaffOfLife(player);
case Constants.GUI_ID_VILLAGEREDITOR:
return new GuiVillagerEditor((EntityVillagerMCA) world.getEntityByID(entityId), player);
case Constants.GUI_ID_GUIDEBOOK:
return new GuiScreenBook(player, player.inventory.getCurrentItem(), false);
case Constants.GUI_ID_WHISTLE:
return new GuiWhistle();
default:
MCA.getLog().fatal("Failed to handle provided GUI ID on client: " + guiId);
return null;
}
}
}
================================================
FILE: src/main/java/mca/core/forge/NetMCA.java
================================================
package mca.core.forge;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import mca.client.gui.GuiStaffOfLife;
import mca.client.gui.GuiWhistle;
import mca.client.network.ClientMessageQueue;
import mca.core.MCA;
import mca.core.minecraft.ProfessionsMCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.SavedVillagers;
import mca.entity.inventory.InventoryMCA;
import mca.items.ItemBaby;
import mca.server.ServerMessageHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.common.registry.VillagerRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import scala.collection.parallel.ParIterableLike;
import javax.annotation.Nullable;
import java.util.*;
public class NetMCA {
public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("mca");
public static void registerMessages() {
INSTANCE.registerMessage(ButtonActionHandler.class, ButtonAction.class, 0, Side.SERVER);
INSTANCE.registerMessage(SayHandler.class, Say.class, 1, Side.CLIENT);
INSTANCE.registerMessage(BabyNameHandler.class, BabyName.class, 2, Side.SERVER);
INSTANCE.registerMessage(CareerResponseHandler.class, CareerResponse.class, 3, Side.CLIENT);
INSTANCE.registerMessage(CareerRequestHandler.class, CareerRequest.class, 4, Side.SERVER);
INSTANCE.registerMessage(InventoryRequestHandler.class, InventoryRequest.class, 5, Side.SERVER);
INSTANCE.registerMessage(InventoryResponseHandler.class, InventoryResponse.class, 6, Side.CLIENT);
INSTANCE.registerMessage(SavedVillagersRequestHandler.class, SavedVillagersRequest.class, 7, Side.SERVER);
INSTANCE.registerMessage(SavedVillagersResponseHandler.class, SavedVillagersResponse.class, 8, Side.CLIENT);
INSTANCE.registerMessage(ReviveVillagerHandler.class, ReviveVillager.class, 9, Side.SERVER);
INSTANCE.registerMessage(SetNameHandler.class, SetName.class, 10, Side.SERVER);
INSTANCE.registerMessage(SpawnParticlesHandler.class, SpawnParticles.class, 11, Side.CLIENT);
INSTANCE.registerMessage(GetFamilyHandler.class, GetFamily.class, 12, Side.SERVER);
INSTANCE.registerMessage(GetFamilyResponseHandler.class, GetFamilyResponse.class, 13, Side.CLIENT);
INSTANCE.registerMessage(CallToPlayerHandler.class, CallToPlayer.class, 14, Side.SERVER);
INSTANCE.registerMessage(SetTextureHandler.class, SetTexture.class, 15, Side.SERVER);
INSTANCE.registerMessage(SetProfessionHandler.class, SetProfession.class, 16, Side.SERVER);
}
@SideOnly(Side.CLIENT)
private static EntityPlayer getPlayerClient() {
return Minecraft.getMinecraft().player;
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
public static class ButtonAction implements IMessage {
private String guiKey;
private String buttonId;
private UUID targetUUID;
@Override
public void toBytes(ByteBuf buf) {
buf.writeBoolean(targetUUID != null);
ByteBufUtils.writeUTF8String(buf, this.guiKey);
ByteBufUtils.writeUTF8String(buf, this.buttonId);
if (targetUUID != null) {
ByteBufUtils.writeUTF8String(buf, this.targetUUID.toString());
}
}
@Override
public void fromBytes(ByteBuf buf) {
boolean hasTarget = buf.readBoolean();
this.guiKey = ByteBufUtils.readUTF8String(buf);
this.buttonId = ByteBufUtils.readUTF8String(buf);
if (hasTarget) {
this.targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public boolean targetsServer() {
return getTargetUUID() == null;
}
}
public static class ButtonActionHandler implements IMessageHandler {
@Override
public IMessage onMessage(ButtonAction message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
// The message can target a particular villager, or the server itself.
if (!message.targetsServer()) {
EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.targetUUID);
if (villager != null) player.getServerWorld().addScheduledTask(() -> villager.handleButtonClick(player, message.guiKey, message.buttonId));
} else ServerMessageHandler.handleMessage(player, message);
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class Say implements IMessage {
private String phraseId;
private int speakingEntityId;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, this.phraseId);
buf.writeInt(this.speakingEntityId);
}
@Override
public void fromBytes(ByteBuf buf) {
this.phraseId = ByteBufUtils.readUTF8String(buf);
this.speakingEntityId = buf.readInt();
}
}
public static class SayHandler implements IMessageHandler {
@Override
public IMessage onMessage(Say message, MessageContext ctx) {
EntityPlayer player = getPlayerClient();
EntityVillagerMCA villager = (EntityVillagerMCA) player.getEntityWorld().getEntityByID(message.speakingEntityId);
if (villager != null) villager.say(com.google.common.base.Optional.of(player), message.phraseId);
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class BabyName implements IMessage {
private String babyName;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, this.babyName);
}
@Override
public void fromBytes(ByteBuf buf) {
this.babyName = ByteBufUtils.readUTF8String(buf);
}
}
public static class BabyNameHandler implements IMessageHandler {
@Override
public IMessage onMessage(BabyName message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
ItemStack stack = player.inventory.getStackInSlot(player.inventory.currentItem);
if (stack.getItem() instanceof ItemBaby) stack.getTagCompound().setString("name", message.babyName);
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
public static class CareerResponse implements IMessage {
private int careerId;
private UUID entityUUID;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeVarInt(buf, careerId, 4);
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
}
@Override
public void fromBytes(ByteBuf buf) {
this.careerId = ByteBufUtils.readVarInt(buf, 4);
this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public static class CareerResponseHandler implements IMessageHandler {
@Override
public IMessage onMessage(CareerResponse message, MessageContext ctx) {
// must be thrown in the queue and processed on the main thread since we must loop through the loaded entity list
// it could change while looping and cause a ConcurrentModificationException.
ClientMessageQueue.add(message);
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class CareerRequest implements IMessage {
private UUID entityUUID;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
}
@Override
public void fromBytes(ByteBuf buf) {
this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public static class CareerRequestHandler implements IMessageHandler {
@Override
public IMessage onMessage(CareerRequest message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
int careerId = -255;
try {
EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.entityUUID);
if (villager != null) careerId = ObfuscationReflectionHelper.getPrivateValue(EntityVillager.class, villager, EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);
} catch (ClassCastException ignored) {
MCA.getLog().error("UUID provided in career request does not match an MCA villager!: " + message.entityUUID.toString());
return null;
} catch (NullPointerException ignored) {
MCA.getLog().error("UUID provided in career request does not match a loaded MCA villager!: " + message.entityUUID.toString());
return null;
}
if (careerId == -255) {
MCA.getLog().error("Career ID wasn't assigned for UUID: " + message.entityUUID);
return null;
}
return new CareerResponse(careerId, message.entityUUID);
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class InventoryRequest implements IMessage {
private UUID entityUUID;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
}
@Override
public void fromBytes(ByteBuf buf) {
this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public static class InventoryRequestHandler implements IMessageHandler {
@Override
public IMessage onMessage(InventoryRequest message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.entityUUID);
if (villager != null && villager.inventory != null) return new InventoryResponse(villager.getUniqueID(), villager.inventory);
return null;
}
}
@NoArgsConstructor
@Getter
public static class InventoryResponse implements IMessage {
private UUID entityUUID;
private NBTTagCompound inventoryNBT;
public InventoryResponse(UUID entityUUID, InventoryMCA inventory) {
this.inventoryNBT = new NBTTagCompound();
this.entityUUID = entityUUID;
this.inventoryNBT.setTag("inventory", inventory.writeInventoryToNBT());
}
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
ByteBufUtils.writeTag(buf, inventoryNBT);
}
@Override
public void fromBytes(ByteBuf buf) {
this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
this.inventoryNBT = ByteBufUtils.readTag(buf);
}
}
public static class InventoryResponseHandler implements IMessageHandler {
@Override
public IMessage onMessage(InventoryResponse message, MessageContext ctx) {
ClientMessageQueue.add(message);
return null;
}
}
public static class SavedVillagersRequest implements IMessage {
@Override
public void fromBytes(ByteBuf buf) {}
@Override
public void toBytes(ByteBuf buf) {}
}
public static class SavedVillagersRequestHandler implements IMessageHandler {
@Override
public IMessage onMessage(SavedVillagersRequest message, MessageContext ctx) {
return new SavedVillagersResponse(ctx.getServerHandler().player);
}
}
@NoArgsConstructor
public static class SavedVillagersResponse implements IMessage {
private Map villagers = new HashMap<>();
public SavedVillagersResponse(EntityPlayer player) {
villagers = SavedVillagers.get(player.world).getMap();
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(villagers.size());
villagers.forEach((k,v) -> {
ByteBufUtils.writeUTF8String(buf, k);
ByteBufUtils.writeTag(buf, v);
});
}
@Override
public void fromBytes(ByteBuf buf) {
int size = buf.readInt();
for (int i = 0; i < size; i++) {
String k = ByteBufUtils.readUTF8String(buf);
NBTTagCompound v = ByteBufUtils.readTag(buf);
villagers.put(k, v);
}
}
}
public static class SavedVillagersResponseHandler implements IMessageHandler {
@Override
public IMessage onMessage(SavedVillagersResponse message, MessageContext ctx) {
GuiScreen screen = Minecraft.getMinecraft().currentScreen;
if (screen instanceof GuiStaffOfLife) ((GuiStaffOfLife) screen).setVillagerData(message.villagers);
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class ReviveVillager implements IMessage {
private UUID target;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, target.toString());
}
@Override
public void fromBytes(ByteBuf buf) {
target = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public static class ReviveVillagerHandler implements IMessageHandler {
@Override
public IMessage onMessage(ReviveVillager message, MessageContext ctx) {
EntityPlayer player = ctx.getServerHandler().player;
SavedVillagers villagers = SavedVillagers.get(player.world);
NBTTagCompound nbt = SavedVillagers.get(player.world).loadByUUID(message.target);
if (nbt != null) {
EntityVillagerMCA villager = new EntityVillagerMCA(player.world);
villager.setPosition(player.posX, player.posY, player.posZ);
player.world.spawnEntity(villager);
villager.readEntityFromNBT(nbt);
villager.reset();
villagers.remove(message.target);
player.inventory.mainInventory.get(player.inventory.currentItem).damageItem(1, player);
}
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class SetName implements IMessage {
private String name;
private UUID entityUUID;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
ByteBufUtils.writeUTF8String(buf, name);
}
@Override
public void fromBytes(ByteBuf buf) {
entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
name = ByteBufUtils.readUTF8String(buf);
}
}
public static class SetNameHandler implements IMessageHandler {
@Override
public IMessage onMessage(SetName message, MessageContext ctx) {
World world = ctx.getServerHandler().player.world;
java.util.Optional entity = world.loadedEntityList.stream().filter((e) -> e.getUniqueID().equals(message.entityUUID)).findFirst();
if (!entity.isPresent()) return null;
if (entity.get() instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA) entity.get();
villager.set(EntityVillagerMCA.VILLAGER_NAME, message.name);
}
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class SpawnParticles implements IMessage {
private UUID entityUUID;
private EnumParticleTypes particleType;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, entityUUID.toString());
buf.writeInt(particleType.getParticleID());
}
@Override
public void fromBytes(ByteBuf buf) {
entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
particleType = EnumParticleTypes.getParticleFromId(buf.readInt());
}
}
public static class SpawnParticlesHandler implements IMessageHandler {
@Override
public IMessage onMessage(SpawnParticles message, MessageContext ctx) {
World world = getPlayerClient().world;
java.util.Optional entity = world.loadedEntityList.stream().filter((e) -> e.getUniqueID().equals(message.entityUUID)).findFirst();
if (!entity.isPresent()) return null;
if (entity.get() instanceof EntityVillagerMCA) {
EntityVillagerMCA villager = (EntityVillagerMCA) entity.get();
villager.spawnParticles(message.particleType);
}
return null;
}
}
@NoArgsConstructor
public static class GetFamily implements IMessage {
@Override
public void toBytes(ByteBuf buf) {}
@Override
public void fromBytes(ByteBuf buf) {}
}
public static class GetFamilyHandler implements IMessageHandler {
@Override
public IMessage onMessage(GetFamily message, MessageContext ctx) {
EntityPlayer player = ctx.getServerHandler().player;
List villagers = new ArrayList<>();
List familyData = new ArrayList<>();
player.world.loadedEntityList.stream().filter(e -> e instanceof EntityVillagerMCA).forEach(e -> villagers.add((EntityVillagerMCA)e));
villagers.stream().filter(e -> e.isMarriedTo(player.getUniqueID()) || e.playerIsParent(player)).forEach(e -> {
NBTTagCompound nbt = new NBTTagCompound();
e.writeEntityToNBT(nbt);
familyData.add(nbt);
});
return new GetFamilyResponse(familyData);
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class GetFamilyResponse implements IMessage {
private List familyData;
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(familyData.size());
familyData.stream().forEach(n -> ByteBufUtils.writeTag(buf, n));
}
@Override
public void fromBytes(ByteBuf buf) {
familyData = new ArrayList<>();
int size = buf.readInt();
for (int i = 0; i < size; i++) {
familyData.add(ByteBufUtils.readTag(buf));
}
}
}
public static class GetFamilyResponseHandler implements IMessageHandler {
@Override
public IMessage onMessage(GetFamilyResponse message, MessageContext ctx) {
GuiScreen screen = Minecraft.getMinecraft().currentScreen;
if (screen instanceof GuiWhistle) {
GuiWhistle whistleScreen = (GuiWhistle)screen;
whistleScreen.setVillagerDataList(message.familyData);
}
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class CallToPlayer implements IMessage {
private UUID targetUUID;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, targetUUID.toString());
}
@Override
public void fromBytes(ByteBuf buf) {
targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
}
}
public static class CallToPlayerHandler implements IMessageHandler {
@Override
public IMessage onMessage(CallToPlayer message, MessageContext ctx) {
EntityPlayer player = ctx.getServerHandler().player;
Optional entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();
entity.ifPresent(e -> {
e.setPosition(player.posX, player.posY, player.posZ);
((EntityLiving)e).getNavigator().clearPath();
});
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class SetProfession implements IMessage {
private UUID targetUUID;
private String profession;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, targetUUID.toString());
ByteBufUtils.writeUTF8String(buf, profession);
}
@Override
public void fromBytes(ByteBuf buf) {
targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
profession = ByteBufUtils.readUTF8String(buf);
}
}
public static class SetProfessionHandler implements IMessageHandler {
@Override
public IMessage onMessage(SetProfession message, MessageContext ctx) {
boolean isCareerSet = false;
EntityPlayer player = ctx.getServerHandler().player;
Optional entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();
if (entity.isPresent()) {
// Loop through all professions in the registry
for (Map.Entry professionEntry : ProfessionsMCA.registry.getEntries()) {
List careers = ObfuscationReflectionHelper.getPrivateValue(VillagerRegistry.VillagerProfession.class, professionEntry.getValue(), 3);
// Career ids are based on their index in the careers list
for (int i = 0; i < careers.size(); i++) {
VillagerRegistry.VillagerCareer career = careers.get(i);
// If we found the correct career, set the profession and career accordingly
if (career.getName().equals(message.profession)) {
EntityVillagerMCA villager = (EntityVillagerMCA)entity.get();
villager.setProfession(professionEntry.getValue());
villager.setVanillaCareer(i);
player.sendMessage(new TextComponentString("Career set to " + message.profession));
isCareerSet = true;
break;
}
}
}
} else {
MCA.getLog().error("Entity not found on career set!: " + message.targetUUID.toString());
return null;
}
if (!isCareerSet) {
player.sendMessage(new TextComponentString("Career not found: " + message.profession));
}
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
public static class SetTexture implements IMessage {
private UUID targetUUID;
private String texture;
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, targetUUID.toString());
ByteBufUtils.writeUTF8String(buf, texture);
}
@Override
public void fromBytes(ByteBuf buf) {
targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));
texture = ByteBufUtils.readUTF8String(buf);
}
}
public static class SetTextureHandler implements IMessageHandler {
@Override
public IMessage onMessage(SetTexture message, MessageContext ctx) {
EntityPlayer player = ctx.getServerHandler().player;
Optional entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();
entity.ifPresent(e -> ((EntityVillagerMCA)e).set(EntityVillagerMCA.TEXTURE, message.texture));
return null;
}
}
}
================================================
FILE: src/main/java/mca/core/forge/ServerProxy.java
================================================
package mca.core.forge;
public class ServerProxy {
public void registerEntityRenderers() {
// Server-side, no rendering.
}
public void registerEventHandlers() {
}
public void registerModelMeshers() {
}
}
================================================
FILE: src/main/java/mca/core/minecraft/BlocksMCA.java
================================================
package mca.core.minecraft;
import mca.blocks.BlockVillagerSpawner;
import mca.core.MCA;
import net.minecraft.block.Block;
import net.minecraft.block.BlockOre;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.registries.IForgeRegistry;
import java.util.ArrayList;
public final class BlocksMCA {
public static final Block ROSE_GOLD_BLOCK = new BlockOre();
public static final Block ROSE_GOLD_ORE = new BlockOre();
public static final BlockVillagerSpawner VILLAGER_SPAWNER = new BlockVillagerSpawner();
private static final ArrayList BLOCKS = new ArrayList<>();
public static void register(RegistryEvent.Register event) {
ROSE_GOLD_BLOCK.setHardness(3.0F).setResistance(5.0F).setCreativeTab(MCA.creativeTab);
ROSE_GOLD_BLOCK.setHarvestLevel("pickaxe", 2);
ROSE_GOLD_ORE.setHardness(3.0F).setResistance(5.0F).setCreativeTab(MCA.creativeTab);
ROSE_GOLD_ORE.setHarvestLevel("pickaxe", 2);
VILLAGER_SPAWNER.setCreativeTab(MCA.creativeTab);
Block[] blocks = {
ROSE_GOLD_BLOCK,
ROSE_GOLD_ORE,
VILLAGER_SPAWNER
};
setBlockName(ROSE_GOLD_BLOCK, "rose_gold_block");
setBlockName(ROSE_GOLD_ORE, "rose_gold_ore");
setBlockName(VILLAGER_SPAWNER, "villager_spawner");
for (Block block : blocks) {
event.getRegistry().register(block);
BLOCKS.add(block);
}
}
public static void registerItemBlocks(RegistryEvent.Register
- event) {
IForgeRegistry
- registry = event.getRegistry();
ItemBlock[] items = {
new ItemBlock(ROSE_GOLD_BLOCK),
new ItemBlock(ROSE_GOLD_ORE),
new ItemBlock(VILLAGER_SPAWNER)
};
for (ItemBlock item : items) {
Block block = item.getBlock();
ResourceLocation registryName = block.getRegistryName();
registry.register(item.setRegistryName(registryName));
}
}
private static void setBlockName(Block block, String blockName) {
block.setRegistryName(MCA.MODID, blockName);
block.setUnlocalizedName(block.getRegistryName().toString());
}
@SideOnly(Side.CLIENT)
public static void registerModelMeshers() {
ItemModelMesher mesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();
for (Block block : BLOCKS) {
mesher.register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory"));
}
}
}
================================================
FILE: src/main/java/mca/core/minecraft/ItemsMCA.java
================================================
package mca.core.minecraft;
import mca.core.Constants;
import mca.core.MCA;
import mca.items.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public final class ItemsMCA {
public static final ItemSpawnEgg EGG_MALE = new ItemSpawnEgg(true);
public static final ItemSpawnEgg EGG_FEMALE = new ItemSpawnEgg(false);
public static final Item WEDDING_RING = new ItemWeddingRing().setMaxStackSize(1);
public static final Item WEDDING_RING_RG = new ItemWeddingRing().setMaxStackSize(1);
public static final Item ENGAGEMENT_RING = new ItemEngagementRing().setMaxStackSize(1);
public static final Item ENGAGEMENT_RING_RG = new ItemEngagementRing().setMaxStackSize(1);
public static final Item MATCHMAKERS_RING = new ItemMatchmakersRing().setMaxStackSize(2);
public static final Item BABY_BOY = new ItemBaby(true);
public static final Item BABY_GIRL = new ItemBaby(false);
public static final Item ROSE_GOLD_INGOT = new Item().setUnlocalizedName("rose_gold_ingot");
public static final Item ROSE_GOLD_DUST = new Item().setUnlocalizedName("rose_gold_dust");
public static final Item GOLD_DUST = new Item().setUnlocalizedName("gold_dust");
public static final Item VILLAGER_EDITOR = new ItemVillagerEditor();
public static final Item STAFF_OF_LIFE = new ItemStaffOfLife();
public static final Item WHISTLE = new ItemWhistle();
public static final ItemGuideBook BOOK_DEATH = new ItemGuideBook();
public static final ItemGuideBook BOOK_ROMANCE = new ItemGuideBook();
public static final ItemGuideBook BOOK_FAMILY = new ItemGuideBook();
public static final ItemGuideBook BOOK_ROSE_GOLD = new ItemGuideBook();
public static final ItemGuideBook BOOK_INFECTION = new ItemGuideBook();
private static final List
- ITEMS = new ArrayList<>();
public static void register(RegistryEvent.Register
- event) {
for (Field f : ItemsMCA.class.getFields()) {
try {
Object instance = f.get(null);
if (instance instanceof Item) {
Item item = (Item) instance;
setItemName(item, f.getName().toLowerCase());
event.getRegistry().register(item);
ITEMS.add(item);
}
} catch (Exception e) {
MCA.getLog().error("Error while registering items: ", e);
}
}
}
public static void assignCreativeTabs() {
ITEMS.stream().forEach(i -> i.setCreativeTab(MCA.creativeTab));
}
public static void setBookNBT(ItemStack stack) {
Item book = stack.getItem();
NBTTagCompound nbt = new NBTTagCompound();
if (book == BOOK_DEATH) {
nbt.setString("title", "Death, and How to Cure It!");
nbt.setString("author", "Ozzie the Warrior");
nbt.setBoolean("resolved", true);
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString(""
+ "I couldn't count how many times my family has been blown to pieces by creepers.\n\nHow are they still around, you may ask?"
+ "\n\nEasy! I, dear reader, have discovered a CURE for death itself! And through this book, I can share it with you."));
/*
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Memorials\n\n" + Constants.Format.RESET
+ "When a family member dies, they will drop a chest - and inside will be an " + Constants.Format.BOLD + "item" + Constants.Format.RESET + " that was important to them.\n\n"
+ "This is the key to reviving someone, don't lose it! Only your spouse and children will drop these items."));
*/
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Staff Of Life\n\n" + Constants.Format.RESET
+ "The Staff is a powerful item that can revive up to 5 people. Wave the staff around and speak the name of the villager you wish to revive. Within moments, your loved one will be fully revived!\n\n"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Summoning Grim\n\n" + Constants.Format.RESET
+ "Unfortunately, you must obtain the Staff from the Grim Reaper himself.\n\n"
+ "To summon him, you must build an altar consisting of 3 obsidian columns that are at least 2 blocks high. They may be higher if you like."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Summoning Grim pt. 2\n\n" + Constants.Format.RESET
+ " # # # X # # #\n"
+ " # # # # # # #\n"
+ " # # # # # # #\n"
+ " X # # E # # X\n\n"
+ "X = Obsidian Column\n"
+ "E = Emerald\n"
+ "# = Empty"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Summoning Grim pt. 3\n\n" + Constants.Format.RESET
+ "After building the altar, wait until night and light all 3 columns.\n\n"
+ "When you're ready to fight, light the emerald block and run!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Fighting Grim\n\n" + Constants.Format.RESET
+ "Grim is tough. Use full diamond armor, lots of potions, and lots of enchantments.\n\n"
+ "He can:\n"
+ "- Fly\n"
+ "- Block attacks\n"
+ "- Blind you\n"
+ "- Move your items\n"
+ "- Teleport\n"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Fighting Grim pt. 2\n\n" + Constants.Format.RESET
+ "If you hit Grim while he's blocking, he will teleport behind you and strike.\n\n"
+ "Do not try to use arrows or poison, he is immune!\n\n"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Fighting Grim pt. 3\n\n" + Constants.Format.RESET
+ "When Grim is at " + Constants.Format.BOLD + "half health" + Constants.Format.RESET + " he will teleport into the air and begin healing.\n\n"
+ "While healing, he will summon his minions from the underworld to fight you."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Fighting Grim pt. 4\n\n" + Constants.Format.RESET
+ "When Grim is healed, he will continue attacking you, but he won't be able to heal again for 3 minutes and 30 seconds.\n\n"
+ "Each time Grim heals, he will not be able to restore as much health has he did previously."));
nbt.setTag("pages", pages);
}
else if (book == BOOK_ROMANCE)
{
nbt.setString("title", "Relationships and You");
nbt.setString("author", "Gerry the Librarian");
nbt.setBoolean("resolved", true);
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Introduction\n\n" + Constants.Format.RESET
+ "Interaction is key to building relationships and finding the love of your life.\n\n"
+ "I've happily written this book in order to share my knowledge of interaction, love, and, unfortunately, divorce, to anyone who may need a little push in the right direction."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Interacting\n" + Constants.Format.RESET
+ "Choose wisely when interacting with a villager!\n\n"
+ "If choosing a romantic interaction, be sure that the villager you are talking to likes you a lot."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Interacting pt. 2\n" + Constants.Format.RESET
+ "Don't be annoying! Talking to someone for too long will bore them, and your interactions may stop succeeding.\n\n"
+ "If this happens, simply wait a few minutes before trying to talk to them again."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Marriage\n" + Constants.Format.RESET
+ "To get married, simply gift a villager a wedding ring once you feel you have reached the highest relationship level.\n\n"
+ "Once you're married, you can then procreate and have children of your own!"));
nbt.setTag("pages", pages);
}
else if (book == BOOK_FAMILY)
{
nbt.setString("title", "Managing Your Family Vol. XI");
nbt.setString("author", "Leanne the Cleric");
nbt.setBoolean("resolved", true);
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString(""
+ "Children are our future! Make sure to have as many as you possibly can.\n\nNot only do you get to experience the joy of"
+ " raising a child, but once they are past the baby stage, put them to work!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Babies\n\n" + Constants.Format.RESET
+ "When you are married, simply approach your spouse and offer to 'Procreate'.\n\n"
+ "After a short dance, you'll be the proud owner of a new baby boy or girl (or maybe even both)!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Growth\n\n" + Constants.Format.RESET
+ "Babies take time to grow, make sure to hold them until they are ready, or give them to your spouse to take care of.\n\n"
+ "Once a baby is ready to grow, you may place it on the ground and it will grow into a child!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Adolescence\n\n" + Constants.Format.RESET
+ "Children will grow slowly from a baby to a teen.\n\nHowever, the magical properties of Golden Apples are said to accelerate "
+ "any child's growth. I have yet to try this myself."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Chores\n\n" + Constants.Format.RESET
+ "Any child can harvest, chop wood, prospect, hunt, and fish. You'll need to provide them with the tools they need to do so.\n\n"
+ "If a tool breaks and the child doesn't have another, they will have no choice but to stop working."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Adulthood\n\n" + Constants.Format.RESET
+ "As sad as it may be, children will eventually grow into adults.\n\n"
+ "Adults can be married off by using Matchmaker's Rings, or they will eventually get married on their own."));
nbt.setTag("pages", pages);
}
else if (book == BOOK_ROSE_GOLD)
{
nbt.setString("title", "On Rose Gold");
nbt.setString("author", "William the Miner");
nbt.setBoolean("resolved", true);
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Warning!\nTOP SECRET\n\n" + Constants.Format.RESET
+ "This manual is the property of William Mining Co.\n\nIf you are not a William Mining Co. employee, please refrain from "
+ "reading this manual and return promptly to William the Miner."));
pages.appendTag(new NBTTagString(""
+ "Ah, rose gold - a lovely combination of silver, copper, and gold that smelts into a pinkish orange metal.\n\n"
+ "Most use it as an alternative to gold for crafting rings as it is much less expensive.\n\n"
+ "However, it has some interesting qualities that are easy to miss."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Creating Dust\n\n" + Constants.Format.RESET
+ "Rose gold, once smelted, can be crushed into a fine dust.\n\n"
+ "Look closely at rose gold dust in bright light, and you'll see shiny flecks of pure gold!\n\n"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Washing Dust\n\n" + Constants.Format.RESET
+ "With a little work, we can actually extract the gold from the dust and create pure gold ingots. Simply mix dust with a bucket of water.\n\n"
+ "The lighter silver and copper components will wash away, leaving you with about 6 smaller piles of gold dust."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Extracting Gold\n\n" + Constants.Format.RESET
+ "Arrange 9 piles of dust on your crafting table, and if you're lucky, you'll find a gold nugget in one of them!\n\n"
+ "And of course, once you have 9 gold nuggets, you'll be able to craft them into a solid gold ingot."));
nbt.setTag("pages", pages);
}
else if (book == BOOK_INFECTION)
{
nbt.setString("title", "Beware the Infection!");
nbt.setString("author", "Richard the Zombie");
nbt.setBoolean("resolved", true);
NBTTagList pages = new NBTTagList();
pages.appendTag(new NBTTagString(""
+ "Good day, readers! I've written this book so that you may not end up suffering the same fate as I.\n\n"
+ "Although I caught the infection, I was luckily able to keep all of my mental faculties."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "What is the Infection?\n\n" + Constants.Format.RESET
+ "I discovered long ago that the zombies that appear at night are actually villagers in the late stages of infection!\n\n"
+ "Newly infected villagers turn green, are unable to speak, and occasionally try to bite!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Curing\n\n" + Constants.Format.RESET
+ "Contrary to popular belief, the infection can be cured if caught in time.\n\n"
+ "You must first weaken the villager or zombie with a potion.\n\n"
+ "Then, immediately feed them a golden apple."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Curing pt. 2\n\n" + Constants.Format.RESET
+ "Zombies that can be cured often have enlarged heads and noses.\n\n"
+ "Any other zombies you see unfortunately are too far gone, and cannot be cured."));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Curing pt. 3\n\n" + Constants.Format.RESET
+ "Zombies will take a couple of minutes to be fully cured.\n\n"
+ "Villagers who were recently infected, though, and haven't had time to degrade into a full zombie, will be cured instantly!"));
pages.appendTag(new NBTTagString(Constants.Format.BOLD + "Warnings\n\n" + Constants.Format.RESET
+ "Villagers are highly susceptible to infection, and children even more so!\n\n"
+ "If you carry a baby with you while fighting zombies, there is a chance it can become infected."));
nbt.setTag("pages", pages);
}
stack.setTagCompound(nbt);
}
@SideOnly(Side.CLIENT)
public static void registerModelMeshers() {
ItemModelMesher mesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();
for (Item item : ITEMS) mesher.register(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
}
private static void setItemName(Item item, String itemName) {
item.setUnlocalizedName(itemName);
item.setRegistryName(new ResourceLocation(MCA.MODID + ":" + itemName));
}
}
================================================
FILE: src/main/java/mca/core/minecraft/ProfessionsMCA.java
================================================
package mca.core.minecraft;
import mca.util.ItemStackCache;
import mca.util.ResourceLocationCache;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.village.MerchantRecipeList;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerCareer;
import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession;
import net.minecraftforge.registries.IForgeRegistry;
import java.util.Arrays;
import java.util.Random;
@GameRegistry.ObjectHolder("mca")
public class ProfessionsMCA {
public static final VillagerProfession guard = new VillagerProfession("mca:guard", "minecraft:textures/entity/villager/villager.png", "minecraft:textures/entity/zombie_villager/zombie_villager.png");
public static final VillagerProfession bandit = new VillagerProfession("mca:bandit", "minecraft:textures/entity/villager/villager.png", "minecraft:textures/entity/zombie_villager/zombie_villager.png");
public static final VillagerProfession child = new VillagerProfession("mca:child", "minecraft:textures/entity/villager/villager.png", "minecraft:textures/entity/zombie_villager/zombie_villager.png");
public static final VillagerProfession baker = new VillagerProfession("mca:baker", "minecraft:textures/entity/villager/farmer.png", "minecraft:textures/entity/zombie_villager/zombie_farmer.png");
public static final VillagerProfession miner = new VillagerProfession("mca:miner", "minecraft:textures/entity/villager/smith.png", "minecraft:textures/entity/zombie_villager/zombie_smith.png");
public static VillagerCareer guard_warrior;
public static VillagerCareer guard_archer;
public static VillagerCareer guard_hero;
public static VillagerCareer bandit_marauder;
public static VillagerCareer bandit_outlaw;
public static VillagerCareer bandit_pillager;
public static VillagerCareer child_child;
public static VillagerCareer baker_baker;
public static VillagerCareer miner_miner;
public static IForgeRegistry registry;
private static final VillagerProfession[] FORBIDDEN_RANDOM_PROFESSIONS = {
bandit, child
};
public static void registerCareers() {
guard_warrior = new VillagerCareer(guard, "warrior");
guard_archer = new VillagerCareer(guard, "archer");
guard_hero = new VillagerCareer(guard, "hero");
bandit_marauder = new VillagerCareer(bandit, "marauder");
bandit_outlaw = new VillagerCareer(bandit, "outlaw");
bandit_pillager = new VillagerCareer(bandit, "pillager");
child_child = new VillagerCareer(child, "child");
baker_baker = new VillagerCareer(baker, "baker");
miner_miner = new VillagerCareer(miner, "miner");
baker_baker.addTrade(1, new BakerTradesLvl1());
baker_baker.addTrade(2, new BakerTradesLvl2());
baker_baker.addTrade(3, new BakerTradesLvl3());
miner_miner.addTrade(1, new MinerTradesLvl1());
miner_miner.addTrade(2, new MinerTradesLvl2());
miner_miner.addTrade(3, new MinerTradesLvl3());
}
public static ItemStack getDefaultHeldItem(VillagerProfession profession, VillagerCareer career) {
if (profession == ProfessionsMCA.guard) return career == ProfessionsMCA.guard_archer ? ItemStackCache.get(Items.BOW) : ItemStackCache.get(Items.IRON_SWORD);
else if (profession == ProfessionsMCA.bandit) return ItemStackCache.get(Items.IRON_SWORD);
return ItemStack.EMPTY;
}
public static VillagerProfession randomProfession() {
ResourceLocation resource = null;
while (resource == null || resource.getResourcePath().contains("nitwit") || inForbiddenProfessions(registry.getValue(resource))) {
int i = new Random().nextInt(registry.getKeys().size() - 1);
resource = (ResourceLocation)registry.getKeys().toArray()[i];
}
return registry.getValue(resource);
}
@Mod.EventBusSubscriber(modid = "mca")
public static class RegistrationHandler {
/**
* Register this mod's {@link VillagerProfession}s.
*
* @param event The event
*/
@SubscribeEvent
public static void onEvent(final RegistryEvent.Register event) {
registry = event.getRegistry();
registry.register(guard);
registry.register(bandit);
registry.register(child);
registry.register(baker);
registry.register(miner);
}
}
public static class BakerTradesLvl1 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Items.WHEAT, 6)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.MILK_BUCKET, 1), new ItemStack(Items.BREAD, 2)));
}
}
public static class BakerTradesLvl2 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 2), new ItemStack(Items.EGG, 12)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.SUGAR, 2), new ItemStack(Items.CAKE, 1)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.STONE_HOE, 1), new ItemStack(Items.WHEAT, 10)));
}
}
public static class BakerTradesLvl3 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Items.CAKE, 1), new ItemStack(Items.EMERALD, 5)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 2), new ItemStack(Items.BREAD, 4)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 3), new ItemStack(Items.COOKIE, 6)));
recipeList.add(new MerchantRecipe(new ItemStack(Blocks.PUMPKIN, 1), new ItemStack(Items.PUMPKIN_PIE, 1)));
}
}
public static class MinerTradesLvl1 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Blocks.COBBLESTONE, 8), new ItemStack(Blocks.STONE, 4)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Blocks.TORCH, 8)));
}
}
public static class MinerTradesLvl2 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Items.GOLD_INGOT, 3), new ItemStack(Items.EMERALD, 2)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Items.COAL, 3)));
}
}
public static class MinerTradesLvl3 implements EntityVillager.ITradeList {
@Override
public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {
recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 4), new ItemStack(Items.IRON_PICKAXE, 1)));
recipeList.add(new MerchantRecipe(new ItemStack(Blocks.EMERALD_BLOCK, 1), new ItemStack(Items.DIAMOND_PICKAXE, 1)));
recipeList.add(new MerchantRecipe(new ItemStack(Items.IRON_INGOT, 8), new ItemStack(Items.DIAMOND, 1)));
}
}
private static boolean inForbiddenProfessions(VillagerProfession profIn) {
for (VillagerProfession profession : FORBIDDEN_RANDOM_PROFESSIONS) {
if (profession == profIn) {
return true;
}
}
return false;
}
}
================================================
FILE: src/main/java/mca/core/minecraft/RoseGoldOreGenerator.java
================================================
package mca.core.minecraft;
import mca.core.MCA;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraftforge.fml.common.IWorldGenerator;
import java.util.Random;
public final class RoseGoldOreGenerator implements IWorldGenerator {
public RoseGoldOreGenerator() {
}
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
if (world.provider.getDimension() == 0) generateSurface(world, random, chunkX * 16, chunkZ * 16);
}
private void generateSurface(World world, Random random, int x, int z) {
this.addOreSpawn(BlocksMCA.ROSE_GOLD_ORE, world, random, x, z, 16, 16, 6, 5);
}
public void addOreSpawn(Block block, World world, Random random, int blockPosX, int blockPosZ, int maxX, int maxZ, int maxVeinSize, int chancesToSpawn) {
if (block == BlocksMCA.ROSE_GOLD_ORE && !MCA.getConfig().allowRoseGoldGeneration) block = Blocks.STONE;
int range = 25;
for (int x = 0; x < chancesToSpawn; x++) {
int posX = blockPosX + random.nextInt(maxX);
int posY = 12 + random.nextInt(range);
int posZ = blockPosZ + random.nextInt(maxZ);
(new WorldGenMinable(block.getDefaultState(), maxVeinSize)).generate(world, random, new BlockPos(posX, posY, posZ));
}
}
}
================================================
FILE: src/main/java/mca/core/minecraft/SoundsMCA.java
================================================
package mca.core.minecraft;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.registries.IForgeRegistry;
public final class SoundsMCA {
private static final ResourceLocation loc_reaper_scythe_out = new ResourceLocation("mca:reaper.scythe.out");
public static final SoundEvent reaper_scythe_out = new SoundEvent(loc_reaper_scythe_out);
private static final ResourceLocation loc_reaper_scythe_swing = new ResourceLocation("mca:reaper.scythe.swing");
public static final SoundEvent reaper_scythe_swing = new SoundEvent(loc_reaper_scythe_swing);
private static final ResourceLocation loc_reaper_idle = new ResourceLocation("mca:reaper.idle");
public static final SoundEvent reaper_idle = new SoundEvent(loc_reaper_idle);
private static final ResourceLocation loc_reaper_death = new ResourceLocation("mca:reaper.death");
public static final SoundEvent reaper_death = new SoundEvent(loc_reaper_death);
private static final ResourceLocation loc_reaper_block = new ResourceLocation("mca:reaper.block");
public static final SoundEvent reaper_block = new SoundEvent(loc_reaper_block);
private static final ResourceLocation loc_reaper_summon = new ResourceLocation("mca:reaper.summon");
public static final SoundEvent reaper_summon = new SoundEvent(loc_reaper_summon);
public static void register(RegistryEvent.Register event) {
IForgeRegistry registry = event.getRegistry();
reaper_scythe_out.setRegistryName(loc_reaper_scythe_out);
reaper_scythe_swing.setRegistryName(loc_reaper_scythe_swing);
reaper_idle.setRegistryName(loc_reaper_idle);
reaper_death.setRegistryName(loc_reaper_death);
reaper_block.setRegistryName(loc_reaper_block);
reaper_summon.setRegistryName(loc_reaper_summon);
registry.register(reaper_scythe_out);
registry.register(reaper_scythe_swing);
registry.register(reaper_idle);
registry.register(reaper_death);
registry.register(reaper_block);
registry.register(reaper_summon);
}
}
================================================
FILE: src/main/java/mca/core/minecraft/VillageHelper.java
================================================
package mca.core.minecraft;
import com.google.common.base.Optional;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.village.Village;
import net.minecraft.world.World;
import java.util.List;
public class VillageHelper {
public static void tick(World world) {
world.getVillageCollection().getVillageList().forEach(v -> spawnGuards(world, v));
}
public static void forceSpawnGuards(EntityPlayerMP player) {
Village nearestVillage = player.world.getVillageCollection().getNearestVillage(player.getPosition(), 100);
spawnGuards(player.world, nearestVillage);
}
public static void forceRaid(EntityPlayerMP player) {
Village nearestVillage = player.world.getVillageCollection().getNearestVillage(player.getPosition(), 100);
startRaid(player.world, nearestVillage);
}
private static void spawnGuards(World world, Village village) {
int guardCapacity = village.getNumVillagers() / MCA.getConfig().guardSpawnRate;
int guards = 0;
// Grab all villagers in the area
List list = world.getEntitiesWithinAABB(EntityVillagerMCA.class,
new AxisAlignedBB((double) (village.getCenter().getX() - village.getVillageRadius()),
(double) (village.getCenter().getY() - 4),
(double) (village.getCenter().getZ() - village.getVillageRadius()),
(double) (village.getCenter().getX() + village.getVillageRadius()),
(double) (village.getCenter().getY() + 4),
(double) (village.getCenter().getZ() + village.getVillageRadius())));
// Count up the guards
for (EntityVillagerMCA villager : list) {
if (villager.getProfessionForge().getRegistryName().equals(ProfessionsMCA.guard.getRegistryName())) guards++;
}
// Spawn a new guard if we don't have enough, up to 10
if (guards < guardCapacity && guards < 10) {
Vec3d spawnPos = findRandomSpawnPos(world, village, village.getCenter(), 2, 4, 2);
if (spawnPos != null) {
EntityVillagerMCA guard = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.guard), Optional.absent());
guard.setPosition(spawnPos.x + 0.5D, spawnPos.y + 1.0D, spawnPos.z + 0.5D);
guard.finalizeMobSpawn(world.getDifficultyForLocation(guard.getPos()), null, false);
world.spawnEntity(guard);
}
}
}
private static void startRaid(World world, Village village) {
int banditsToSpawn = world.rand.nextInt(5) + 1;
while (banditsToSpawn > 0) {
EntityVillagerMCA bandit = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.bandit), Optional.absent());
BlockPos spawnLocation = village.getCenter();
bandit.setPosition(spawnLocation.getX(), spawnLocation.getY(), spawnLocation.getZ());
world.spawnEntity(bandit);
banditsToSpawn--;
}
}
private static Vec3d findRandomSpawnPos(World world, Village village, BlockPos pos, int x, int y, int z) {
for (int i = 0; i < 10; ++i) {
BlockPos blockpos = pos.add(world.rand.nextInt(16) - 8, world.rand.nextInt(6) - 3, world.rand.nextInt(16) - 8);
if (village.isBlockPosWithinSqVillageRadius(blockpos) && isAreaClearAround(world, new BlockPos(x, y, z), blockpos))
return new Vec3d((double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ());
}
return null;
}
private static boolean isAreaClearAround(World world, BlockPos blockSize, BlockPos blockLocation) {
if (!world.getBlockState(blockLocation.down()).isTopSolid()) return false;
int i = blockLocation.getX() - blockSize.getX() / 2;
int j = blockLocation.getZ() - blockSize.getZ() / 2;
for (int k = i; k < i + blockSize.getX(); ++k) {
for (int l = blockLocation.getY(); l < blockLocation.getY() + blockSize.getY(); ++l) {
for (int i1 = j; i1 < j + blockSize.getZ(); ++i1) {
if (world.getBlockState(new BlockPos(k, l, i1)).isNormalCube()) {
return false;
}
}
}
}
return true;
}
}
================================================
FILE: src/main/java/mca/core/minecraft/WorldEventListenerMCA.java
================================================
package mca.core.minecraft;
import mca.core.forge.NetMCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import javax.annotation.Nullable;
public class WorldEventListenerMCA implements IWorldEventListener {
public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {
}
public void notifyLightSet(BlockPos pos) {
}
public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {
}
public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch) {
}
public void playRecord(SoundEvent soundIn, BlockPos pos) {
}
public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int... parameters) {
}
public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... parameters) {
}
public void onEntityAdded(Entity entityIn) {
// Ask the server to send the villager's career ID when it is loaded into the world client-side
if (entityIn instanceof EntityVillagerMCA) {
// Career ID is not data managed, but we depend on it to display the proper profession for the villager alongside their name.
// The ID is randomized client-side with populateBuyingList(), which doesn't affect anything. This throws off the career ID that we send the client.
// To stop this, we default the career ID and level client-side to 1. This prevents populateBuyingList() from running and allows our career ID sent from the server to apply.
ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, (EntityVillagerMCA) entityIn, 1, EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);
ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, (EntityVillagerMCA) entityIn, 1, EntityVillagerMCA.VANILLA_CAREER_LEVEL_FIELD_INDEX);
NetMCA.INSTANCE.sendToServer(new NetMCA.CareerRequest(entityIn.getUniqueID()));
// The villager's inventory is also not synced to the client until it is opened in a Container.
// When the entity joins the client world, ask the server to send over the inventory data.
NetMCA.INSTANCE.sendToServer(new NetMCA.InventoryRequest(entityIn.getUniqueID()));
}
}
public void onEntityRemoved(Entity entityIn) {
}
public void broadcastSound(int soundID, BlockPos pos, int data) {
}
public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) {
}
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {
}
}
================================================
FILE: src/main/java/mca/entity/EntityGrimReaper.java
================================================
package mca.entity;
import mca.core.MCA;
import mca.core.minecraft.ItemsMCA;
import mca.core.minecraft.SoundsMCA;
import mca.enums.EnumReaperAttackState;
import mca.util.Util;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.*;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.BossInfo;
import net.minecraft.world.BossInfoServer;
import net.minecraft.world.World;
public class EntityGrimReaper extends EntityMob {
private static final DataParameter ATTACK_STATE = EntityDataManager.createKey(EntityGrimReaper.class, DataSerializers.VARINT);
private static final DataParameter STATE_TRANSITION_COOLDOWN = EntityDataManager.createKey(EntityGrimReaper.class, DataSerializers.VARINT);
private final BossInfoServer bossInfo = (BossInfoServer) (new BossInfoServer(this.getDisplayName(), BossInfo.Color.PURPLE, BossInfo.Overlay.PROGRESS)).setDarkenSky(true);
private EntityAINearestAttackableTarget aiNearestAttackableTarget = new EntityAINearestAttackableTarget(this, EntityPlayer.class, true);
private int healingCooldown;
private int timesHealed;
private float floatingTicks;
public EntityGrimReaper(World world) {
super(world);
setSize(1.0F, 2.6F);
this.experienceValue = 100;
this.tasks.addTask(1, new EntityAISwimming(this));
this.tasks.addTask(4, new EntityAIWander(this, 1.0D));
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(6, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0]));
this.targetTasks.addTask(2, aiNearestAttackableTarget);
}
@Override
protected final void applyEntityAttributes() {
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30F);
this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(12.5F);
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(225.0F);
}
@Override
protected void dropFewItems(boolean hitByPlayer, int lootingLvl) {
dropItem(ItemsMCA.STAFF_OF_LIFE, 1);
}
@Override
protected void entityInit() {
super.entityInit();
this.dataManager.register(ATTACK_STATE, 0);
this.dataManager.register(STATE_TRANSITION_COOLDOWN, 0);
}
public EnumReaperAttackState getAttackState() {
return EnumReaperAttackState.fromId(this.dataManager.get(ATTACK_STATE));
}
public void setAttackState(EnumReaperAttackState state) {
// Only update if needed so that sounds only play once.
if (this.dataManager.get(ATTACK_STATE) != state.getId()) {
this.dataManager.set(ATTACK_STATE, state.getId());
switch (state) {
case PRE:
this.playSound(SoundsMCA.reaper_scythe_out, 1.0F, 1.0F);
break;
case POST:
this.playSound(SoundsMCA.reaper_scythe_swing, 1.0F, 1.0F);
break;
}
}
}
public boolean hasEntityToAttack() {
return this.getAttackTarget() != null;
}
@Override
public void onStruckByLightning(EntityLightningBolt entity) {
return;
}
@Override
public boolean attackEntityFrom(DamageSource source, float damage) {
bossInfo.setPercent(this.getHealth() / this.getMaxHealth());
// Ignore wall damage and fire damage.
if (source == DamageSource.IN_WALL || source == DamageSource.ON_FIRE || source.isExplosion() || source == DamageSource.IN_FIRE) {
// Teleport out of any walls we may end up in.
if (source == DamageSource.IN_WALL) {
teleportTo(this.posX, this.posY + 3, this.posZ);
}
return false;
}
// Ignore damage when blocking, and teleport behind the player when they attempt to block.
else if (!world.isRemote && this.getAttackState() == EnumReaperAttackState.BLOCK && source.getImmediateSource() instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) source.getImmediateSource();
double deltaX = this.posX - player.posX;
double deltaZ = this.posZ - player.posZ;
this.playSound(SoundsMCA.reaper_block, 1.0F, 1.0F);
teleportTo(player.posX - (deltaX * 2), player.posY + 2, this.posZ - (deltaZ * 2));
setStateTransitionCooldown(0);
return false;
}
// Randomly portal behind the player who just attacked.
else if (!world.isRemote && source.getImmediateSource() instanceof EntityPlayer && rand.nextFloat() >= 0.30F) {
EntityPlayer player = (EntityPlayer) source.getImmediateSource();
double deltaX = this.posX - player.posX;
double deltaZ = this.posZ - player.posZ;
teleportTo(player.posX - (deltaX * 2), player.posY + 2, this.posZ - (deltaZ * 2));
}
// Teleport behind the player who fired an arrow and ignore its damage.
else if (source.getImmediateSource() instanceof EntityArrow) {
EntityArrow arrow = (EntityArrow) source.getImmediateSource();
if (arrow.shootingEntity instanceof EntityPlayer && getAttackState() != EnumReaperAttackState.REST) {
EntityPlayer player = (EntityPlayer) arrow.shootingEntity;
double newX = player.posX + rand.nextFloat() >= 0.50F ? 2 : -2;
double newZ = player.posZ + rand.nextFloat() >= 0.50F ? 2 : -2;
teleportTo(newX, player.posY, newZ);
}
arrow.setDead();
return false;
}
// Still take damage when healing, but reduced by a third.
else if (this.getAttackState() == EnumReaperAttackState.REST) {
damage /= 3;
}
super.attackEntityFrom(source, damage);
if (!world.isRemote && this.getHealth() <= (this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue() / 2) && healingCooldown == 0) {
setAttackState(EnumReaperAttackState.REST);
healingCooldown = 4200; // 3 minutes 30 seconds
teleportTo(this.posX, this.posY + 8, this.posZ);
setStateTransitionCooldown(1200); // 1 minute
}
return true;
}
protected void attackEntity(Entity entity, float damage) {
EntityLivingBase entityToAttack = this.getAttackTarget();
if (entityToAttack == null) return;
// Set attack state to post attack.
// If we're blocking, we will teleport away instead of attacking to prevent an unfair attack.
// Attacking us WHILE we're blocking will cause us to attack, however.
if (this.getDistance(entityToAttack) <= 0.8D && getAttackState() == EnumReaperAttackState.PRE) {
if (getAttackState() == EnumReaperAttackState.BLOCK) {
int rX = this.getRNG().nextInt(10);
int rZ = this.getRNG().nextInt(10);
teleportTo(this.posX + 5 + rX, this.posY, this.posZ + rZ);
} else {
entity.attackEntityFrom(DamageSource.causeMobDamage(this), this.world.getDifficulty().getDifficultyId() * 5.75F);
if (entity instanceof EntityLivingBase) {
((EntityLivingBase) entity).addPotionEffect(new PotionEffect(MobEffects.WITHER, this.world.getDifficulty().getDifficultyId() * 20, 1));
}
setAttackState(EnumReaperAttackState.POST);
setStateTransitionCooldown(10); // For preventing immediate return to the PRE or IDLE stage. Ticked down in onUpdate()
}
}
// Check if we're waiting for cooldown from the last attack.
if (getStateTransitionCooldown() == 0) {
// Within 3 blocks from the target, ready the scythe
if (getDistance(entityToAttack) <= 3.5D) {
// Check to see if the player's blocking, then teleport behind them.
// Also randomly swap their selected item with something else in the hotbar and apply blindness.
if (entityToAttack instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) entityToAttack;
if (player.isActiveItemStackBlocking()) {
double dX = this.posX - player.posX;
double dZ = this.posZ - player.posZ;
teleportTo(player.posX - (dX * 2), player.posY + 2, this.posZ - (dZ * 2));
if (!world.isRemote && rand.nextFloat() >= 0.20F) {
int currentItem = player.inventory.currentItem;
int randomItem = rand.nextInt(InventoryPlayer.getHotbarSize());
ItemStack currentItemStack = player.inventory.mainInventory.get(currentItem);
ItemStack randomItemStack = player.inventory.mainInventory.get(randomItem);
player.inventory.mainInventory.set(currentItem, randomItemStack);
player.inventory.mainInventory.set(randomItem, currentItemStack);
player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, this.world.getDifficulty().getDifficultyId() * 40, 1));
}
} else // If the player is not blocking, ready the scythe, or randomly block their attack.
{
// Don't block if we've already committed to an attack.
if (rand.nextFloat() >= 40.0F && getAttackState() != EnumReaperAttackState.PRE) {
setStateTransitionCooldown(20);
setAttackState(EnumReaperAttackState.BLOCK);
} else {
setAttackState(EnumReaperAttackState.PRE);
setStateTransitionCooldown(20);
}
}
}
} else // Reset the attacking state when we're more than 3 blocks away.
{
setAttackState(EnumReaperAttackState.IDLE);
}
}
}
protected Entity findPlayerToAttack() {
return world.getClosestPlayerToEntity(this, 48.0D);
}
@Override
public int getTalkInterval() {
return 300;
}
@Override
protected SoundEvent getAmbientSound() {
return SoundsMCA.reaper_idle;
}
@Override
protected SoundEvent getDeathSound() {
return SoundsMCA.reaper_death;
}
@Override
protected SoundEvent getHurtSound(DamageSource source) {
return SoundEvents.ENTITY_WITHER_HURT;
}
@Override
public void onUpdate() {
super.onUpdate();
extinguish(); // No fire.
if (!MCA.getConfig().allowGrimReaper) {
setDead();
}
EntityLivingBase entityToAttack = this.getAttackTarget();
if (entityToAttack != null && getAttackState() != EnumReaperAttackState.REST) {
attackEntity(entityToAttack, 5.0F);
this.getMoveHelper().setMoveTo(entityToAttack.posX, entityToAttack.posY, entityToAttack.posZ, 6.0F);
}
// Increment floating ticks on the client when resting.
if (world.isRemote && getAttackState() == EnumReaperAttackState.REST) {
floatingTicks += 0.1F;
}
// Increase health when resting and check to stop rest state.
// Runs on common to spawn lightning.
if (getAttackState() == EnumReaperAttackState.REST) {
if (!world.isRemote && getStateTransitionCooldown() == 1) {
setAttackState(EnumReaperAttackState.IDLE);
timesHealed++;
} else if (!world.isRemote && getStateTransitionCooldown() % 100 == 0) {
this.setHealth(this.getHealth() + MathHelper.clamp(10.5F - (timesHealed * 3.5F), 3.0F, 10.5F));
// Let's have a light show.
int dX = rand.nextInt(8) + 4 * rand.nextFloat() >= 0.50F ? 1 : -1;
int dZ = rand.nextInt(8) + 4 * rand.nextFloat() >= 0.50F ? 1 : -1;
int y = Util.getSpawnSafeTopLevel(world, (int) posX + dX, 256, (int) posZ + dZ);
EntityLightningBolt bolt = new EntityLightningBolt(world, dX, y, dZ, false);
world.addWeatherEffect(bolt);
// Also spawn a random skeleton or zombie.
if (!world.isRemote) {
EntityMob mob = rand.nextFloat() >= 0.50F ? new EntityZombie(world) : new EntitySkeleton(world);
mob.setPosition(posX + dX + 4, y, posZ + dZ + 4);
if (mob instanceof EntitySkeleton) {
mob.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW));
}
world.spawnEntity(mob);
}
}
}
// Prevent flying off into oblivion on death...
if (this.getHealth() <= 0.0F) {
motionX = 0;
motionY = 0;
motionZ = 0;
return;
}
// Stop at our current position if resting
if (getAttackState() == EnumReaperAttackState.REST) {
motionX = 0;
motionY = 0;
motionZ = 0;
}
// Logic for flying.
fallDistance = 0.0F;
if (motionY > 0) {
motionY = motionY * 1.04F;
} else {
double yMod = Math.sqrt((motionX * motionX) + (motionZ * motionZ));
motionY = motionY * 0.6F + yMod * 0.3F;
}
// Tick down cooldowns.
if (getStateTransitionCooldown() > 0) {
setStateTransitionCooldown(getStateTransitionCooldown() - 1);
}
if (healingCooldown > 0) {
healingCooldown--;
}
// See if our entity to attack has died at any point.
if (entityToAttack != null && entityToAttack.isDead) {
this.setAttackTarget(null);
setAttackState(EnumReaperAttackState.IDLE);
}
// Move towards target if we're not resting
if (entityToAttack != null && getAttackState() != EnumReaperAttackState.REST) {
// If we have a creature to attack, we need to move downwards if we're above it, and vice-versa.
double sqDistanceTo = Math.sqrt(Math.pow(entityToAttack.posX - posX, 2) + Math.pow(entityToAttack.posZ - posZ, 2));
float moveAmount = 0.0F;
if (sqDistanceTo < 8F) {
moveAmount = MathHelper.clamp(((8F - (float) sqDistanceTo) / 8F) * 4F, 0, 2.5F);
}
if (entityToAttack.posY + 0.2F < posY) {
motionY = motionY - 0.05F * moveAmount;
}
if (entityToAttack.posY - 0.5F > posY) {
motionY = motionY + 0.01F * moveAmount;
}
}
}
@Override
public void onDeath(DamageSource source) {
super.onDeath(source);
}
@Override
public String getName() {
return "Grim Reaper";
}
@Override
protected boolean canDespawn() {
return true;
}
public int getStateTransitionCooldown() {
return this.dataManager.get(STATE_TRANSITION_COOLDOWN);
}
public void setStateTransitionCooldown(int value) {
this.dataManager.set(STATE_TRANSITION_COOLDOWN, value);
}
public float getFloatingTicks() {
return floatingTicks;
}
private void teleportTo(double x, double y, double z) {
if (!world.isRemote) {
this.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 2.0F, 1.0F);
this.setPosition(x, y, z);
this.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 2.0F, 1.0F);
}
}
@Override
public boolean isNonBoss() {
return false;
}
/**
* Add the given player to the list of players tracking this entity. For instance, a player may track a boss in
* order to view its associated boss bar.
*/
@Override
public void addTrackingPlayer(EntityPlayerMP player) {
super.addTrackingPlayer(player);
this.bossInfo.addPlayer(player);
}
/**
* Removes the given player from the list of players tracking this entity. See {@link Entity#addTrackingPlayer} for
* more information on tracking.
*/
@Override
public void removeTrackingPlayer(EntityPlayerMP player) {
super.removeTrackingPlayer(player);
this.bossInfo.removePlayer(player);
}
}
================================================
FILE: src/main/java/mca/entity/EntityVillagerMCA.java
================================================
package mca.entity;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import mca.api.API;
import mca.api.types.APIButton;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.forge.NetMCA;
import mca.core.minecraft.ItemsMCA;
import mca.core.minecraft.ProfessionsMCA;
import mca.entity.ai.*;
import mca.entity.data.ParentData;
import mca.entity.data.PlayerHistory;
import mca.entity.data.PlayerSaveData;
import mca.entity.data.SavedVillagers;
import mca.entity.inventory.InventoryMCA;
import mca.enums.*;
import mca.items.ItemSpecialCaseGift;
import mca.util.ItemStackCache;
import mca.util.ResourceLocationCache;
import mca.util.Util;
import net.minecraft.block.BlockBed;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.*;
import net.minecraft.entity.monster.EntityVex;
import net.minecraft.entity.monster.EntityVindicator;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.RegistryNamespaced;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.registry.VillagerRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import static net.minecraft.block.BlockBed.OCCUPIED;
import static net.minecraft.block.BlockBed.PART;
public class EntityVillagerMCA extends EntityVillager {
public static final int VANILLA_CAREER_ID_FIELD_INDEX = 13;
public static final int VANILLA_CAREER_LEVEL_FIELD_INDEX = 14;
public static final DataParameter VILLAGER_NAME = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);
public static final DataParameter TEXTURE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);
public static final DataParameter GENDER = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter GIRTH = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.FLOAT);
public static final DataParameter TALLNESS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.FLOAT);
public static final DataParameter PLAYER_HISTORY_MAP = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.COMPOUND_TAG);
public static final DataParameter MOVE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter SPOUSE_NAME = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);
public static final DataParameter> SPOUSE_UUID = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.OPTIONAL_UNIQUE_ID);
public static final DataParameter MARRIAGE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter IS_PROCREATING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
public static final DataParameter PARENTS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.COMPOUND_TAG);
public static final DataParameter IS_INFECTED = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
public static final DataParameter AGE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter ACTIVE_CHORE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter IS_SWINGING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
public static final DataParameter HAS_BABY = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
public static final DataParameter BABY_IS_MALE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
public static final DataParameter BABY_AGE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);
public static final DataParameter> CHORE_ASSIGNING_PLAYER = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.OPTIONAL_UNIQUE_ID);
public static final DataParameter BED_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);
public static final DataParameter WORKPLACE_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);
public static final DataParameter HANGOUT_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);
public static final DataParameter SLEEPING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);
private static final Predicate BANDIT_TARGET_SELECTOR = (v) -> v.getProfessionForge() != ProfessionsMCA.bandit && v.getProfessionForge() != ProfessionsMCA.child;
private static final Predicate GUARD_TARGET_SELECTOR = (v) -> v.getProfessionForge() == ProfessionsMCA.bandit;
public final InventoryMCA inventory;
public int babyAge = 0;
public UUID playerToFollowUUID = Constants.ZERO_UUID;
private BlockPos home = BlockPos.ORIGIN;
private int startingAge = 0;
private float swingProgressTicks;
public float renderOffsetX;
public float renderOffsetY;
public float renderOffsetZ;
public EntityVillagerMCA() {
super(null);
inventory = null;
}
public EntityVillagerMCA(World worldIn) {
super(worldIn);
inventory = new InventoryMCA(this);
}
public EntityVillagerMCA(World worldIn, Optional profession, Optional gender) {
this(worldIn);
if (!worldIn.isRemote) {
EnumGender eGender = gender.isPresent() ? gender.get() : EnumGender.getRandom();
set(GENDER, eGender.getId());
set(VILLAGER_NAME, API.getRandomName(eGender));
setProfession(profession.isPresent() ? profession.get() : ProfessionsMCA.randomProfession());
setVanillaCareer(getProfessionForge().getRandomCareer(worldIn.rand));
set(TEXTURE, API.getRandomSkin(this));
applySpecialAI();
}
}
@Override
protected void entityInit() {
super.entityInit();
this.dataManager.register(VILLAGER_NAME, "");
this.dataManager.register(TEXTURE, "");
this.dataManager.register(GENDER, EnumGender.MALE.getId());
this.dataManager.register(GIRTH, 0.0F);
this.dataManager.register(TALLNESS, 0.0F);
this.dataManager.register(PLAYER_HISTORY_MAP, new NBTTagCompound());
this.dataManager.register(MOVE_STATE, EnumMoveState.MOVE.getId());
this.dataManager.register(SPOUSE_NAME, "");
this.dataManager.register(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));
this.dataManager.register(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());
this.dataManager.register(IS_PROCREATING, false);
this.dataManager.register(PARENTS, new NBTTagCompound());
this.dataManager.register(IS_INFECTED, false);
this.dataManager.register(AGE_STATE, EnumAgeState.ADULT.getId());
this.dataManager.register(ACTIVE_CHORE, EnumChore.NONE.getId());
this.dataManager.register(IS_SWINGING, false);
this.dataManager.register(HAS_BABY, false);
this.dataManager.register(BABY_IS_MALE, false);
this.dataManager.register(BABY_AGE, 0);
this.dataManager.register(CHORE_ASSIGNING_PLAYER, Optional.of(Constants.ZERO_UUID));
this.dataManager.register(BED_POS, BlockPos.ORIGIN);
this.dataManager.register(WORKPLACE_POS, BlockPos.ORIGIN);
this.dataManager.register(HANGOUT_POS, BlockPos.ORIGIN);
this.dataManager.register(SLEEPING, false);
this.setSilent(false);
}
@Override
protected void applyEntityAttributes() {
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(MCA.getConfig().villagerMaxHealth);
this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(32.0D);
if (this.getHealth() <= MCA.getConfig().villagerMaxHealth) {
this.setHealth(MCA.getConfig().villagerMaxHealth);
}
}
public T get(DataParameter key) {
return this.dataManager.get(key);
}
public void set(DataParameter key, T value) {
this.dataManager.set(key, value);
}
@Override
public boolean attackEntityAsMob(@Nonnull Entity entityIn) {
super.attackEntityAsMob(entityIn);
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), this.getProfessionForge() == ProfessionsMCA.guard ? 9.0F : 2.0F);
}
@Override
public void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt);
set(VILLAGER_NAME, nbt.getString("name"));
set(GENDER, nbt.getInteger("gender"));
set(TEXTURE, nbt.getString("texture"));
set(GIRTH, nbt.getFloat("girth"));
set(TALLNESS, nbt.getFloat("tallness"));
set(PLAYER_HISTORY_MAP, nbt.getCompoundTag("playerHistoryMap"));
set(MOVE_STATE, nbt.getInteger("moveState"));
set(MARRIAGE_STATE, nbt.getInteger("marriageState"));
set(SPOUSE_UUID, Optional.of(nbt.getUniqueId("spouseUUID")));
set(SPOUSE_NAME, nbt.getString("spouseName"));
set(IS_PROCREATING, nbt.getBoolean("isProcreating"));
set(IS_INFECTED, nbt.getBoolean("infected"));
set(AGE_STATE, nbt.getInteger("ageState"));
set(ACTIVE_CHORE, nbt.getInteger("activeChore"));
set(CHORE_ASSIGNING_PLAYER, Optional.of(nbt.getUniqueId("choreAssigningPlayer")));
set(HAS_BABY, nbt.getBoolean("hasBaby"));
set(BABY_IS_MALE, nbt.getBoolean("babyIsMale"));
set(PARENTS, nbt.getCompoundTag("parents"));
set(BED_POS, new BlockPos(nbt.getInteger("bedX"), nbt.getInteger("bedY"), nbt.getInteger("bedZ")));
set(HANGOUT_POS, new BlockPos(nbt.getInteger("hangoutX"), nbt.getInteger("hangoutY"), nbt.getInteger("hangoutZ")));
set(WORKPLACE_POS, new BlockPos(nbt.getInteger("workplaceX"), nbt.getInteger("workplaceY"), nbt.getInteger("workplaceZ")));
set(SLEEPING, nbt.getBoolean("sleeping"));
inventory.readInventoryFromNBT(nbt.getTagList("inventory", 10));
// Vanilla Age doesn't apply from the superclass call. Causes children to revert to the starting age on world reload.
this.startingAge = nbt.getInteger("startingAge");
setGrowingAge(nbt.getInteger("Age"));
this.home = new BlockPos(nbt.getDouble("homePositionX"), nbt.getDouble("homePositionY"), nbt.getDouble("homePositionZ"));
this.playerToFollowUUID = nbt.getUniqueId("playerToFollowUUID");
this.babyAge = nbt.getInteger("babyAge");
applySpecialAI();
}
@Override
public void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt);
nbt.setUniqueId("uuid", this.getUniqueID()); // for SavedVillagers
nbt.setString("name", get(VILLAGER_NAME));
nbt.setString("texture", get(TEXTURE));
nbt.setInteger("gender", get(GENDER));
nbt.setFloat("girth", get(GIRTH));
nbt.setFloat("tallness", get(TALLNESS));
nbt.setTag("playerHistoryMap", get(PLAYER_HISTORY_MAP));
nbt.setInteger("moveState", get(MOVE_STATE));
nbt.setInteger("marriageState", get(MARRIAGE_STATE));
nbt.setDouble("homePositionX", home.getX());
nbt.setDouble("homePositionY", home.getY());
nbt.setDouble("homePositionZ", home.getZ());
nbt.setUniqueId("playerToFollowUUID", playerToFollowUUID);
nbt.setUniqueId("spouseUUID", get(SPOUSE_UUID).or(Constants.ZERO_UUID));
nbt.setString("spouseName", get(SPOUSE_NAME));
nbt.setBoolean("isProcreating", get(IS_PROCREATING));
nbt.setBoolean("infected", get(IS_INFECTED));
nbt.setInteger("ageState", get(AGE_STATE));
nbt.setInteger("startingAge", startingAge);
nbt.setInteger("activeChore", get(ACTIVE_CHORE));
nbt.setUniqueId("choreAssigningPlayer", get(CHORE_ASSIGNING_PLAYER).or(Constants.ZERO_UUID));
nbt.setTag("inventory", inventory.writeInventoryToNBT());
nbt.setInteger("babyAge", babyAge);
nbt.setTag("parents", get(PARENTS));
nbt.setInteger("bedX", get(BED_POS).getX());
nbt.setInteger("bedY", get(BED_POS).getY());
nbt.setInteger("bedZ", get(BED_POS).getZ());
nbt.setInteger("workplaceX", get(WORKPLACE_POS).getX());
nbt.setInteger("workplaceY", get(WORKPLACE_POS).getY());
nbt.setInteger("workplaceZ", get(WORKPLACE_POS).getZ());
nbt.setInteger("hangoutX", get(HANGOUT_POS).getX());
nbt.setInteger("hangoutY", get(HANGOUT_POS).getY());
nbt.setInteger("hangoutZ", get(HANGOUT_POS).getZ());
nbt.setBoolean("sleeping", get(SLEEPING));
}
@Override
protected void damageEntity(@Nonnull DamageSource damageSource, float damageAmount) {
// Guards take 50% less damage
if (getProfessionForge() == ProfessionsMCA.guard) {
damageAmount *= 0.50;
}
super.damageEntity(damageSource, damageAmount);
// Check for infection to apply. Does not affect guards.
if (MCA.getConfig().enableInfection && getProfessionForge() != ProfessionsMCA.guard && damageSource.getImmediateSource() instanceof EntityZombie && getRNG().nextFloat() < MCA.getConfig().infectionChance / 100) {
set(IS_INFECTED, true);
}
}
@Override
public void onUpdate() {
super.onUpdate();
updateSwinging();
updateSleeping();
if (this.isServerWorld()) {
onEachServerUpdate();
} else {
onEachClientUpdate();
}
}
@Override
protected SoundEvent getAmbientSound() {
return null;
}
@Override
protected SoundEvent getHurtSound(DamageSource damageSourceIn) {
return SoundEvents.ENTITY_GENERIC_HURT;
}
@Override
protected SoundEvent getDeathSound() {
return get(IS_INFECTED) ? SoundEvents.ENTITY_ZOMBIE_DEATH : null;
}
@Override
public boolean processInteract(EntityPlayer player, @Nonnull EnumHand hand) {
// No-op, handled by EventHooks
return true;
}
@Override
public void onDeath(@Nonnull DamageSource cause) {
if (!world.isRemote) {
if (MCA.getConfig().logVillagerDeaths) {
String causeName = cause.getImmediateSource() == null ? "Unknown" : cause.getImmediateSource().getName();
MCA.getLog().info("Villager death: " + get(VILLAGER_NAME) + ". Caused by: " + causeName + ". UUID: " + this.getUniqueID().toString());
}
//TODO: player history gets lsot on revive
//TODO: childp becomes to child on revive (needs verification)
inventory.dropAllItems();
inventory.clear(); //fixes issue #1227, dropAllItems() should clear, but it does not work
if (isMarried()) {
UUID spouseUUID = get(SPOUSE_UUID).or(Constants.ZERO_UUID);
Optional spouse = Util.getEntityByUUID(world, spouseUUID, EntityVillagerMCA.class);
PlayerSaveData playerSaveData = PlayerSaveData.getExisting(world, spouseUUID);
// Notify spouse of the death
if (spouse.isPresent()) {
spouse.get().endMarriage();
} else if (playerSaveData != null) {
playerSaveData.endMarriage();
EntityPlayer player = world.getPlayerEntityByUUID(spouseUUID);
if (player != null) {
player.sendMessage(new TextComponentString(Constants.Color.RED + MCA.getLocalizer().localize("notify.spousedied", get(VILLAGER_NAME), cause.getImmediateSource().getName())));
}
}
}
// Notify all parents of the death
ParentData parents = ParentData.fromNBT(get(PARENTS));
Arrays.stream(parents.getParentEntities(world))
.filter(e -> e instanceof EntityPlayer)
.forEach(e -> {
EntityPlayer player = (EntityPlayer) e;
player.sendMessage(new TextComponentString(Constants.Color.RED + MCA.getLocalizer().localize("notify.childdied", get(VILLAGER_NAME), cause.getImmediateSource().getName())));
});
SavedVillagers.get(world).save(this);
}
}
@Override
protected void onGrowingAdult() {
Entity[] parents = ParentData.fromNBT(get(PARENTS)).getParentEntities(world);
set(AGE_STATE, EnumAgeState.ADULT.getId());
Arrays.stream(parents).filter((e) -> e instanceof EntityPlayer).forEach((e) -> {
PlayerHistory history = getPlayerHistoryFor(e.getUniqueID());
history.setDialogueType(EnumDialogueType.ADULT);
e.sendMessage(new TextComponentString(MCA.getLocalizer().localize("notify.child.grownup", this.get(VILLAGER_NAME))));
});
// set profession away from child for villager children
if (getProfessionForge() == ProfessionsMCA.child) {
setProfession(ProfessionsMCA.randomProfession());
setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));
}
}
@Override
@Nonnull
public ITextComponent getDisplayName() {
// translate profession name
ITextComponent careerName = new TextComponentTranslation("entity.Villager." + getVanillaCareer().getName());
EnumAgeState age = EnumAgeState.byId(get(AGE_STATE));
String professionName = age != EnumAgeState.ADULT ? age.localizedName() : careerName.getUnformattedText();
String color = this.getProfessionForge() == ProfessionsMCA.bandit ? Constants.Color.RED : this.getProfessionForge() == ProfessionsMCA.guard ? Constants.Color.GREEN : "";
return new TextComponentString(String.format("%1$s%2$s%3$s (%4$s)", color, MCA.getConfig().villagerChatPrefix, get(VILLAGER_NAME), professionName));
}
@Override
@Nonnull
public String getCustomNameTag() {
return get(VILLAGER_NAME);
}
@Override
@Nonnull
public boolean hasCustomName() {
return true;
}
@Override
public void swingArm(EnumHand hand) {
this.setActiveHand(EnumHand.MAIN_HAND);
super.swingArm(EnumHand.MAIN_HAND);
if (!get(IS_SWINGING) || swingProgressTicks >= 8 / 2 || swingProgressTicks < 0) {
swingProgressTicks = -1;
set(IS_SWINGING, true);
}
}
private void updateSwinging() {
if (get(IS_SWINGING)) {
swingProgressTicks++;
if (swingProgressTicks >= 8) {
swingProgressTicks = 0;
set(IS_SWINGING, false);
}
} else {
swingProgressTicks = 0;
}
swingProgress = swingProgressTicks / (float) 8;
}
@Override
@Nonnull
public ItemStack getItemStackFromSlot(EntityEquipmentSlot slotIn) {
if (slotIn == EntityEquipmentSlot.MAINHAND) {
VillagerRegistry.VillagerProfession profession = getProfessionForge();
EnumChore chore = EnumChore.byId(get(ACTIVE_CHORE));
if (get(HAS_BABY)) {
return ItemStackCache.get(get(BABY_IS_MALE) ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL);
} else if (chore != EnumChore.NONE) {
return inventory.getBestItemOfType(chore.getToolType());
} else {
return ProfessionsMCA.getDefaultHeldItem(profession, getVanillaCareer());
}
} else {
return inventory.getBestArmorOfType(slotIn);
}
}
public void setStartingAge(int value) {
this.startingAge = value;
setGrowingAge(value);
}
public PlayerHistory getPlayerHistoryFor(UUID uuid) {
if (!get(PLAYER_HISTORY_MAP).hasKey(uuid.toString())) {
updatePlayerHistoryMap(PlayerHistory.getNew(this, uuid));
}
return PlayerHistory.fromNBT(this, uuid, get(PLAYER_HISTORY_MAP).getCompoundTag(uuid.toString()));
}
public void updatePlayerHistoryMap(PlayerHistory history) {
NBTTagCompound nbt = get(PLAYER_HISTORY_MAP);
nbt.setTag(history.getPlayerUUID().toString(), history.toNBT());
set(PLAYER_HISTORY_MAP, nbt);
this.dataManager.setDirty(PLAYER_HISTORY_MAP);
}
public void reset() {
set(PLAYER_HISTORY_MAP, new NBTTagCompound());
dataManager.setDirty(PLAYER_HISTORY_MAP);
setHealth(20.0F);
set(SPOUSE_NAME, "");
set(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));
set(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());
set(HAS_BABY, false);
}
public VillagerRegistry.VillagerCareer getVanillaCareer() {
return this.getProfessionForge().getCareer(ObfuscationReflectionHelper.getPrivateValue(EntityVillager.class, this, VANILLA_CAREER_ID_FIELD_INDEX));
}
public void setVanillaCareer(int careerId) {
ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, this, careerId, VANILLA_CAREER_ID_FIELD_INDEX);
}
private void setSizeForAge() {
EnumAgeState age = EnumAgeState.byId(get(AGE_STATE));
this.setSize(age.getWidth(), age.getHeight());
this.setScale(1.0F); // trigger rebuild of the bounding box
}
private void toggleMount(EntityPlayerMP player) {
if (getRidingEntity() != null) {
dismountRidingEntity();
} else {
try {
List horses = world.getEntities(EntityHorse.class, h -> (h.isHorseSaddled() && !h.isBeingRidden() && h.getDistance(this) < 3.0D));
startRiding(horses.stream().min(Comparator.comparingDouble(this::getDistance)).get(), true);
getNavigator().clearPath();
} catch (NoSuchElementException e) {
say(Optional.of(player), "interaction.ridehorse.fail.notnearby");
}
}
}
private void goHome(EntityPlayerMP player) {
if (home.equals(Vec3d.ZERO)) {
say(Optional.of(player), "interaction.gohome.fail");
} else {
say(Optional.of(player), "interaction.gohome.success");
if (!getNavigator().setPath(getNavigator().getPathToXYZ(home.getX(), home.getY(), home.getZ()), 1.0D)) {
attemptTeleport(home.getX(), home.getY(), home.getZ());
}
}
}
public BlockPos getWorkplace() {
return get(WORKPLACE_POS);
}
public BlockPos getHangout() {
return get(HANGOUT_POS);
}
/**
* Forces the villager's home to be set to their position. No checks for safety are made.
* This is used on overwriting the original villager.
*/
public void forcePositionAsHome() {
this.home = this.getPosition();
}
private void setHome(EntityPlayerMP player) {
if (attemptTeleport(player.posX, player.posY, player.posZ)) {
say(Optional.of(player), "interaction.sethome.success");
this.home = player.getPosition();
this.setHomePosAndDistance(this.home, 32);
BlockPos bed = searchBed();
if (bed != null) {
set(BED_POS, bed);
}
} else {
say(Optional.of(player), "interaction.sethome.fail");
}
}
public void setWorkplace(EntityPlayerMP player) {
say(Optional.of(player), "interaction.setworkplace.success");
set(WORKPLACE_POS, player.getPosition());
}
public void setHangout(EntityPlayerMP player) {
say(Optional.of(player), "interaction.sethangout.success");
set(HANGOUT_POS, player.getPosition());
}
public void say(Optional player, String phraseId, @Nullable String... params) {
ArrayList paramsList = new ArrayList<>();
if (params != null) Collections.addAll(paramsList, params);
if (player.isPresent()) {
EntityPlayer thePlayer = player.get();
// Provide player as the first param, always
paramsList.add(0, thePlayer.getName());
// Infected villagers do not speak.
if (get(IS_INFECTED)) {
thePlayer.sendMessage(new TextComponentString(getDisplayName().getFormattedText() + ": " + "???"));
this.playSound(SoundEvents.ENTITY_ZOMBIE_AMBIENT, 0.5F, rand.nextFloat() + 0.5F);
} else {
String dialogueType = getPlayerHistoryFor(player.get().getUniqueID()).getDialogueType().getId();
String phrase = MCA.getLocalizer().localize(dialogueType + "." + phraseId, paramsList);
thePlayer.sendMessage(new TextComponentString(String.format("%1$s: %2$s", getDisplayName().getFormattedText(), phrase)));
}
} else {
MCA.getLog().warn(new Throwable("Say called on player that is not present!"));
}
}
public boolean isMarried() {
return !get(SPOUSE_UUID).or(Constants.ZERO_UUID).equals(Constants.ZERO_UUID);
}
public boolean isMarriedTo(UUID uuid) {
return get(SPOUSE_UUID).or(Constants.ZERO_UUID).equals(uuid);
}
public void marry(EntityPlayer player) {
set(SPOUSE_UUID, Optional.of(player.getUniqueID()));
set(SPOUSE_NAME, player.getName());
set(MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());
}
private void endMarriage() {
set(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));
set(SPOUSE_NAME, "");
set(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());
}
private void handleInteraction(EntityPlayerMP player, PlayerHistory history, APIButton button) {
float successChance = 0.85F;
int heartsBoost = button.getConstraints().contains(EnumConstraint.ADULTS) ? 15 : 5;
String interactionName = button.getIdentifier().replace("gui.button.", "");
successChance -= button.getConstraints().contains(EnumConstraint.ADULTS) ? 0.25F : 0.0F;
successChance += (history.getHearts() / 10.0D) * 0.025F;
if (MCA.getConfig().enableDiminishingReturns) successChance -= history.getInteractionFatigue() * 0.05F;
boolean succeeded = rand.nextFloat() < successChance;
if (MCA.getConfig().enableDiminishingReturns && succeeded)
heartsBoost -= history.getInteractionFatigue() * 0.05F;
history.changeInteractionFatigue(1);
history.changeHearts(succeeded ? heartsBoost : (heartsBoost * -1));
String responseId = String.format("%s.%s", interactionName, succeeded ? "success" : "fail");
say(Optional.of(player), responseId);
}
public void handleButtonClick(EntityPlayerMP player, String guiKey, String buttonId) {
PlayerHistory history = getPlayerHistoryFor(player.getUniqueID());
java.util.Optional button = API.getButtonById(guiKey, buttonId);
if (!button.isPresent()) {
MCA.getLog().warn("Button not found for key and ID: " + guiKey + ", " + buttonId);
} else if (button.get().isInteraction()) handleInteraction(player, history, button.get());
switch (buttonId) {
case "gui.button.move":
set(MOVE_STATE, EnumMoveState.MOVE.getId());
this.playerToFollowUUID = Constants.ZERO_UUID;
break;
case "gui.button.stay":
set(MOVE_STATE, EnumMoveState.STAY.getId());
break;
case "gui.button.follow":
set(MOVE_STATE, EnumMoveState.FOLLOW.getId());
this.playerToFollowUUID = player.getUniqueID();
stopChore();
break;
case "gui.button.ridehorse":
toggleMount(player);
break;
case "gui.button.sethome":
setHome(player);
break;
case "gui.button.gohome":
goHome(player);
break;
case "gui.button.setworkplace":
setWorkplace(player);
break;
case "gui.button.sethangout":
setHangout(player);
break;
case "gui.button.trade":
if (MCA.getConfig().allowTrading) {
setCustomer(player);
player.displayVillagerTradeGui(this);
} else {
player.sendMessage(new TextComponentString(MCA.getLocalizer().localize("info.trading.disabled")));
}
break;
case "gui.button.inventory":
player.openGui(MCA.getInstance(), Constants.GUI_ID_INVENTORY, player.world, this.getEntityId(), 0, 0);
break;
case "gui.button.gift":
ItemStack stack = player.inventory.getStackInSlot(player.inventory.currentItem);
int giftValue = API.getGiftValueFromStack(stack);
if (!handleSpecialCaseGift(player, stack)) {
if (stack.getItem() == Items.GOLDEN_APPLE) set(IS_INFECTED, false);
else {
history.changeHearts(giftValue);
say(Optional.of(player), API.getResponseForGift(stack));
}
}
if (giftValue > 0) {
player.inventory.decrStackSize(player.inventory.currentItem, 1);
}
break;
case "gui.button.procreate":
if (PlayerSaveData.get(player).isBabyPresent())
say(Optional.of(player), "interaction.procreate.fail.hasbaby");
else if (history.getHearts() < 100) say(Optional.of(player), "interaction.procreate.fail.lowhearts");
else {
EntityAITasks.EntityAITaskEntry task = tasks.taskEntries.stream().filter((ai) -> ai.action instanceof EntityAIProcreate).findFirst().orElse(null);
if (task != null) {
((EntityAIProcreate) task.action).procreateTimer = 20 * 3; // 3 seconds
set(IS_PROCREATING, true);
}
}
break;
case "gui.button.infected":
set(IS_INFECTED, !get(IS_INFECTED));
break;
case "gui.button.texture.randomize":
set(TEXTURE, API.getRandomSkin(this));
break;
case "gui.button.profession.randomize":
setProfession(ProfessionsMCA.randomProfession());
setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));
break;
case "gui.button.gender":
EnumGender gender = EnumGender.byId(get(GENDER));
if (gender == EnumGender.MALE) {
set(GENDER, EnumGender.FEMALE.getId());
} else {
set(GENDER, EnumGender.MALE.getId());
}
// intentional fall-through here
case "gui.button.texture":
set(TEXTURE, API.getRandomSkin(this));
break;
case "gui.button.random":
set(VILLAGER_NAME, API.getRandomName(EnumGender.byId(get(GENDER))));
break;
case "gui.button.profession":
RegistryNamespaced registry = ObfuscationReflectionHelper.getPrivateValue(VillagerRegistry.class, VillagerRegistry.instance(), "REGISTRY");
setProfession(ProfessionsMCA.randomProfession());
setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));
applySpecialAI();
break;
case "gui.button.prospecting":
startChore(EnumChore.PROSPECT, player);
break;
case "gui.button.hunting":
startChore(EnumChore.HUNT, player);
break;
case "gui.button.fishing":
startChore(EnumChore.FISH, player);
break;
case "gui.button.chopping":
startChore(EnumChore.CHOP, player);
break;
case "gui.button.harvesting":
startChore(EnumChore.HARVEST, player);
break;
case "gui.button.stopworking":
stopChore();
break;
}
}
private boolean handleSpecialCaseGift(EntityPlayer player, ItemStack stack) {
Item item = stack.getItem();
if (item instanceof ItemSpecialCaseGift && !this.isChild()) { // special case gifts are rings so far so prevent giving them to children
boolean decStackSize = ((ItemSpecialCaseGift) item).handle(player, this);
if (decStackSize) player.inventory.decrStackSize(player.inventory.currentItem, -1);
return true;
} else if (item == Items.CAKE) {
Optional spouse = Util.getEntityByUUID(world, get(SPOUSE_UUID).or(Constants.ZERO_UUID));
if (spouse.isPresent()) {
EntityVillagerMCA progressor = this.get(GENDER) == EnumGender.FEMALE.getId() ? this : (EntityVillagerMCA) spouse.get();
progressor.set(HAS_BABY, true);
progressor.set(BABY_IS_MALE, rand.nextBoolean());
progressor.spawnParticles(EnumParticleTypes.HEART);
} else say(Optional.of(player), "gift.cake.fail");
} else if (item == Items.GOLDEN_APPLE && this.isChild()) {
this.addGrowth(((startingAge / 4) / 20 * -1));
return true;
}
return false;
}
private void onEachClientUpdate() {
if (get(IS_PROCREATING)) {
this.rotationYawHead += 50.0F;
}
if (this.ticksExisted % 20 == 0) {
onEachClientSecond();
}
}
private void onEachClientSecond() {
this.setSizeForAge();
}
private void onEachServerUpdate() {
if (this.ticksExisted % 20 == 0) { // Every second
onEachServerSecond();
}
if (this.ticksExisted % 200 == 0 && this.getHealth() > 0.0F) { // Every 10 seconds and when we're not already dead
if (this.getHealth() < this.getMaxHealth()) {
this.setHealth(this.getHealth() + 1.0F); // heal
}
}
if (isChild()) {
EnumAgeState current = EnumAgeState.byId(get(AGE_STATE));
EnumAgeState target = EnumAgeState.byCurrentAge(startingAge, getGrowingAge());
if (current != target) {
set(AGE_STATE, target.getId());
}
}
}
private void onEachServerSecond() {
NBTTagCompound memories = get(PLAYER_HISTORY_MAP);
memories.getKeySet().forEach((key) -> PlayerHistory.fromNBT(this, UUID.fromString(key), memories.getCompoundTag(key)).update());
if (get(HAS_BABY)) {
set(BABY_AGE, get(BABY_AGE) + 1);
if (get(BABY_AGE) >= MCA.getConfig().babyGrowUpTime * 60) { // grow up time is in minutes and we measure age in seconds
EntityVillagerMCA child = new EntityVillagerMCA(world, Optional.absent(), Optional.of(get(BABY_IS_MALE) ? EnumGender.MALE : EnumGender.FEMALE));
child.set(EntityVillagerMCA.AGE_STATE, EnumAgeState.BABY.getId());
child.setStartingAge(MCA.getConfig().childGrowUpTime * 60 * 20 * -1);
child.setScaleForAge(true);
child.setPosition(this.posX, this.posY, this.posZ);
child.set(EntityVillagerMCA.PARENTS, ParentData.create(this.getUniqueID(), this.get(SPOUSE_UUID).get(), this.get(VILLAGER_NAME), this.get(SPOUSE_NAME)).toNBT());
world.spawnEntity(child);
set(HAS_BABY, false);
set(BABY_AGE, 0);
}
}
}
public ResourceLocation getTextureResourceLocation() {
if (get(IS_INFECTED)) {
return ResourceLocationCache.getResourceLocationFor(String.format("mca:skins/%s/zombievillager.png", get(GENDER) == EnumGender.MALE.getId() ? "male" : "female"));
} else {
return ResourceLocationCache.getResourceLocationFor(get(TEXTURE));
}
}
@Override
protected void initEntityAI() {
super.initEntityAI();
this.tasks.addTask(0, new EntityAIProspecting(this));
this.tasks.addTask(0, new EntityAIHunting(this));
this.tasks.addTask(0, new EntityAIChopping(this));
this.tasks.addTask(0, new EntityAIHarvesting(this));
this.tasks.addTask(0, new EntityAIFishing(this));
this.tasks.addTask(0, new EntityAIMoveState(this));
this.tasks.addTask(0, new EntityAIAgeBaby(this));
this.tasks.addTask(0, new EntityAIProcreate(this));
this.tasks.addTask(5, new EntityAIGoWorkplace(this));
this.tasks.addTask(5, new EntityAIGoHangout(this));
this.tasks.addTask(1, new EntityAISleeping(this));
this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(10, new EntityAILookIdle(this));
}
private void applySpecialAI() {
if (getProfessionForge() == ProfessionsMCA.bandit) {
this.tasks.taskEntries.clear();
this.tasks.addTask(1, new EntityAIAttackMelee(this, 0.8D, false));
this.tasks.addTask(2, new EntityAIMoveThroughVillage(this, 0.6D, false));
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVillagerMCA.class, 100, false, false, BANDIT_TARGET_SELECTOR));
this.targetTasks.addTask(1, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true));
} else if (getProfessionForge() == ProfessionsMCA.guard) {
removeCertainTasks(EntityAIAvoidEntity.class);
this.tasks.addTask(1, new EntityAIAttackMelee(this, 0.8D, false));
this.tasks.addTask(2, new EntityAIMoveThroughVillage(this, 0.6D, false));
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVillagerMCA.class, 100, false, false, GUARD_TARGET_SELECTOR));
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityZombie.class, 100, false, false, null));
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVex.class, 100, false, false, null));
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVindicator.class, 100, false, false, null));
} else {
//every other villager is allowed to defend itself from zombies while fleeing
this.tasks.addTask(0, new EntityAIDefendFromTarget(this));
this.targetTasks.taskEntries.clear();
this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityZombie.class, 100, false, false, null));
}
}
//guards should not run away from zombies
//TODO: should only avoid zombies when low on health
private void removeCertainTasks(Class typ) {
Iterator iterator = this.tasks.taskEntries.iterator();
while (iterator.hasNext()) {
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry = iterator.next();
EntityAIBase entityaibase = entityaitasks$entityaitaskentry.action;
if (entityaibase.getClass().equals(typ)) {
iterator.remove();
}
}
}
public void spawnParticles(EnumParticleTypes particleType) {
if (this.world.isRemote) {
for (int i = 0; i < 5; ++i) {
double d0 = this.rand.nextGaussian() * 0.02D;
double d1 = this.rand.nextGaussian() * 0.02D;
double d2 = this.rand.nextGaussian() * 0.02D;
this.world.spawnParticle(particleType, this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 1.0D + (double) (this.rand.nextFloat() * this.height), this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);
}
} else {
NetMCA.INSTANCE.sendToAll(new NetMCA.SpawnParticles(this.getUniqueID(), particleType));
}
}
public void stopChore() {
set(ACTIVE_CHORE, EnumChore.NONE.getId());
set(CHORE_ASSIGNING_PLAYER, Optional.of(Constants.ZERO_UUID));
}
public void startChore(EnumChore chore, EntityPlayer player) {
set(ACTIVE_CHORE, chore.getId());
set(CHORE_ASSIGNING_PLAYER, Optional.of(player.getUniqueID()));
}
public boolean playerIsParent(EntityPlayer player) {
ParentData data = ParentData.fromNBT(get(PARENTS));
return data.getParent1UUID().equals(player.getUniqueID()) || data.getParent2UUID().equals(player.getUniqueID());
}
@Override
public BlockPos getHomePosition() {
return home;
}
@Override
public void detachHome() {
// no-op, skip EntityVillager's detaching homes which messes up MoveTowardsRestriction.
}
public String getCurrentActivity() {
EnumMoveState moveState = EnumMoveState.byId(get(MOVE_STATE));
if (moveState != EnumMoveState.MOVE) {
return moveState.getFriendlyName();
}
EnumChore chore = EnumChore.byId(get(ACTIVE_CHORE));
if (chore != EnumChore.NONE) {
return chore.getFriendlyName();
}
return null;
}
public void moveTowardsBlock(BlockPos target) {
moveTowardsBlock(target, 0.5D);
}
public void moveTowardsBlock(BlockPos target, double speed) {
double range = getNavigator().getPathSearchRange() - 6.0D;
if (getDistanceSq(target) > Math.pow(range, 2.0)) {
Vec3d vec3d = RandomPositionGenerator.findRandomTargetBlockTowards(this, (int) range, 8, new Vec3d(target.getX(), target.getY(), target.getZ()));
if (vec3d != null && !getNavigator().setPath(getNavigator().getPathToXYZ(vec3d.x, vec3d.y, vec3d.z), speed)) {
attemptTeleport(vec3d.x, vec3d.y, vec3d.z);
}
} else {
if (!getNavigator().setPath(getNavigator().getPathToPos(target), speed)) {
attemptTeleport(target.getX(), target.getY(), target.getZ());
}
}
}
//searches for the nearest bed
public BlockPos searchBed() {
List nearbyBeds = Util.getNearbyBlocks(getPos(), world, BlockBed.class, 8, 8);
List valid = new ArrayList<>();
for (BlockPos pos : nearbyBeds) {
IBlockState state = world.getBlockState(pos);
if (!(state.getValue(OCCUPIED)) && state.getValue(PART) != BlockBed.EnumPartType.HEAD) {
valid.add(pos);
}
}
return Util.getNearestPoint(getPos(), valid);
}
/**
* Returns the orientation of the bed in degrees.
*/
@SideOnly(Side.CLIENT)
public float getBedOrientationInDegrees() {
BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);
IBlockState state = bedLocation == BlockPos.ORIGIN ? null : this.world.getBlockState(bedLocation);
if (state != null && state.getBlock().isBed(state, world, bedLocation, this)) {
EnumFacing enumfacing = state.getBlock().getBedDirection(state, world, bedLocation);
switch (enumfacing) {
case SOUTH:
return 90.0F;
case WEST:
return 0.0F;
case NORTH:
return 270.0F;
case EAST:
return 180.0F;
}
}
return 0.0F;
}
public boolean isSleeping() {
return get(SLEEPING);
}
private void updateSleeping() {
if (isSleeping()) {
BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);
final IBlockState state = this.world.isBlockLoaded(bedLocation) ? this.world.getBlockState(bedLocation) : null;
final boolean isBed = state != null && state.getBlock().isBed(state, this.world, bedLocation, this);
if (isBed) {
final EnumFacing enumfacing = state.getBlock() instanceof BlockHorizontal ? state.getValue(BlockHorizontal.FACING) : null;
if (enumfacing != null) {
float f1 = 0.5F + (float) enumfacing.getFrontOffsetX() * 0.4F;
float f = 0.5F + (float) enumfacing.getFrontOffsetZ() * 0.4F;
this.setRenderOffsetForSleep(enumfacing);
this.setPosition((double) ((float) bedLocation.getX() + f1), (double) ((float) bedLocation.getY() + 0.6875F), (double) ((float) bedLocation.getZ() + f));
} else {
this.setPosition((double) ((float) bedLocation.getX() + 0.5F), (double) ((float) bedLocation.getY() + 0.6875F), (double) ((float) bedLocation.getZ() + 0.5F));
}
this.setSize(0.2F, 0.2F);
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
} else {
set(EntityVillagerMCA.BED_POS, BlockPos.ORIGIN);
stopSleeping();
}
} else {
this.setSize(0.6F, 1.8F);
}
}
private void setRenderOffsetForSleep(EnumFacing bedDirection) {
this.renderOffsetX = -1.0F * (float) bedDirection.getFrontOffsetX();
this.renderOffsetZ = -1.0F * (float) bedDirection.getFrontOffsetZ();
}
public void startSleeping() {
if (this.isRiding()) {
this.dismountRidingEntity();
}
set(SLEEPING, true);
BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);
IBlockState blockstate = this.world.getBlockState(bedLocation);
if (blockstate.getBlock() == Blocks.BED) {
blockstate.getBlock().setBedOccupied(world, bedLocation, null, true);
}
}
public void stopSleeping() {
BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);
if (bedLocation != BlockPos.ORIGIN) {
IBlockState blockstate = this.world.getBlockState(bedLocation);
if (blockstate.getBlock().isBed(blockstate, world, bedLocation, this)) {
blockstate.getBlock().setBedOccupied(world, bedLocation, null, false);
BlockPos blockpos = blockstate.getBlock().getBedSpawnPosition(blockstate, world, bedLocation, null);
if (blockpos == null) {
blockpos = bedLocation.up();
}
this.setPosition((double) ((float) blockpos.getX() + 0.5F), (double) ((float) blockpos.getY() + 0.1F), (double) ((float) blockpos.getZ() + 0.5F));
}
}
set(SLEEPING, false);
}
}
================================================
FILE: src/main/java/mca/entity/ai/AbstractEntityAIChore.java
================================================
package mca.entity.ai;
import com.google.common.base.Optional;
import mca.core.Constants;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.player.EntityPlayer;
public abstract class AbstractEntityAIChore extends EntityAIBase {
protected final EntityVillagerMCA villager;
public AbstractEntityAIChore(EntityVillagerMCA entityIn) {
this.villager = entityIn;
this.setMutexBits(4);
}
@Override
public void updateTask() {
super.updateTask();
if (!getAssigningPlayer().isPresent()) {
MCA.getLog().warn("Force-stopped chore because assigning player was not present.");
villager.stopChore();
}
}
Optional getAssigningPlayer() {
EntityPlayer player = villager.world.getPlayerEntityByUUID(villager.get(EntityVillagerMCA.CHORE_ASSIGNING_PLAYER).or(Constants.ZERO_UUID));
return Optional.fromNullable(player);
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIAgeBaby.java
================================================
package mca.entity.ai;
import com.google.common.base.Optional;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.ParentData;
import mca.enums.EnumGender;
import net.minecraft.entity.ai.EntityAIBase;
public class EntityAIAgeBaby extends EntityAIBase {
private final EntityVillagerMCA villager;
public EntityAIAgeBaby(EntityVillagerMCA entityIn) {
this.villager = entityIn;
this.setMutexBits(4);
}
public boolean shouldExecute() {
return villager.get(EntityVillagerMCA.HAS_BABY);
}
public void updateTask() {
if (villager.ticksExisted % 1200 != 0) return;
villager.babyAge += 1;
if (villager.babyAge < MCA.getConfig().babyGrowUpTime) return;
EntityVillagerMCA child = new EntityVillagerMCA(villager.world, Optional.absent(), Optional.of(villager.get(EntityVillagerMCA.BABY_IS_MALE) ? EnumGender.MALE : EnumGender.FEMALE));
child.set(EntityVillagerMCA.PARENTS, ParentData.fromVillager(villager).toNBT());
child.setPosition(villager.posX, villager.posY, villager.posZ);
villager.world.spawnEntity(child);
villager.set(EntityVillagerMCA.HAS_BABY, false);
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIChopping.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
import mca.util.Util;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockLog;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.List;
public class EntityAIChopping extends AbstractEntityAIChore {
private int chopTicks;
private BlockPos targetTree;
public EntityAIChopping(EntityVillagerMCA entityIn) {
super(entityIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getHealth() < villager.getMaxHealth()) {
villager.stopChore();
}
return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.CHOP;
}
public void updateTask() {
if (!villager.inventory.contains(ItemAxe.class)) {
villager.say(getAssigningPlayer(), "chore.chopping.noaxe");
villager.stopChore();
}
if (targetTree == null) {
List nearbyLogs = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockLog.class, 10, 5);
List nearbyTrees = new ArrayList<>();
// valid "trees" are logs on the ground with leaves around them
nearbyLogs.stream()
.filter(log -> {
IBlockState down = villager.world.getBlockState(log.down());
List leaves = Util.getNearbyBlocks(log, villager.world, BlockLeaves.class, 1, 5);
return leaves.size() > 0 && (down.getBlock() == Blocks.GRASS || down.getBlock() == Blocks.DIRT);
})
.forEach(nearbyTrees::add);
targetTree = Util.getNearestPoint(villager.getPos(), nearbyTrees);
return;
}
double distance = Math.sqrt(villager.getDistanceSq(targetTree));
if (distance >= 4.0D) villager.getNavigator().setPath(villager.getNavigator().getPathToPos(targetTree), 0.5D);
else {
IBlockState state = villager.world.getBlockState(targetTree);
if (state.getBlock() instanceof BlockLog) {
BlockLog log = (BlockLog) state.getBlock();
villager.swingArm(EnumHand.MAIN_HAND);
chopTicks++;
if (chopTicks >= 80) {
chopTicks = 0;
villager.inventory.addItem(new ItemStack(log, 1));
villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);
if (villager.world.rand.nextFloat() >= 0.90) destroyTree(targetTree);
}
} else targetTree = null;
}
}
private void destroyTree(BlockPos origin) {
BlockPos pos = origin;
while (villager.world.getBlockState(pos).getBlock() instanceof BlockLog) {
villager.world.setBlockToAir(pos);
pos = pos.add(0, 1, 0);
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIDefendFromTarget.java
================================================
package mca.entity.ai;
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.util.EnumHand;
public class EntityAIDefendFromTarget extends EntityAIBase {
private EntityCreature attacker;
private int attackTick;
public EntityAIDefendFromTarget(EntityCreature creature) {
this.attacker = creature;
this.setMutexBits(0);
}
public boolean shouldExecute() {
this.attackTick--;
EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();
if (entitylivingbase == null) {
return false;
} else if (!entitylivingbase.isEntityAlive()) {
return false;
} else if (this.attackTick > 0) {
return false;
} else {
return 4.0D >= this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.getEntityBoundingBox().minY, entitylivingbase.posZ);
}
}
public boolean shouldContinueExecuting() {
return false;
}
public void startExecuting() {
this.attackTick = 10;
EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();
if (entitylivingbase != null) {
this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);
this.attacker.swingArm(EnumHand.MAIN_HAND);
this.attacker.attackEntityAsMob(entitylivingbase);
}
}
public void resetTask() {
}
public void updateTask() {
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIFishing.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
import mca.util.Util;
import net.minecraft.block.BlockStaticLiquid;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemFishFood;
import net.minecraft.item.ItemFishingRod;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import java.util.Comparator;
import java.util.List;
public class EntityAIFishing extends AbstractEntityAIChore {
private BlockPos targetWater;
private boolean hasCastRod;
private int ticks;
public EntityAIFishing(EntityVillagerMCA entityIn) {
super(entityIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getHealth() < villager.getMaxHealth()) {
villager.stopChore();
}
return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.FISH;
}
public void updateTask() {
super.updateTask();
if (!villager.inventory.contains(ItemFishingRod.class)) {
villager.say(getAssigningPlayer(), "chore.fishing.norod");
villager.stopChore();
return;
}
if (targetWater == null) {
List nearbyStaticLiquid = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockStaticLiquid.class, 12, 3);
targetWater = nearbyStaticLiquid.stream()
.filter((p) -> villager.world.getBlockState(p).getBlock() == Blocks.WATER)
.min(Comparator.comparingDouble(villager::getDistanceSq)).orElse(null);
} else if (villager.getDistanceSq(targetWater) > 5.0D) villager.getNavigator().setPath(villager.getNavigator().getPathToPos(targetWater), 0.8D);
else if (villager.getDistanceSq(targetWater) < 5.0D) {
villager.getNavigator().clearPath();
if (!hasCastRod) {
villager.swingArm(EnumHand.MAIN_HAND);
hasCastRod = true;
}
ticks++;
if (ticks >= villager.world.rand.nextInt(200) + 200) {
if (villager.world.rand.nextFloat() >= 0.35F) {
int typesSize = ItemFishFood.FishType.values().length;
ItemFishFood.FishType type = ItemFishFood.FishType.values()[villager.world.rand.nextInt(typesSize)];
ItemStack stack = new ItemStack(Items.FISH, 1, type.getMetadata());
villager.swingArm(EnumHand.MAIN_HAND);
villager.inventory.addItem(stack);
villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);
}
ticks = 0;
}
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIGoHangout.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
public class EntityAIGoHangout extends AbstractEntityAIChore {
private boolean atHangout = false;
public EntityAIGoHangout(EntityVillagerMCA villagerIn) {
super(villagerIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getHangout().getY() == 0) {
return false; //no workplace
}
//no time, has to work
if (EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) != EnumChore.NONE) {
return false;
}
long time = villager.world.getWorldTime() % 24000L;
if (time < 9000 || time > 11000) {
//spare time is over, villager will start going home
atHangout = false;
return false;
}
double validArea = 64.0D; //allows 8 blocks radius to stay
double distance = villager.getDistanceSq(villager.getHangout());
if (!atHangout) {
if (distance < 9.0) {
//arrived at hangout
atHangout = true;
} else {
//did not reach workplace for today -> shrink valid area so the villager gathers clearly at his workplace
validArea = 4.0D;
}
}
return distance > validArea;
}
public boolean shouldContinueExecuting() {
return !villager.getNavigator().noPath();
}
public void startExecuting() {
villager.moveTowardsBlock(villager.getHangout());
}
public void updateTask() {
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIGoWorkplace.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
public class EntityAIGoWorkplace extends AbstractEntityAIChore {
private boolean atWork = false;
public EntityAIGoWorkplace(EntityVillagerMCA villagerIn) {
super(villagerIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getWorkplace().getY() == 0 || villager.world.isRaining()) {
return false; //no workplace or it is raining
}
long time = villager.world.getWorldTime() % 24000L;
if (time < 4000 || time > 7000) {
//work is over, villager will start spreading
atWork = false;
return false;
}
double validArea = 576.0D; //allows 24 blocks radius to work
double distance = villager.getDistanceSq(villager.getWorkplace());
if (!atWork) {
if (distance < 9.0) {
//arrived at workplace
atWork = true;
} else {
//did not reach workplace for today -> shrink valid area so the villager gathers clearly at his workplace
validArea = 4.0D;
}
}
return distance > validArea;
}
public boolean shouldContinueExecuting() {
return !villager.getNavigator().noPath();
}
public void startExecuting() {
//MCA.getLog().info(villager.getName() + " goes to work");
villager.moveTowardsBlock(villager.getWorkplace());
}
public void updateTask() {
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIHarvesting.java
================================================
package mca.entity.ai;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
import mca.util.Util;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.*;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.List;
public class EntityAIHarvesting extends AbstractEntityAIChore {
private int blockWork = 0;
private int lastCropScan = 0;
public EntityAIHarvesting(EntityVillagerMCA villagerIn) {
super(villagerIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getHealth() < villager.getMaxHealth()) {
villager.stopChore();
}
return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.HARVEST && (blockWork - villager.ticksExisted) < 0;
}
public boolean shouldContinueExecuting() {
return !villager.getNavigator().noPath();
}
private BlockPos searchCrop(int rangeX, int rangeY) {
List nearbyCrops = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockCrops.class, rangeX, rangeY);
List harvestable = new ArrayList<>();
for (BlockPos pos : nearbyCrops) {
IBlockState state = villager.world.getBlockState(pos);
BlockCrops crop = (BlockCrops) state.getBlock();
if (crop.isMaxAge(state)) {
harvestable.add(pos);
}
}
return Util.getNearestPoint(villager.getPos(), harvestable);
}
public void startExecuting() {
if (!villager.inventory.contains(ItemHoe.class)) {
villager.say(getAssigningPlayer(), "chore.harvesting.nohoe");
villager.stopChore();
}
//search crop
BlockPos target = searchCrop(16, 3);
//no crop next to villager -> long range scan
//limited to once a minute to reduce CPU usage
if (target == null && villager.ticksExisted - lastCropScan > 1200) {
//MCA.getLog().info(villager.getName() + " scans for crops");
lastCropScan = villager.ticksExisted;
target = searchCrop(32, 16);
}
if (target == null) {
if (villager.getWorkplace().getY() > 0 && villager.getDistanceSq(villager.getWorkplace()) > 256.0D) {
//go to their workplace (if set and more than 16 blocks away)
//MCA.getLog().info(villager.getName() + " goes to workplace");
villager.moveTowardsBlock(villager.getWorkplace());
} else {
//failed (no crop on range), allows now other, lower priority tasks to interrupt
//MCA.getLog().info(villager.getName() + " idles");
blockWork = villager.ticksExisted + 100 + villager.getRNG().nextInt(100);
}
} else {
//harvest if next to it, else try to reach it
double distanceTo = Math.sqrt(villager.getDistanceSq(target));
if (distanceTo >= 2.0D) {
if (!villager.getNavigator().setPath(villager.getNavigator().getPathToPos(target), 0.5D)) {
villager.attemptTeleport(target.getX(), target.getY(), target.getZ());
}
} else {
//harvest
IBlockState state = villager.world.getBlockState(target);
if (state.getBlock() instanceof BlockCrops) {
BlockCrops crop = (BlockCrops) state.getBlock();
NonNullList drops = NonNullList.create();
crop.getDrops(drops, villager.world, target, state, 0);
for (ItemStack stack : drops) {
villager.inventory.addItem(stack);
}
villager.swingArm(EnumHand.MAIN_HAND);
villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);
try {
IProperty property = (IProperty) crop.getBlockState().getProperty("age");
villager.world.setBlockState(target, state.withProperty(property, 0));
} catch (Exception e) { // age property may have some issues on certain mods, if it errors just set to air
MCA.getLog().warn("Error resetting crop age at " + target.toString() + "! Setting to air.");
villager.world.setBlockToAir(target);
}
}
//wait before harvesting next crop
ItemStack hoeStack = villager.inventory.getBestItemOfType(ItemHoe.class);
float efficiency = hoeStack == ItemStack.EMPTY ? 0.0f : Item.ToolMaterial.valueOf(((ItemHoe) hoeStack.getItem()).getMaterialName()).getEfficiency();
blockWork = villager.ticksExisted + (int) Math.max(2.0f, 60.0f - efficiency * 5.0f);
}
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIHunting.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.item.ItemSword;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import java.util.Comparator;
import java.util.Optional;
public class EntityAIHunting extends AbstractEntityAIChore {
private int ticks = 0;
private int nextAction = 0;
private EntityAnimal target = null;
public EntityAIHunting(EntityVillagerMCA entityIn) {
super(entityIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
if (villager.getHealth() < villager.getMaxHealth()) {
villager.stopChore();
}
return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.HUNT;
}
public void updateTask() {
super.updateTask();
if (!villager.inventory.contains(ItemSword.class)) {
villager.say(getAssigningPlayer(), "chore.hunting.nosword");
villager.stopChore();
}
if (target == null) {
ticks++;
if (ticks >= nextAction) {
ticks = 0;
if (villager.world.rand.nextFloat() >= 0.0D) {
Optional animal = villager.world.getEntitiesWithinAABB(EntityAnimal.class, villager.getEntityBoundingBox().grow(15.0D, 3.0D, 15.0D)).stream()
.filter((a) -> !(a instanceof EntityTameable))
.min(Comparator.comparingDouble(villager::getDistance));
if (animal.isPresent()) {
target = animal.get();
target.getNavigator().setPath(target.getNavigator().getPathToEntityLiving(villager), 1.0F);
}
}
nextAction = 300;
}
} else {
boolean pathSuccess = villager.getNavigator().setPath(villager.getNavigator().getPathToEntityLiving(target), 0.6F);
if (!pathSuccess || target.isDead) {
// search for EntityItems around the target and grab them
villager.world.loadedEntityList.stream()
.filter((e) -> e instanceof EntityItem && e.getDistance(target) <= 5.0D)
.forEach((item) -> {
villager.inventory.addItem(((EntityItem) item).getItem());
item.setDead();
});
target = null;
} else if (villager.getDistance(target) <= 3.5F) {
villager.getNavigator().setPath(villager.getNavigator().getPathToEntityLiving(target), 1.0F);
villager.swingArm(EnumHand.MAIN_HAND);
target.attackEntityFrom(DamageSource.causeMobDamage(villager), 6.0F);
villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);
}
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIMoveState.java
================================================
package mca.entity.ai;
import mca.core.Constants;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumMoveState;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.pathfinding.PathNavigate;
public class EntityAIMoveState extends EntityAIBase {
private final EntityVillagerMCA villager;
public EntityAIMoveState(EntityVillagerMCA entityIn) {
this.villager = entityIn;
this.setMutexBits(1);
}
public boolean shouldExecute() {
return !villager.playerToFollowUUID.equals(Constants.ZERO_UUID) || EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE)) == EnumMoveState.STAY;
}
public void updateTask() {
PathNavigate nav = villager.getNavigator();
EntityPlayer playerToFollow = villager.world.getPlayerEntityByUUID(villager.playerToFollowUUID);
switch (EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE))) {
case FOLLOW:
double distance = playerToFollow != null ? villager.getDistance(playerToFollow) : -1.0D;
if (playerToFollow == null) {
villager.set(EntityVillagerMCA.MOVE_STATE, EnumMoveState.MOVE.getId());
break;
} else if (distance >= 3.0D && distance <= 10.0D) {
nav.setPath(nav.getPathToEntityLiving(playerToFollow), villager.isRiding() ? 1.7D : 0.8D);
} else if (distance > 10.0D) {
villager.attemptTeleport(playerToFollow.posX, playerToFollow.posY, playerToFollow.posZ);
} else { // close enough to avoid crowding the player
nav.clearPath();
}
break;
case STAY:
nav.clearPath();
break;
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIProcreate.java
================================================
package mca.entity.ai;
import lombok.RequiredArgsConstructor;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.minecraft.ItemsMCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.PlayerSaveData;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.SoundCategory;
@RequiredArgsConstructor
public class EntityAIProcreate extends EntityAIBase {
private final EntityVillagerMCA villager;
public int procreateTimer;
@Override
public boolean shouldExecute() {
return villager.get(EntityVillagerMCA.IS_PROCREATING);
}
@Override
public void updateTask() {
if (procreateTimer % 5 == 0) villager.spawnParticles(EnumParticleTypes.HEART);
if (--procreateTimer <= 0) {
villager.set(EntityVillagerMCA.IS_PROCREATING, false);
EntityPlayer spousePlayer = villager.world.getPlayerEntityByUUID(villager.get(EntityVillagerMCA.SPOUSE_UUID).or(Constants.ZERO_UUID));
if (spousePlayer != null) {
villager.world.playSound(null, villager.posX, villager.posY, villager.posZ, SoundEvents.ENTITY_CHICKEN_EGG, SoundCategory.NEUTRAL, 1.0F, 1.0F);
spousePlayer.inventory.addItemStackToInventory(new ItemStack(villager.getRNG().nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));
PlayerSaveData.get(spousePlayer).setBabyPresent(true);
if (villager.getRNG().nextFloat() < MCA.getConfig().chanceToHaveTwins / 100)
spousePlayer.inventory.addItemStackToInventory(new ItemStack(villager.getRNG().nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));
}
}
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAIProspecting.java
================================================
package mca.entity.ai;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumChore;
import mca.util.Util;
import net.minecraft.block.Block;
import net.minecraft.block.BlockOre;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
public class EntityAIProspecting extends AbstractEntityAIChore {
private int ticks;
public EntityAIProspecting(EntityVillagerMCA entityIn) {
super(entityIn);
this.setMutexBits(4);
}
public boolean shouldExecute() {
if (villager.getHealth() < villager.getMaxHealth()) {
villager.stopChore();
}
return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.PROSPECT;
}
public void updateTask() {
super.updateTask();
ItemStack pickStack = villager.inventory.getBestItemOfType(ItemPickaxe.class);
if (pickStack == ItemStack.EMPTY) {
villager.say(getAssigningPlayer(), "chore.mining.nopick");
villager.stopChore();
return;
}
float efficiency = Item.ToolMaterial.valueOf(((ItemPickaxe) pickStack.getItem()).getToolMaterialName()).getEfficiency();
float notifyRate = Math.max(600 - efficiency * 50, 100);
if (ticks >= notifyRate) {
BlockPos closestOre = Util.getNearestPoint(villager.getPos(), Util.getNearbyBlocks(villager.getPos(), villager.world, BlockOre.class, 4, 3));
if (closestOre != null) {
Block block = villager.world.getBlockState(closestOre).getBlock();
villager.say(getAssigningPlayer(), "chore.mining.orenotify", block.getLocalizedName());
pickStack.damageItem(2, villager);
}
ticks = 0;
return;
}
ticks++;
}
}
================================================
FILE: src/main/java/mca/entity/ai/EntityAISleeping.java
================================================
package mca.entity.ai;
import mca.core.minecraft.ProfessionsMCA;
import mca.entity.EntityVillagerMCA;
import net.minecraft.util.math.BlockPos;
public class EntityAISleeping extends AbstractEntityAIChore {
private int failed = 0;
public EntityAISleeping(EntityVillagerMCA villagerIn) {
super(villagerIn);
this.setMutexBits(1);
}
public boolean shouldExecute() {
//let the avoid tasks work
if (villager.getHealth() < villager.getMaxHealth()) {
return false;
}
if (villager.ticksExisted - failed < 1200) {
//wake up if still sleeping
if (villager.isSleeping()) {
villager.stopSleeping();
}
return false;
}
long time = villager.world.getWorldTime() % 24000L;
if (villager.get(EntityVillagerMCA.BED_POS) == BlockPos.ORIGIN && time < 16000) { //at tick 18000 villager without bed are allowed to automatically choose one
//wake up if still sleeping
if (villager.isSleeping()) {
villager.stopSleeping();
}
return false;
}
//if guards detect enemies they won't sleep
if (villager.getProfessionForge() == ProfessionsMCA.guard && villager.getAttackTarget() != null) {
//wake up, this is a emergency!
if (villager.isSleeping()) {
villager.stopSleeping();
}
return false;
}
if (time > (villager.getProfessionForge() == ProfessionsMCA.guard ? 14000 : 12000) && time < 23000) {
return true;
} else {
//wake up if still sleeping
if (villager.isSleeping()) {
villager.stopSleeping();
}
return false;
}
}
public boolean shouldContinueExecuting() {
return shouldExecute() && (!villager.getNavigator().noPath() || villager.isSleeping());
}
public void startExecuting() {
if (villager.get(EntityVillagerMCA.BED_POS) == BlockPos.ORIGIN || villager.getDistanceSq(villager.get(EntityVillagerMCA.BED_POS)) < 4.0) {
//search for the nearest bed, might be a different than before
BlockPos pos = villager.searchBed();
if (pos == null) {
//no bed found, let's forget about the remembered bed
if (villager.get(EntityVillagerMCA.BED_POS) != BlockPos.ORIGIN) {
//TODO: notify the player?
//MCA.getLog().info(villager.getName() + " lost the bed");
villager.set(EntityVillagerMCA.BED_POS, BlockPos.ORIGIN);
} else {
//MCA.getLog().info(villager.getName() + " has no bed");
}
failed = villager.ticksExisted;
} else {
//MCA.getLog().info(villager.getName() + " sleeps now");
villager.set(EntityVillagerMCA.BED_POS, pos);
villager.startSleeping();
}
} else {
//MCA.getLog().info(villager.getName() + " is going to bed");
villager.moveTowardsBlock(villager.get(EntityVillagerMCA.BED_POS), 0.75);
}
}
public void resetTask() {
if (villager.isSleeping()) {
//MCA.getLog().info(villager.getName() + " wakes up");
villager.stopSleeping();
}
}
public void updateTask() {
if (villager.isSleeping()) {
villager.setRotationYawHead(0.0f);
villager.rotationYaw = 0.0f;
}
}
}
================================================
FILE: src/main/java/mca/entity/data/ParentData.java
================================================
package mca.entity.data;
import lombok.Getter;
import mca.core.Constants;
import mca.entity.EntityVillagerMCA;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import java.util.UUID;
import static mca.entity.EntityVillagerMCA.*;
@Getter
public class ParentData {
private UUID parent1UUID = Constants.ZERO_UUID;
private UUID parent2UUID = Constants.ZERO_UUID;
private String parent1Name = "";
private String parent2Name = "";
public static ParentData fromNBT(NBTTagCompound nbt) {
ParentData data = new ParentData();
data.parent1UUID = nbt.getUniqueId("parent1UUID");
data.parent2UUID = nbt.getUniqueId("parent2UUID");
data.parent1Name = nbt.getString("parent1Name");
data.parent2Name = nbt.getString("parent2Name");
return data;
}
public static ParentData create(UUID parent1UUID, UUID parent2UUID, String parent1Name, String parent2Name) {
ParentData data = new ParentData();
data.parent1UUID = parent1UUID;
data.parent2UUID = parent2UUID;
data.parent1Name = parent1Name;
data.parent2Name = parent2Name;
return data;
}
public static ParentData fromVillager(EntityVillagerMCA villager) {
ParentData data = new ParentData();
data.parent1Name = villager.get(VILLAGER_NAME);
data.parent1UUID = villager.getUniqueID();
data.parent2Name = villager.get(SPOUSE_NAME);
data.parent2UUID = villager.get(SPOUSE_UUID).or(Constants.ZERO_UUID);
return data;
}
public NBTTagCompound toNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setUniqueId("parent1UUID", parent1UUID);
nbt.setUniqueId("parent2UUID", parent2UUID);
nbt.setString("parent1Name", parent1Name);
nbt.setString("parent2Name", parent2Name);
return nbt;
}
public ParentData setParents(UUID parent1UUID, String parent1Name, UUID parent2UUID, String parent2Name) {
this.parent1UUID = parent1UUID;
this.parent2UUID = parent2UUID;
this.parent1Name = parent1Name;
this.parent2Name = parent2Name;
return this;
}
public Entity getParentEntity(World world, UUID uuid) {
return world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(uuid)).findFirst().orElse(null); // TODO: This should definitely be changed to an optional
}
public Entity[] getParentEntities(World world) {
return new Entity[]{
getParentEntity(world, getParent1UUID()),
getParentEntity(world, getParent2UUID())
};
}
}
================================================
FILE: src/main/java/mca/entity/data/PlayerHistory.java
================================================
package mca.entity.data;
import lombok.Getter;
import mca.core.Constants;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumDialogueType;
import net.minecraft.nbt.NBTTagCompound;
import java.util.UUID;
public class PlayerHistory {
@Getter private int hearts;
@Getter private int interactionFatigue;
@Getter private boolean giftPresent;
@Getter private int greetTimer;
@Getter private EnumDialogueType dialogueType;
@Getter private UUID playerUUID;
private EntityVillagerMCA villager;
private PlayerHistory() {
hearts = 0;
interactionFatigue = 0;
giftPresent = false;
greetTimer = 0;
playerUUID = Constants.ZERO_UUID;
dialogueType = EnumDialogueType.ADULT;
}
public static PlayerHistory getNew(EntityVillagerMCA villager, UUID uuid) {
PlayerHistory history = new PlayerHistory();
history.villager = villager;
history.playerUUID = uuid;
if (villager.isChild()) {
history.setDialogueType(EnumDialogueType.CHILD);
} else {
history.setDialogueType(EnumDialogueType.ADULT);
}
return history;
}
public static PlayerHistory fromNBT(EntityVillagerMCA villager, UUID uuid, NBTTagCompound nbt) {
PlayerHistory history = new PlayerHistory();
history.villager = villager;
history.playerUUID = uuid;
history.hearts = nbt.getInteger("hearts");
history.interactionFatigue = nbt.getInteger("interactionFatigue");
history.giftPresent = nbt.getBoolean("giftPresent");
history.greetTimer = nbt.getInteger("greetTimer");
history.dialogueType = EnumDialogueType.byValue(nbt.getString("dialogueType"));
return history;
}
public NBTTagCompound toNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("hearts", hearts);
nbt.setInteger("interactionFatigue", interactionFatigue);
nbt.setBoolean("giftPresent", giftPresent);
nbt.setInteger("greetTimer", greetTimer);
nbt.setString("dialogueType", dialogueType.getId());
return nbt;
}
public void setHearts(int value) {
hearts = value;
villager.updatePlayerHistoryMap(this);
}
public void changeHearts(int value) {
hearts += value;
villager.updatePlayerHistoryMap(this);
}
public void changeInteractionFatigue(int value) {
interactionFatigue += value;
villager.updatePlayerHistoryMap(this);
}
public void update() {
// every 5 minutes reduce interaction fatigues
if (villager.ticksExisted % 6000 == 0) changeInteractionFatigue(-1);
}
public void setDialogueType(EnumDialogueType type) {
this.dialogueType = type;
villager.updatePlayerHistoryMap(this);
}
}
================================================
FILE: src/main/java/mca/entity/data/PlayerSaveData.java
================================================
package mca.entity.data;
import lombok.Getter;
import mca.core.Constants;
import mca.core.MCA;
import mca.enums.EnumMarriageState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraft.world.storage.WorldSavedData;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Getter
public class PlayerSaveData extends WorldSavedData {
private static final String PREFIX = "MCA-Player-V1-";
private UUID spouseUUID = Constants.ZERO_UUID;
private EnumMarriageState marriageState = EnumMarriageState.NOT_MARRIED;
private String spouseName = "";
private boolean babyPresent = false;
public PlayerSaveData(String id) {
super(id);
}
public static PlayerSaveData get(EntityPlayer player) {
String dataId = PREFIX + player.getUniqueID().toString();
PlayerSaveData data = (PlayerSaveData) player.world.loadData(PlayerSaveData.class, dataId);
if (data == null) {
data = new PlayerSaveData(dataId);
player.world.setData(dataId, data);
}
return data;
}
public static PlayerSaveData getExisting(World world, UUID uuid) {
return (PlayerSaveData) world.loadData(PlayerSaveData.class, PREFIX + uuid.toString());
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setUniqueId("spouseUUID", spouseUUID);
nbt.setInteger("marriageState", marriageState.getId());
nbt.setString("spouseName", spouseName);
nbt.setBoolean("babyPresent", babyPresent);
return nbt;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
spouseUUID = nbt.getUniqueId("spouseUUID");
marriageState = EnumMarriageState.byId(nbt.getInteger("marriageState"));
spouseName = nbt.getString("spouseName");
babyPresent = nbt.getBoolean("babyPresent");
}
public boolean isMarriedOrEngaged() {
return marriageState != EnumMarriageState.NOT_MARRIED;
}
public void marry(UUID uuid, String name) {
spouseUUID = uuid;
marriageState = EnumMarriageState.MARRIED;
spouseName = name;
markDirty();
}
public void endMarriage() {
spouseUUID = Constants.ZERO_UUID;
spouseName = "";
marriageState = EnumMarriageState.NOT_MARRIED;
markDirty();
}
public void setBabyPresent(boolean value) {
this.babyPresent = value;
markDirty();
}
public void reset() {
endMarriage();
setBabyPresent(false);
markDirty();
}
public List getDataFields() {
return Arrays.stream(this.getClass().getDeclaredFields()).filter(f -> !Modifier.isFinal(f.getModifiers())).collect(Collectors.toList());
}
public void dump(EntityPlayer player) {
for (Field f : getDataFields()) {
try {
player.sendMessage(new TextComponentString(f.getName() + " = " + f.get(this).toString()));
} catch (Exception e) {
MCA.getLog().error("Error dumping player data!");
MCA.getLog().error(e);
}
}
}
}
================================================
FILE: src/main/java/mca/entity/data/SavedVillagers.java
================================================
package mca.entity.data;
import mca.entity.EntityVillagerMCA;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.storage.WorldSavedData;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* SavedVillagers handles saving dead villagers to the world which allows them to be restored later.
*/
public class SavedVillagers extends WorldSavedData {
private static final String DATA_ID = "MCA-Villagers-V1";
private Map villagerData = new HashMap<>();
public SavedVillagers(String id) {
super(id);
}
public static SavedVillagers get(World world) {
SavedVillagers data = (SavedVillagers) world.loadData(SavedVillagers.class, DATA_ID);
if (data == null) {
data = new SavedVillagers(DATA_ID);
world.setData(DATA_ID, data);
}
return data;
}
public void save(EntityVillagerMCA villager) {
villagerData.put(villager.getUniqueID().toString(), villager.writeToNBT(new NBTTagCompound()));
markDirty();
}
public void remove(UUID uuid) {
villagerData.remove(uuid.toString());
markDirty();
}
public Map getMap() {
return villagerData;
}
public NBTTagCompound loadByUUID(UUID uuid) {
return villagerData.get(uuid.toString());
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
villagerData.forEach(nbt::setTag);
return nbt;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
nbt.getKeySet().forEach((k) -> villagerData.put(k, nbt.getCompoundTag(k)));
}
}
================================================
FILE: src/main/java/mca/entity/inventory/InventoryMCA.java
================================================
package mca.entity.inventory;
import mca.entity.EntityVillagerMCA;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.inventory.InventoryBasic;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class InventoryMCA extends InventoryBasic {
private EntityVillagerMCA villager;
public InventoryMCA(EntityVillagerMCA villager) {
super("Villager Inventory", true, 27);
this.villager = villager;
}
public int getFirstSlotContainingItem(Item item) {
for (int i = 0; i < this.getSizeInventory(); i++) {
ItemStack stack = this.getStackInSlot(i);
if (stack.getItem() != item) continue;
return i;
}
return -1;
}
public boolean contains(Class clazz) {
for (int i = 0; i < this.getSizeInventory(); ++i) {
final ItemStack stack = this.getStackInSlot(i);
final Item item = stack.getItem();
if (item.getClass() == clazz) return true;
}
return false;
}
/**
* Gets the best quality (max damage) item of the specified type that is in the inventory.
*
* @param type The class of item that will be returned.
* @return The item stack containing the item of the specified type with the highest max damage.
*/
public ItemStack getBestItemOfType(@Nullable Class type) {
if (type == null) return ItemStack.EMPTY;
else return getStackInSlot(getBestItemOfTypeSlot(type));
}
public ItemStack getBestArmorOfType(EntityEquipmentSlot slot) {
ItemStack returnStack = ItemStack.EMPTY;
List armors = new ArrayList();
for (int i = 0; i < this.getSizeInventory(); ++i) {
ItemStack stack = this.getStackInSlot(i);
if (stack.getItem() instanceof ItemArmor) {
ItemArmor armor = (ItemArmor) stack.getItem();
if (armor.armorType == slot) armors.add(stack);
}
}
int highestMaxDamage = 0;
for (ItemStack stack : armors) {
if (stack.getMaxDamage() > highestMaxDamage) {
returnStack = stack;
highestMaxDamage = stack.getMaxDamage();
}
}
return returnStack;
}
public int getBestItemOfTypeSlot(Class type) {
int highestMaxDamage = 0;
int best = -1;
for (int i = 0; i < this.getSizeInventory(); ++i) {
ItemStack stackInInventory = this.getStackInSlot(i);
final String itemClassName = stackInInventory.getItem().getClass().getName();
if (itemClassName.equals(type.getName()) && highestMaxDamage < stackInInventory.getMaxDamage()) {
highestMaxDamage = stackInInventory.getMaxDamage();
best = i;
}
}
return best;
}
public void dropAllItems() {
for (int i = 0; i < this.getSizeInventory(); i++) {
ItemStack stack = this.getStackInSlot(i);
villager.entityDropItem(stack, 1.0F);
}
}
public void readInventoryFromNBT(NBTTagList tagList) {
for (int i = 0; i < this.getSizeInventory(); ++i) {
this.setInventorySlotContents(i, ItemStack.EMPTY);
}
for (int i = 0; i < tagList.tagCount(); ++i) {
NBTTagCompound nbt = tagList.getCompoundTagAt(i);
int slot = nbt.getByte("Slot") & 255;
if (slot < this.getSizeInventory()) {
this.setInventorySlotContents(slot, new ItemStack(nbt));
}
}
}
public NBTTagList writeInventoryToNBT() {
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < this.getSizeInventory(); ++i) {
ItemStack itemstack = this.getStackInSlot(i);
if (itemstack != ItemStack.EMPTY) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setByte("Slot", (byte) i);
itemstack.writeToNBT(nbt);
tagList.appendTag(nbt);
}
}
return tagList;
}
}
================================================
FILE: src/main/java/mca/enums/EnumAgeState.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.core.MCA;
import java.util.Arrays;
import java.util.Optional;
@AllArgsConstructor
@Getter
public enum EnumAgeState {
UNASSIGNED(-1, 0.8f, 2.0f, 1.5f),
BABY(0, 0.3f, 0.5f, 0.4f),
TODDLER(1, 0.3f, 0.6f, 0.5f),
CHILD(2, 0.5f, 1.1f, 1f),
TEEN(3, 0.6f, 1.6f, 1.35f),
ADULT(4, 0.8f, 2f, 1.5f);
int id;
float width;
float height;
float scaleForAge;
public static EnumAgeState byId(int id) {
Optional state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();
return state.orElse(UNASSIGNED);
}
public static EnumAgeState byCurrentAge(int startingAge, int growingAge) {
int step = startingAge / 4;
if (growingAge >= step) return EnumAgeState.TEEN;
else if (growingAge >= step * 2) return EnumAgeState.CHILD;
else if (growingAge >= step * 3 && growingAge < step * 2) return EnumAgeState.TODDLER;
else if (growingAge >= step * 4 && growingAge < step * 3) return EnumAgeState.BABY;
return EnumAgeState.ADULT;
}
public String localizedName() {
return MCA.getLocalizer().localize("enum.agestate." + name().toLowerCase());
}
}
================================================
FILE: src/main/java/mca/enums/EnumChore.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.core.MCA;
import net.minecraft.item.*;
import java.util.Arrays;
import java.util.Optional;
@AllArgsConstructor
public enum EnumChore {
NONE(0, "none", null),
PROSPECT(1, "gui.label.prospecting", ItemPickaxe.class),
HARVEST(2, "gui.label.harvesting", ItemHoe.class),
CHOP(3, "gui.label.chopping", ItemAxe.class),
HUNT(4, "gui.label.hunting", ItemSword.class),
FISH(5, "gui.label.fishing", ItemFishingRod.class);
@Getter int id;
String friendlyName;
@Getter Class toolType;
public static EnumChore byId(int id) {
Optional state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();
return state.orElse(NONE);
}
public String getFriendlyName() {
return MCA.getLocalizer().localize(this.friendlyName);
}
}
================================================
FILE: src/main/java/mca/enums/EnumConstraint.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@AllArgsConstructor
@Getter
public enum EnumConstraint {
FAMILY("family"),
NOT_FAMILY("notfamily"),
ADULTS("adults"),
SPOUSE("spouse"),
NOT_SPOUSE("notspouse"),
HIDE_ON_FAIL("hideonfail");
String id;
public static List fromStringList(String constraints) {
List list = new ArrayList<>();
if (constraints != null && !constraints.isEmpty()) {
String[] splitConstraints = constraints.split("\\|");
for (String s : splitConstraints) {
EnumConstraint constraint = byValue(s);
if (s != null) {
list.add(constraint);
}
}
}
return list;
}
public static EnumConstraint byValue(String value) {
Optional state = Arrays.stream(values()).filter((e) -> e.id.equals(value)).findFirst();
return state.orElse(null);
}
}
================================================
FILE: src/main/java/mca/enums/EnumDialogueType.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@AllArgsConstructor
@Getter
public enum EnumDialogueType {
CHILDP("childp"),
CHILD("child"),
ADULT("adult"),
SPOUSE("spouse");
String id;
public static EnumDialogueType byValue(String value) {
return Arrays.stream(values()).filter(c -> c.getId().equals(value)).findFirst().orElse(null);
}
}
================================================
FILE: src/main/java/mca/enums/EnumGender.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Optional;
import java.util.Random;
@AllArgsConstructor
@Getter
public enum EnumGender {
UNASSIGNED(0, "unassigned"),
MALE(1, "male"),
FEMALE(2, "female");
int id;
String strName;
public static EnumGender byId(int id) {
Optional gender = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();
return gender.orElse(UNASSIGNED);
}
public static EnumGender getRandom() {
return new Random().nextBoolean() ? MALE : FEMALE;
}
public static EnumGender byName(String name) {
Optional gender = Arrays.stream(values()).filter((e) -> e.getStrName().equals(name)).findFirst();
return gender.orElse(UNASSIGNED);
}
}
================================================
FILE: src/main/java/mca/enums/EnumMarriageState.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Optional;
@AllArgsConstructor
@Getter
public enum EnumMarriageState {
NOT_MARRIED(0),
ENGAGED(1),
MARRIED(2);
int id;
public static EnumMarriageState byId(int id) {
Optional state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();
return state.orElse(NOT_MARRIED);
}
}
================================================
FILE: src/main/java/mca/enums/EnumMoveState.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import mca.core.MCA;
import java.util.Arrays;
@AllArgsConstructor
public enum EnumMoveState {
MOVE(0, ""),
STAY(1, "gui.label.staying"),
FOLLOW(2, "gui.label.following");
@Getter int id;
String friendlyName;
public static EnumMoveState byId(int id) {
return Arrays.stream(values()).filter(s -> s.id == id).findFirst().orElse(MOVE);
}
public String getFriendlyName() {
return MCA.getLocalizer().localize(friendlyName);
}
}
================================================
FILE: src/main/java/mca/enums/EnumReaperAttackState.java
================================================
package mca.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@AllArgsConstructor
@Getter
public enum EnumReaperAttackState {
IDLE(0),
PRE(1),
POST(2),
REST(3),
BLOCK(4);
int id;
public static EnumReaperAttackState fromId(int id) {
return Arrays.stream(values()).filter(s -> s.id == id).findFirst().orElse(IDLE);
}
}
================================================
FILE: src/main/java/mca/items/ItemBaby.java
================================================
package mca.items;
import com.google.common.base.Optional;
import mca.api.API;
import mca.core.Constants;
import mca.core.Localizer;
import mca.core.MCA;
import mca.core.minecraft.ProfessionsMCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.ParentData;
import mca.entity.data.PlayerSaveData;
import mca.enums.EnumAgeState;
import mca.enums.EnumDialogueType;
import mca.enums.EnumGender;
import net.minecraft.client.Minecraft;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
public class ItemBaby extends Item {
private boolean isMale;
public ItemBaby(boolean isMale) {
this.isMale = isMale;
this.setMaxStackSize(1);
}
@Override
public void onUpdate(ItemStack itemStack, World world, Entity entity, int unknownInt, boolean unknownBoolean) {
super.onUpdate(itemStack, world, entity, unknownInt, unknownBoolean);
if (!world.isRemote) {
if (!itemStack.hasTagCompound()) {
NBTTagCompound compound = new NBTTagCompound();
compound.setString("name", "");
compound.setInteger("age", 0);
compound.setUniqueId("ownerUUID", entity.getUniqueID());
compound.setString("ownerName", entity.getName());
compound.setBoolean("isInfected", false);
itemStack.setTagCompound(compound);
} else {
updateBabyGrowth(itemStack);
}
}
}
@Override
public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
BlockPos pos = player.getPosition();
ItemStack stack = player.getHeldItem(hand);
int posX = pos.getX();
int posY = pos.getY() + 1;
int posZ = pos.getZ();
// Right-clicking an unnamed baby allows you to name it
if (world.isRemote && getBabyName(stack).equals(""))
player.openGui(MCA.getInstance(), Constants.GUI_ID_NAMEBABY, player.world, player.getEntityId(), 0, 0);
if (!world.isRemote) {
if (isReadyToGrowUp(stack) && !getBabyName(stack).equals("")) { // Name is good and we're ready to grow
EntityVillagerMCA child = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.child), Optional.of(this.isMale ? EnumGender.MALE : EnumGender.FEMALE));
child.set(EntityVillagerMCA.VILLAGER_NAME, getBabyName(stack));
child.set(EntityVillagerMCA.TEXTURE, API.getRandomSkin(child)); // allow for special-case skins to be applied with the proper name attached to the child at this point
child.set(EntityVillagerMCA.AGE_STATE, EnumAgeState.BABY.getId());
child.setStartingAge(MCA.getConfig().childGrowUpTime * 60 * 20 * -1);
child.setScaleForAge(true);
child.setPosition(posX, posY, posZ);
world.spawnEntity(child);
PlayerSaveData playerData = PlayerSaveData.get(player);
child.set(EntityVillagerMCA.PARENTS, ParentData.create(player.getUniqueID(), playerData.getSpouseUUID(), player.getName(), playerData.getSpouseName()).toNBT());
player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);
playerData.setBabyPresent(false);
// set proper dialogue type
child.getPlayerHistoryFor(player.getUniqueID()).setDialogueType(EnumDialogueType.CHILDP);
}
}
return super.onItemRightClick(world, player, hand);
}
private String getBabyName(ItemStack stack) {
return stack.getTagCompound().getString("name");
}
@Override
public boolean onEntityItemUpdate(EntityItem entityItem) {
if (!entityItem.world.isRemote) {
updateBabyGrowth(entityItem.getItem());
}
return super.onEntityItemUpdate(entityItem);
}
@SideOnly(Side.CLIENT)
@Override
public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
super.addInformation(stack, worldIn, tooltip, flagIn);
Localizer loc = MCA.getLocalizer();
if (stack.hasTagCompound()) {
EntityPlayer player = Minecraft.getMinecraft().player;
NBTTagCompound nbt = stack.getTagCompound();
String textColor = ((ItemBaby) stack.getItem()).isMale ? Constants.Color.AQUA : Constants.Color.LIGHTPURPLE;
int ageInMinutes = nbt.getInteger("age");
String ownerName = nbt.getUniqueId("ownerUUID").equals(player.getUniqueID()) ? MCA.getLocalizer().localize("label.you") : nbt.getString("ownerName");
if (getBabyName(stack).equals(""))
tooltip.add(textColor + loc.localize("gui.label.name") + " " + Constants.Format.RESET + MCA.getLocalizer().localize("label.unnamed"));
else
tooltip.add(textColor + loc.localize("gui.label.name") + " " + Constants.Format.RESET + nbt.getString("name"));
tooltip.add(textColor + loc.localize("gui.label.age") + " " + Constants.Format.RESET + ageInMinutes + " " + (ageInMinutes == 1 ? loc.localize("gui.label.minute") : loc.localize("gui.label.minutes")));
tooltip.add(textColor + loc.localize("gui.label.parent") + " " + Constants.Format.RESET + ownerName);
if (nbt.getBoolean("isInfected")) tooltip.add(Constants.Color.GREEN + loc.localize("gui.label.infected"));
if (isReadyToGrowUp(stack)) tooltip.add(Constants.Color.GREEN + loc.localize("gui.label.readytogrow"));
if (nbt.getString("name").equals(loc.localize("gui.label.unnamed"))) tooltip.add(Constants.Color.YELLOW + loc.localize("gui.label.rightclicktoname"));
}
}
private void updateBabyGrowth(ItemStack itemStack) {
if (itemStack.hasTagCompound() && FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter() % 1200 == 0) {
int age = itemStack.getTagCompound().getInteger("age");
age++;
itemStack.getTagCompound().setInteger("age", age);
}
}
private boolean isReadyToGrowUp(ItemStack itemStack) {
return itemStack.getTagCompound().getInteger("age") >= MCA.getConfig().babyGrowUpTime;
}
public EnumGender getGender() {
return isMale ? EnumGender.MALE : EnumGender.FEMALE;
}
}
================================================
FILE: src/main/java/mca/items/ItemEngagementRing.java
================================================
package mca.items;
import mca.entity.EntityVillagerMCA;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.util.List;
public class ItemEngagementRing extends ItemWeddingRing {
public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {
return super.handle(player, villager);
}
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) {
tooltip.add("Halves the hearts required to marry someone.");
}
}
================================================
FILE: src/main/java/mca/items/ItemGuideBook.java
================================================
package mca.items;
import mca.core.Constants;
import mca.core.MCA;
import mca.core.minecraft.ItemsMCA;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemWrittenBook;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.play.server.SPacketSetSlot;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentUtils;
import net.minecraft.world.World;
public class ItemGuideBook extends ItemWrittenBook {
public ItemGuideBook() {
super();
}
@Override
public void onUpdate(ItemStack itemStack, World world, Entity entity, int unknownInt, boolean unknownBoolean) {
super.onUpdate(itemStack, world, entity, unknownInt, unknownBoolean);
if (!world.isRemote && !itemStack.hasTagCompound()) ItemsMCA.setBookNBT(itemStack);
}
@Override
public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
ItemStack itemstack = playerIn.getHeldItem(handIn);
if (worldIn.isRemote) {
playerIn.openGui(MCA.getInstance(), Constants.GUI_ID_GUIDEBOOK, worldIn, (int)playerIn.posX, (int)playerIn.posY, (int)playerIn.posZ);
}
return new ActionResult(EnumActionResult.SUCCESS, itemstack);
}
private void resolveContents(ItemStack stack, EntityPlayer player) {
if (stack.getTagCompound() != null) {
NBTTagCompound nbttagcompound = stack.getTagCompound();
if (!nbttagcompound.getBoolean("resolved")) {
nbttagcompound.setBoolean("resolved", true);
if (validBookTagContents(nbttagcompound)) {
NBTTagList nbttaglist = nbttagcompound.getTagList("pages", 8);
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
String s = nbttaglist.getStringTagAt(i);
ITextComponent itextcomponent;
try {
itextcomponent = ITextComponent.Serializer.fromJsonLenient(s);
itextcomponent = TextComponentUtils.processComponent(player, itextcomponent, player);
} catch (Exception var9) {
itextcomponent = new TextComponentString(s);
}
nbttaglist.set(i, new NBTTagString(ITextComponent.Serializer.componentToJson(itextcomponent)));
}
nbttagcompound.setTag("pages", nbttaglist);
if (player instanceof EntityPlayerMP && player.getHeldItemMainhand() == stack) {
Slot slot = player.openContainer.getSlotFromInventory(player.inventory, player.inventory.currentItem);
((EntityPlayerMP)player).connection.sendPacket(new SPacketSetSlot(0, slot.slotNumber, stack));
}
}
}
}
}
}
================================================
FILE: src/main/java/mca/items/ItemMatchmakersRing.java
================================================
package mca.items;
import com.google.common.base.Optional;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumMarriageState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumParticleTypes;
import java.util.Comparator;
import java.util.List;
public class ItemMatchmakersRing extends ItemSpecialCaseGift {
public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {
// ensure two rings are in the inventory
if (player.inventory.getStackInSlot(player.inventory.currentItem).getCount() < 2) {
villager.say(Optional.of(player), "interaction.matchmaker.fail.needtwo");
return false;
}
// ensure our target isn't married already
if (villager.isMarried()) {
villager.say(Optional.of(player), "interaction.matchmaker.fail.married");
return false;
}
List villagers = villager.world.getEntities(EntityVillagerMCA.class, v -> v != null && !v.isMarried() && !v.isChild() && v.getDistance(villager) < 3.0D && v != villager);
java.util.Optional target = villagers.stream().min(Comparator.comparingDouble(villager::getDistance));
// ensure we found a nearby villager
if (!target.isPresent()) {
villager.say(Optional.of(player), "interaction.matchmaker.fail.novillagers");
return false;
}
// setup the marriage by assigning spouse UUIDs
EntityVillagerMCA spouse = target.get();
villager.set(EntityVillagerMCA.SPOUSE_UUID, Optional.of(target.get().getUniqueID()));
villager.set(EntityVillagerMCA.MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());
villager.set(EntityVillagerMCA.SPOUSE_NAME, spouse.get(EntityVillagerMCA.VILLAGER_NAME));
spouse.set(EntityVillagerMCA.SPOUSE_UUID, Optional.of(villager.getUniqueID()));
spouse.set(EntityVillagerMCA.MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());
spouse.set(EntityVillagerMCA.SPOUSE_NAME, villager.get(EntityVillagerMCA.VILLAGER_NAME));
// spawn hearts to show something happened
villager.spawnParticles(EnumParticleTypes.HEART);
target.get().spawnParticles(EnumParticleTypes.HEART);
// remove the rings for survival mode
if (!player.isCreative()) player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);
return true;
}
}
================================================
FILE: src/main/java/mca/items/ItemSpawnEgg.java
================================================
package mca.items;
import com.google.common.base.Optional;
import mca.entity.EntityVillagerMCA;
import mca.enums.EnumGender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ItemSpawnEgg extends Item {
private boolean isMale;
public ItemSpawnEgg(boolean isMale) {
this.isMale = isMale;
this.setMaxStackSize(1);
}
@Override
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
int posX = pos.getX();
int posY = pos.getY() + 1;
int posZ = pos.getZ();
if (!world.isRemote) {
EntityVillagerMCA villager = new EntityVillagerMCA(world, Optional.absent(), Optional.of(isMale ? EnumGender.MALE : EnumGender.FEMALE));
villager.setPosition(posX + 0.5D, posY, posZ + 0.5D);
villager.finalizeMobSpawn(world.getDifficultyForLocation(villager.getPos()), null, false);
world.spawnEntity(villager);
if (!player.capabilities.isCreativeMode) player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);
}
return EnumActionResult.PASS;
}
}
================================================
FILE: src/main/java/mca/items/ItemSpecialCaseGift.java
================================================
package mca.items;
import mca.entity.EntityVillagerMCA;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
public abstract class ItemSpecialCaseGift extends Item {
public abstract boolean handle(EntityPlayer player, EntityVillagerMCA villager);
}
================================================
FILE: src/main/java/mca/items/ItemStaffOfLife.java
================================================
package mca.items;
import mca.core.Constants;
import mca.core.MCA;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import javax.annotation.Nullable;
import java.util.List;
public class ItemStaffOfLife extends Item {
public ItemStaffOfLife() {
super();
maxStackSize = 1;
setUnlocalizedName("staff_of_life");
setMaxDamage(4);
}
@Override
public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
if (!MCA.getConfig().enableRevivals)
playerIn.sendMessage(new TextComponentString(MCA.getLocalizer().localize("notify.revival.disabled")));
playerIn.openGui(MCA.getInstance(), Constants.GUI_ID_STAFFOFLIFE, playerIn.world, 0, 0, 0);
return super.onItemRightClick(worldIn, playerIn, handIn);
}
@Override
public void addInformation(ItemStack itemStack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) {
tooltip.add("Uses left: " + (itemStack.getMaxDamage() - itemStack.getItemDamage() + 1));
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
tooltip.add("Use to revive a previously dead");
tooltip.add("villager, but all of their memories");
tooltip.add("will be forgotten.");
} else tooltip.add("Hold " + Constants.Color.YELLOW + "SHIFT" + Constants.Color.GRAY + " for info.");
}
@SideOnly(Side.CLIENT)
@Override
public boolean hasEffect(ItemStack itemStack) {
return true;
}
}
================================================
FILE: src/main/java/mca/items/ItemVillagerEditor.java
================================================
package mca.items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemVillagerEditor extends Item {
public ItemVillagerEditor() {
super();
maxStackSize = 1;
setUnlocalizedName("villager_editor");
}
@SideOnly(Side.CLIENT)
@Override
public boolean hasEffect(ItemStack itemStack) {
return true;
}
}
================================================
FILE: src/main/java/mca/items/ItemWeddingRing.java
================================================
package mca.items;
import com.google.common.base.Optional;
import mca.core.MCA;
import mca.entity.EntityVillagerMCA;
import mca.entity.data.PlayerHistory;
import mca.entity.data.PlayerSaveData;
import mca.enums.EnumDialogueType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumParticleTypes;
public class ItemWeddingRing extends ItemSpecialCaseGift {
public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {
PlayerSaveData playerData = PlayerSaveData.get(player);
PlayerHistory history = villager.getPlayerHistoryFor(player.getUniqueID());
String response;
if (villager.isMarriedTo(player.getUniqueID()))
response = "interaction.marry.fail.marriedtogiver";
else if (villager.isMarried())
response = "interaction.marry.fail.marriedtoother";
else if (playerData.isMarriedOrEngaged())
response = "interaction.marry.fail.marriedtoother";
else if (this instanceof ItemEngagementRing && history.getHearts() < MCA.getConfig().marriageHeartsRequirement / 2)
response = "interaction.marry.fail.lowhearts";
else if (!(this instanceof ItemEngagementRing) && history.getHearts() < MCA.getConfig().marriageHeartsRequirement)
response = "interaction.marry.fail.lowhearts";
else {
response = "interaction.marry.success";
playerData.marry(villager.getUniqueID(), villager.get(EntityVillagerMCA.VILLAGER_NAME));
villager.getPlayerHistoryFor(player.getUniqueID()).setDialogueType(EnumDialogueType.SPOUSE);
villager.spawnParticles(EnumParticleTypes.HEART);
villager.marry(player);
}
villager.say(Optional.of(player), response);
return false;
}
}
================================================
FILE: src/main/java/mca/items/ItemWhistle.java
================================================
package mca.items;
import java.util.List;
import mca.core.Constants;
import mca.core.MCA;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ItemWhistle extends Item {
public ItemWhistle() {
super();
maxStackSize = 1;
}
@Override
public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
player.openGui(MCA.getInstance(), Constants.GUI_ID_WHISTLE, world, (int)player.posX, (int)player.posY, (int)player.posZ);
return super.onItemRightClick(world, player, hand);
}
@Override
public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
super.addInformation(stack, worldIn, tooltip, flagIn);
tooltip.add("Allows you to call your family to your current location.");
}
}
================================================
FILE: src/main/java/mca/server/ServerMessageHandler.java
================================================
package mca.server;
import mca.core.forge.NetMCA;
import mca.core.minecraft.VillageHelper;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextComponentString;
public class ServerMessageHandler {
public static void handleMessage(EntityPlayerMP player, NetMCA.ButtonAction message) {
switch (message.getButtonId()) {
case "gui.button.debug.startraid":
startRaid(player);
break;
case "gui.button.debug.spawnguards":
spawnGuards(player);
break;
case "gui.button.debug.rebuildvillage":
rebuildVillage(player);
break;
}
}
private static void startRaid(EntityPlayerMP player) {
player.sendMessage(new TextComponentString("Starting raid on village..."));
VillageHelper.forceRaid(player);
}
private static void spawnGuards(EntityPlayerMP player) {
player.sendMessage(new TextComponentString("Spawning village guards..."));
VillageHelper.tick(player.world);
}
private static void rebuildVillage(EntityPlayerMP player) {
player.sendMessage(new TextComponentString("Rebuilding annihilated village..."));
}
}
================================================
FILE: src/main/java/mca/util/ItemStackCache.java
================================================
package mca.util;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import java.util.HashMap;
import java.util.Map;
public class ItemStackCache {
private static Map
- cache = new HashMap<>();
public static ItemStack get(Item item) {
if (!cache.containsKey(item)) cache.put(item, new ItemStack(item, 1));
return cache.get(item);
}
}
================================================
FILE: src/main/java/mca/util/ResourceLocationCache.java
================================================
package mca.util;
import net.minecraft.util.ResourceLocation;
import java.util.HashMap;
import java.util.Map;
public class ResourceLocationCache {
private static Map cache = new HashMap<>();
public static ResourceLocation getResourceLocationFor(String location) {
if (cache.containsKey(location)) {
return cache.get(location);
} else {
ResourceLocation rLoc = new ResourceLocation(location);
cache.put(location, rLoc);
return rLoc;
}
}
}
================================================
FILE: src/main/java/mca/util/Util.java
================================================
package mca.util;
import com.google.common.base.Optional;
import com.google.gson.Gson;
import mca.core.MCA;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.commons.io.IOUtils;
import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static org.apache.http.protocol.HTTP.USER_AGENT;
public class Util {
private static final String RESOURCE_PREFIX = "assets/mca/";
/**
* Finds a y position given an x,y,z coordinate triple that is assumed to be the world's "ground".
*
* @param world The world in which blocks will be tested
* @param x X coordinate
* @param y Y coordinate, used as the starting height for finding ground.
* @param z Z coordinate
* @return Integer representing the air block above the first non-air block given the provided ordered triples.
*/
public static int getSpawnSafeTopLevel(World world, int x, int y, int z)
{
Block block = Blocks.AIR;
while (block == Blocks.AIR && y > 0) {
y--;
block = world.getBlockState(new BlockPos(x, y, z)).getBlock();
}
return y + 1;
}
public static String readResource(String path) {
String data;
String location = RESOURCE_PREFIX + path;
try {
data = IOUtils.toString(new InputStreamReader(MCA.class.getClassLoader().getResourceAsStream(location)));
} catch (IOException e) {
throw new RuntimeException("Failed to read resource from JAR: " + location);
}
return data;
}
public static T readResourceAsJSON(String path, Class type) {
Gson gson = new Gson();
T data = gson.fromJson(Util.readResource(path), type);
return data;
}
public static Optional getEntityByUUID(World world, UUID uuid) {
for (Entity entity : world.loadedEntityList) {
if (entity.getUniqueID().equals(uuid)) {
return Optional.of(entity);
}
}
return Optional.absent();
}
public static Optional getEntityByUUID(World world, UUID uuid, Class extends T> clazz) {
for (Entity entity : world.loadedEntityList) {
if (entity.getClass().isAssignableFrom(clazz) && entity.getUniqueID().equals(uuid)) {
return Optional.of((T) entity);
}
}
return Optional.absent();
}
public static List getNearbyBlocks(BlockPos origin, World world, @Nullable Class filter, int xzDist, int yDist) {
final List pointsList = new ArrayList<>();
for (int x = -xzDist; x <= xzDist; x++) {
for (int y = -yDist; y <= yDist; y++) {
for (int z = -xzDist; z <= xzDist; z++) {
if (x != 0 || y != 0 || z != 0) {
BlockPos pos = new BlockPos(origin.getX() + x, origin.getY() + y, origin.getZ() + z);
if (filter != null && filter.isAssignableFrom(world.getBlockState(pos).getBlock().getClass())) {
pointsList.add(pos);
} else if (filter == null) {
pointsList.add(pos);
}
}
}
}
}
return pointsList;
}
public static BlockPos getNearestPoint(BlockPos origin, List blocks) {
double closest = 100.0D;
BlockPos returnPoint = null;
for (BlockPos point : blocks) {
double distance = origin.getDistance(point.getX(), point.getY(), point.getZ());
if (distance < closest) {
closest = distance;
returnPoint = point;
}
}
return returnPoint;
}
public static String httpGet(String url) {
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
} catch (IOException ignored) {
MCA.getLog().error("Failed to GET from: " + url);
}
return "";
}
}
================================================
FILE: src/main/resources/assets/mca/api/gifts.json
================================================
[
{"type":"item", "name":"minecraft:wooden_sword", "value":3},
{"type":"item", "name":"minecraft:wooden_axe", "value":3},
{"type":"item", "name":"minecraft:wooden_hoe", "value":3},
{"type":"item", "name":"minecraft:wooden_shovel", "value":3},
{"type":"item", "name":"minecraft:stone_sword", "value":6},
{"type":"item", "name":"minecraft:stone_axe", "value":6},
{"type":"item", "name":"minecraft:stone_hoe", "value":6},
{"type":"item", "name":"minecraft:stone_shovel", "value":6},
{"type":"item", "name":"minecraft:wooden_pickaxe", "value":3},
{"type":"item", "name":"minecraft:beef", "value":5},
{"type":"item", "name":"minecraft:chicken", "value":5},
{"type":"item", "name":"minecraft:porkchop", "value":5},
{"type":"item", "name":"minecraft:leather", "value":3},
{"type":"item", "name":"minecraft:leather_chestplate", "value":3},
{"type":"item", "name":"minecraft:leather_helmet", "value":3},
{"type":"item", "name":"minecraft:leather_leggings", "value":3},
{"type":"item", "name":"minecraft:leather_boots", "value":3},
{"type":"item", "name":"minecraft:reeds", "value":2},
{"type":"item", "name":"minecraft:wheat_seeds", "value":1},
{"type":"item", "name":"minecraft:wheat", "value":1},
{"type":"item", "name":"minecraft:bread", "value":3},
{"type":"item", "name":"minecraft:coal", "value":5},
{"type":"item", "name":"minecraft:sugar", "value":5},
{"type":"item", "name":"minecraft:clay_ball", "value":0},
{"type":"item", "name":"minecraft:dye", "value":1},
{"type":"item", "name":"minecraft:cooked_beef", "value":5},
{"type":"item", "name":"minecraft:cooked_chicken", "value":5},
{"type":"item", "name":"minecraft:cooked_porkchop", "value":5},
{"type":"item", "name":"minecraft:cookie", "value":10},
{"type":"item", "name":"minecraft:melon", "value":5},
{"type":"item", "name":"minecraft:melon_seeds", "value":1},
{"type":"item", "name":"minecraft:iron_helmet", "value":5},
{"type":"item", "name":"minecraft:iron_chestplate", "value":5},
{"type":"item", "name":"minecraft:iron_leggings", "value":5},
{"type":"item", "name":"minecraft:iron_boots", "value":5},
{"type":"item", "name":"minecraft:cake", "value":15},
{"type":"item", "name":"minecraft:iron_sword", "value":5},
{"type":"item", "name":"minecraft:iron_axe", "value":5},
{"type":"item", "name":"minecraft:iron_hoe", "value":5},
{"type":"item", "name":"minecraft:iron_pickaxe", "value":5},
{"type":"item", "name":"minecraft:iron_shovel", "value":5},
{"type":"item", "name":"minecraft:fishing_rod", "value":1},
{"type":"item", "name":"minecraft:bow", "value":3},
{"type":"item", "name":"minecraft:book", "value":5},
{"type":"item", "name":"minecraft:bucket", "value":0},
{"type":"item", "name":"minecraft:milk_bucket", "value":3},
{"type":"item", "name":"minecraft:water_bucket", "value":0},
{"type":"item", "name":"minecraft:lava_bucket", "value":0},
{"type":"item", "name":"minecraft:mushroom_stew", "value":10},
{"type":"item", "name":"minecraft:pumpkin_seeds", "value":2},
{"type":"item", "name":"minecraft:flint_and_steel", "value":3},
{"type":"item", "name":"minecraft:redstone", "value":2},
{"type":"item", "name":"minecraft:boat", "value":3},
{"type":"item", "name":"minecraft:iron_door", "value":0},
{"type":"item", "name":"minecraft:minecart", "value":0},
{"type":"item", "name":"minecraft:flint", "value":0},
{"type":"item", "name":"minecraft:gold_nugget", "value":5},
{"type":"item", "name":"minecraft:gold_ingot", "value":8},
{"type":"item", "name":"minecraft:iron_ingot", "value":4},
{"type":"item", "name":"minecraft:diamond", "value":15},
{"type":"item", "name":"minecraft:map", "value":0},
{"type":"item", "name":"minecraft:clock", "value":3},
{"type":"item", "name":"minecraft:compass", "value":3},
{"type":"item", "name":"minecraft:blaze_rod", "value":10},
{"type":"item", "name":"minecraft:blaze_powder", "value":6},
{"type":"item", "name":"minecraft:diamond_sword", "value":10},
{"type":"item", "name":"minecraft:diamond_axe", "value":10},
{"type":"item", "name":"minecraft:diamond_shovel", "value":10},
{"type":"item", "name":"minecraft:diamond_hoe", "value":10},
{"type":"item", "name":"minecraft:diamond_helmet", "value":10},
{"type":"item", "name":"minecraft:diamond_chestplate", "value":10},
{"type":"item", "name":"minecraft:diamond_leggings", "value":10},
{"type":"item", "name":"minecraft:diamond_boots", "value":10},
{"type":"item", "name":"minecraft:painting", "value":10},
{"type":"item", "name":"minecraft:ender_pearl", "value":15},
{"type":"item", "name":"minecraft:ender_eye", "value":25},
{"type":"item", "name":"minecraft:slime_ball", "value":0},
{"type":"item", "name":"minecraft:saddle", "value":3},
{"type":"item", "name":"minecraft:gunpowder", "value":5},
{"type":"item", "name":"minecraft:golden_apple", "value":25},
{"type":"item", "name":"minecraft:record_11", "value":15},
{"type":"item", "name":"minecraft:record_13", "value":15},
{"type":"item", "name":"minecraft:record_wait", "value":15},
{"type":"item", "name":"minecraft:record_cat", "value":15},
{"type":"item", "name":"minecraft:record_chirp", "value":15},
{"type":"item", "name":"minecraft:record_far", "value":15},
{"type":"item", "name":"minecraft:record_mall", "value":15},
{"type":"item", "name":"minecraft:record_mellohi", "value":15},
{"type":"item", "name":"minecraft:record_stal", "value":15},
{"type":"item", "name":"minecraft:record_strad", "value":15},
{"type":"item", "name":"minecraft:record_ward", "value":15},
{"type":"item", "name":"minecraft:emerald", "value":25},
{"type":"block","name":"minecraft:red_flower","value":2},
{"type":"block","name":"minecraft:yellow_flower","value":2},
{"type":"block","name":"minecraft:planks","value":1},
{"type":"block","name":"minecraft:log","value":1},
{"type":"block","name":"minecraft:pumpkin","value":3},
{"type":"block","name":"minecraft:chest","value":6},
{"type":"block","name":"minecraft:wool","value":3},
{"type":"block","name":"minecraft:iron_ore","value":3},
{"type":"block","name":"minecraft:gold_ore","value":5},
{"type":"block","name":"minecraft:redstone_ore","value":3},
{"type":"block","name":"minecraft:rail","value":5},
{"type":"block","name":"minecraft:detector_rail","value":7},
{"type":"block","name":"minecraft:activator_rail","value":7},
{"type":"block","name":"minecraft:furnace","value":5},
{"type":"block","name":"minecraft:crafting_table","value":3},
{"type":"block","name":"minecraft:lapis_block","value":15},
{"type":"block","name":"minecraft:bookshelf","value":5},
{"type":"block","name":"minecraft:gold_block","value":15},
{"type":"block","name":"minecraft:iron_block","value":10},
{"type":"block","name":"minecraft:diamond_block","value":25},
{"type":"block","name":"minecraft:brewing_stand","value":5},
{"type":"block","name":"minecraft:enchanting_table","value":5},
{"type":"block","name":"minecraft:brick_block","value":3},
{"type":"block","name":"minecraft:obsidian","value":9},
{"type":"block","name":"minecraft:piston","value":6},
{"type":"block","name":"minecraft:glowstone","value":5},
{"type":"block","name":"minecraft:emerald_block","value":25},
{"type":"block","name":"minecraft:redstone_block","value":15},
{"type":"block","name":"mca:rose_gold_block","value":10},
{"type":"block","name":"mca:rose_gold_ore","value":10}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/debug.json
================================================
[
{
"id": 1,
"identifier": "gui.button.debug.startraid",
"x": 120,
"y": -115,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": true,
"constraints": ""
},
{
"id": 2,
"identifier": "gui.button.debug.spawnguards",
"x": 120,
"y": -93,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": true,
"constraints": ""
},
{
"id": 3,
"identifier": "gui.button.debug.selectnearestvillager",
"x": 120,
"y": -71,
"width": 85,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 4,
"identifier": "gui.button.debug.startmining",
"x": 120,
"y": -49,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 5,
"identifier": "gui.button.debug.startfishing",
"x": 120,
"y": -27,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 6,
"identifier": "gui.button.debug.startchopping",
"x": 120,
"y": -5,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 7,
"identifier": "gui.button.debug.starthunting",
"x": 120,
"y": 17,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 8,
"identifier": "gui.button.debug.startharvesting",
"x": 120,
"y": 39,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 9,
"identifier": "gui.button.debug.zombify",
"x": 10,
"y": -115,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 10,
"identifier": "gui.button.debug.unzombify",
"x": 10,
"y": -93,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 11,
"identifier": "gui.button.debug.marrytoplayer",
"x": 10,
"y": -71,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 12,
"identifier": "gui.button.debug.rebuildvillage",
"x": 10,
"y": -49,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": true,
"constraints": ""
},
{
"id": 13,
"identifier": "gui.button.debug.openinventory",
"x": 10,
"y": -27,
"width": 85,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/editor.json
================================================
[
{
"id": 1,
"identifier": "gui.button.random",
"x": -50,
"y": -95,
"width": 60,
"height": 20,
"notifyServer": true
},
{
"id": 2,
"identifier": "gui.button.gender",
"x": -190,
"y": -40,
"width": 175,
"height": 20,
"notifyServer": true
},
{
"id": 3,
"identifier": "gui.button.texture.set",
"x": 70,
"y": -15,
"width": 60,
"height": 20
},
{
"id": 4,
"identifier": "gui.button.texture.randomize",
"x": 140,
"y": -15,
"width": 60,
"height": 20,
"notifyServer": true
},
{
"id": 5,
"identifier": "gui.button.profession.set",
"x": 70,
"y": 10,
"width": 60,
"height": 20
},
{
"id": 6,
"identifier": "gui.button.profession.randomize",
"x": 140,
"y": 10,
"width": 60,
"height": 20,
"notifyServer": true
},
{
"id": 7,
"identifier": "gui.button.infected",
"x": -190,
"y": 35,
"width": 175,
"height": 20,
"notifyServer": true
},
{
"id": 8,
"identifier": "gui.button.done",
"x": -65,
"y": 85,
"width": 75,
"height": 20
},
{
"id": 9,
"identifier": "gui.button.copyuuid",
"x": 25,
"y": 85,
"width": 75,
"height": 20
}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/interact.json
================================================
[
{
"id": 1,
"identifier": "gui.button.backarrow",
"x": 120,
"y": -115,
"width": 15,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 1,
"identifier": "gui.button.chat",
"x": 140,
"y": -115,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "",
"isInteraction": true
},
{
"id": 2,
"identifier": "gui.button.joke",
"x": 140,
"y": -93,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "",
"isInteraction": true
},
{
"id": 3,
"identifier": "gui.button.gift",
"x": 140,
"y": -71,
"width": 65,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 4,
"identifier": "gui.button.shakehand",
"x": 140,
"y": -49,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "",
"isInteraction": true
},
{
"id": 5,
"identifier": "gui.button.tellstory",
"x": 140,
"y": -27,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "",
"isInteraction": true
},
{
"id": 6,
"identifier": "gui.button.flirt",
"x": 140,
"y": -5,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "adults",
"isInteraction": true
},
{
"id": 7,
"identifier": "gui.button.hug",
"x": 140,
"y": 17,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "adults",
"isInteraction": true
},
{
"id": 8,
"identifier": "gui.button.kiss",
"x": 140,
"y": 39,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "adults",
"isInteraction": true
}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/location.json
================================================
[
{
"id": 1,
"identifier": "gui.button.backarrow",
"x": 140,
"y": -115,
"width": 65,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 2,
"identifier": "gui.button.sethome",
"x": 140,
"y": -93,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 3,
"identifier": "gui.button.setworkplace",
"x": 140,
"y": -71,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 4,
"identifier": "gui.button.sethangout",
"x": 140,
"y": -49,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/main.json
================================================
[
{
"id": 1,
"identifier": "gui.button.interact",
"x": 140,
"y": -115,
"width": 65,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 2,
"identifier": "gui.button.follow",
"x": 140,
"y": -93,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 3,
"identifier": "gui.button.stay",
"x": 140,
"y": -71,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 4,
"identifier": "gui.button.move",
"x": 140,
"y": -49,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 5,
"identifier": "gui.button.trade",
"x": 140,
"y": -27,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "notfamily|hideonfail"
},
{
"id": 12,
"identifier": "gui.button.inventory",
"x": 140,
"y": -27,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "family|hideonfail"
},
{
"id": 6,
"identifier": "gui.button.location",
"x": 140,
"y": -5,
"width": 65,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 7,
"identifier": "gui.button.gohome",
"x": 140,
"y": 17,
"width": 65,
"height": 20,
"notifyServer": true,
"spouseOnly": false,
"targetServer": false,
"constraints": ""
},
{
"id": 8,
"identifier": "gui.button.ridehorse",
"x": 140,
"y": 39,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 9,
"identifier": "gui.button.work",
"x": 140,
"y": 61,
"width": 65,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": "family|hideonfail"
},
{
"id": 10,
"identifier": "gui.button.procreate",
"x": 140,
"y": 83,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": "spouse|hideonfail"
}
]
================================================
FILE: src/main/resources/assets/mca/api/gui/work.json
================================================
[
{
"id": 1,
"identifier": "gui.button.backarrow",
"x": 140,
"y": -115,
"width": 15,
"height": 20,
"notifyServer": false,
"targetServer": false,
"constraints": ""
},
{
"id": 2,
"identifier": "gui.button.fishing",
"x": 140,
"y": -115,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 3,
"identifier": "gui.button.harvesting",
"x": 140,
"y": -93,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 4,
"identifier": "gui.button.hunting",
"x": 140,
"y": -71,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 5,
"identifier": "gui.button.prospecting",
"x": 140,
"y": -49,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 5,
"identifier": "gui.button.chopping",
"x": 140,
"y": -27,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
},
{
"id": 6,
"identifier": "gui.button.stopworking",
"x": 140,
"y": -5,
"width": 65,
"height": 20,
"notifyServer": true,
"targetServer": false,
"constraints": ""
}
]
================================================
FILE: src/main/resources/assets/mca/api/skins.json
================================================
[
{
"gender": "male",
"profession": "minecraft:farmer",
"paths": [
"mca:skins/male/farmer/farmerm1_converted.png",
"mca:skins/male/farmer/farmerm2_converted.png",
"mca:skins/male/farmer/farmerm3_converted.png",
"mca:skins/male/farmer/farmerm4_converted.png",
"mca:skins/male/farmer/farmerm5_converted.png",
"mca:skins/male/farmer/farmerm6_converted.png",
"mca:skins/male/farmer/farmerm7_converted.png",
"mca:skins/male/farmer/farmerm8_converted.png",
"mca:skins/male/farmer/farmerm9_converted.png",
"mca:skins/male/farmer/farmerm10_converted.png",
"mca:skins/male/farmer/farmerm11_converted.png",
"mca:skins/male/farmer/farmerm12_converted.png",
"mca:skins/male/farmer/farmerm13_converted.png",
"mca:skins/male/farmer/farmerm14_converted.png",
"mca:skins/male/farmer/farmerm15_converted.png",
"mca:skins/male/farmer/farmerm16_converted.png",
"mca:skins/male/farmer/farmerm17_converted.png",
"mca:skins/male/farmer/farmerm18_converted.png",
"mca:skins/male/farmer/farmerm19_converted.png",
"mca:skins/male/farmer/farmerm20_converted.png",
"mca:skins/male/farmer/farmerm21_converted.png",
"mca:skins/male/farmer/farmerm23_converted.png",
"mca:skins/male/farmer/farmerm25_converted.png"
]
},
{
"gender": "female",
"profession": "minecraft:farmer",
"paths": [
"mca:skins/female/farmer/farmerf1_converted.png",
"mca:skins/female/farmer/farmerf2_converted.png",
"mca:skins/female/farmer/farmerf3_converted.png",
"mca:skins/female/farmer/farmerf4_converted.png",
"mca:skins/female/farmer/farmerf5_converted.png",
"mca:skins/female/farmer/farmerf6_converted.png",
"mca:skins/female/farmer/farmerf7_converted.png",
"mca:skins/female/farmer/farmerf8_converted.png",
"mca:skins/female/farmer/farmerf9_converted.png",
"mca:skins/female/farmer/farmerf10_converted.png",
"mca:skins/female/farmer/farmerf11_converted.png",
"mca:skins/female/farmer/farmerf12_converted.png",
"mca:skins/female/farmer/farmerf13_converted.png",
"mca:skins/female/farmer/farmerf14_converted.png",
"mca:skins/female/farmer/farmerf15_converted.png",
"mca:skins/female/farmer/farmerf16_converted.png",
"mca:skins/female/farmer/farmerf17_converted.png",
"mca:skins/female/farmer/farmerf18_converted.png",
"mca:skins/female/farmer/farmerf19_converted.png",
"mca:skins/female/farmer/farmerf20_converted.png",
"mca:skins/female/farmer/farmerf21_converted.png",
"mca:skins/female/farmer/farmerf22_converted.png",
"mca:skins/female/farmer/farmerf23_converted.png",
"mca:skins/female/farmer/farmerf24_converted.png",
"mca:skins/female/farmer/farmerf25_converted.png"
]
},
{
"gender": "male",
"profession": "minecraft:librarian",
"paths": [
"mca:skins/male/librarian/librarianm1_converted.png",
"mca:skins/male/librarian/librarianm2_converted.png",
"mca:skins/male/librarian/librarianm3_converted.png",
"mca:skins/male/librarian/librarianm4_converted.png",
"mca:skins/male/librarian/librarianm5_converted.png",
"mca:skins/male/librarian/librarianm6_converted.png",
"mca:skins/male/librarian/librarianm7_converted.png",
"mca:skins/male/librarian/librarianm8_converted.png",
"mca:skins/male/librarian/librarianm9_converted.png",
"mca:skins/male/librarian/librarianm10_converted.png",
"mca:skins/male/librarian/librarianm11_converted.png",
"mca:skins/male/librarian/librarianm12_converted.png",
"mca:skins/male/librarian/librarianm13_converted.png"
]
},
{
"gender": "female",
"profession": "minecraft:librarian",
"paths": [
"mca:skins/female/librarian/librarianf1_converted.png",
"mca:skins/female/librarian/librarianf2_converted.png",
"mca:skins/female/librarian/librarianf3_converted.png",
"mca:skins/female/librarian/librarianf4_converted.png",
"mca:skins/female/librarian/librarianf5_converted.png",
"mca:skins/female/librarian/librarianf6_converted.png",
"mca:skins/female/librarian/librarianf7_converted.png",
"mca:skins/female/librarian/librarianf8_converted.png",
"mca:skins/female/librarian/librarianf9_converted.png",
"mca:skins/female/librarian/librarianf10_converted.png"
]
},
{
"gender": "male",
"profession": "minecraft:priest",
"paths": [
"mca:skins/male/priest/priestm1_converted.png",
"mca:skins/male/priest/priestm2_converted.png",
"mca:skins/male/priest/priestm3_converted.png",
"mca:skins/male/priest/priestm4_converted.png",
"mca:skins/male/priest/priestm5_converted.png",
"mca:skins/male/priest/priestm6_converted.png",
"mca:skins/male/priest/priestm7_converted.png",
"mca:skins/male/priest/priestm8_converted.png",
"mca:skins/male/priest/priestm9_converted.png",
"mca:skins/male/priest/priestm10_converted.png",
"mca:skins/male/priest/priestm11_converted.png",
"mca:skins/male/priest/priestm12_converted.png"
]
},
{
"gender": "female",
"profession": "minecraft:priest",
"paths": [
"mca:skins/female/priest/priestf1_converted.png",
"mca:skins/female/priest/priestf2_converted.png",
"mca:skins/female/priest/priestf3_converted.png",
"mca:skins/female/priest/priestf4_converted.png",
"mca:skins/female/priest/priestf5_converted.png",
"mca:skins/female/priest/priestf6_converted.png",
"mca:skins/female/priest/priestf7_converted.png",
"mca:skins/female/priest/priestf8_converted.png",
"mca:skins/female/priest/priestf9_converted.png",
"mca:skins/female/priest/priestf10_converted.png",
"mca:skins/female/priest/priestf11_converted.png",
"mca:skins/female/priest/priestf12_converted.png"
]
},
{
"gender": "male",
"profession": "minecraft:smith",
"paths": [
"mca:skins/male/smith/smithm1_converted.png",
"mca:skins/male/smith/smithm2_converted.png",
"mca:skins/male/smith/smithm3_converted.png",
"mca:skins/male/smith/smithm4_converted.png",
"mca:skins/male/smith/smithm5_converted.png",
"mca:skins/male/smith/smithm6_converted.png",
"mca:skins/male/smith/smithm7_converted.png",
"mca:skins/male/smith/smithm8_converted.png",
"mca:skins/male/smith/smithm9_converted.png"
]
},
{
"gender": "female",
"profession": "minecraft:smith",
"paths": [
"mca:skins/female/smith/smithf1_converted.png",
"mca:skins/female/smith/smithf2_converted.png",
"mca:skins/female/smith/smithf3_converted.png",
"mca:skins/female/smith/smithf4_converted.png",
"mca:skins/female/smith/smithf5_converted.png",
"mca:skins/female/smith/smithf6_converted.png",
"mca:skins/female/smith/smithf7_converted.png"
]
},
{
"gender": "male",
"profession": "minecraft:butcher",
"paths": [
"mca:skins/male/butcher/butcherm1_converted.png",
"mca:skins/male/butcher/butcherm2_converted.png",
"mca:skins/male/butcher/butcherm3_converted.png",
"mca:skins/male/butcher/butcherm4_converted.png",
"mca:skins/male/butcher/butcherm5_converted.png",
"mca:skins/male/butcher/butcherm6_converted.png",
"mca:skins/male/butcher/butcherm7_converted.png",
"mca:skins/male/butcher/butcherm8_converted.png",
"mca:skins/male/butcher/butcherm9_converted.png"
]
},
{
"gender": "female",
"profession": "minecraft:butcher",
"paths": [
"mca:skins/female/butcher/butcherf1_converted.png",
"mca:skins/female/butcher/butcherf2_converted.png",
"mca:skins/female/butcher/butcherf3_converted.png",
"mca:skins/female/butcher/butcherf4_converted.png"
]
},
{
"gender": "male",
"profession": "mca:baker",
"paths": [
"mca:skins/male/baker/bakerm1_converted.png",
"mca:skins/male/baker/bakerm2_converted.png",
"mca:skins/male/baker/bakerm3_converted.png",
"mca:skins/male/baker/bakerm4_converted.png",
"mca:skins/male/baker/bakerm5_converted.png",
"mca:skins/male/baker/bakerm6_converted.png",
"mca:skins/male/baker/bakerm7_converted.png",
"mca:skins/male/baker/bakerm8_converted.png",
"mca:skins/male/baker/bakerm9_converted.png",
"mca:skins/male/baker/bakerm10_converted.png"
]
},
{
"gender": "female",
"profession": "mca:baker",
"paths": [
"mca:skins/female/baker/bakerf1_converted.png",
"mca:skins/female/baker/bakerf2_converted.png",
"mca:skins/female/baker/bakerf3_converted.png",
"mca:skins/female/baker/bakerf4_converted.png",
"mca:skins/female/baker/bakerf5_converted.png",
"mca:skins/female/baker/bakerf6_converted.png",
"mca:skins/female/baker/bakerf7_converted.png",
"mca:skins/female/baker/bakerf8_converted.png",
"mca:skins/female/baker/bakerf9_converted.png",
"mca:skins/female/baker/bakerf10_converted.png",
"mca:skins/female/baker/bakerf11_converted.png",
"mca:skins/female/baker/bakerf12_converted.png",
"mca:skins/female/baker/bakerf13_converted.png"
]
},
{
"gender": "male",
"profession": "mca:miner",
"paths": [
"mca:skins/male/miner/minerm1_converted.png",
"mca:skins/male/miner/minerm2_converted.png",
"mca:skins/male/miner/minerm3_converted.png",
"mca:skins/male/miner/minerm4_converted.png",
"mca:skins/male/miner/minerm5_converted.png",
"mca:skins/male/miner/minerm6_converted.png",
"mca:skins/male/miner/minerm7_converted.png",
"mca:skins/male/miner/minerm8_converted.png",
"mca:skins/male/miner/minerm9_converted.png",
"mca:skins/male/miner/minerm10_converted.png",
"mca:skins/male/miner/minerm11_converted.png",
"mca:skins/male/miner/minerm12_converted.png",
"mca:skins/male/miner/minerm13_converted.png",
"mca:skins/male/miner/minerm14_converted.png"
]
},
{
"gender": "female",
"profession": "mca:miner",
"paths": [
"mca:skins/female/miner/minerf1_converted.png",
"mca:skins/female/miner/minerf2_converted.png",
"mca:skins/female/miner/minerf3_converted.png",
"mca:skins/female/miner/minerf4_converted.png",
"mca:skins/female/miner/minerf5_converted.png",
"mca:skins/female/miner/minerf6_converted.png",
"mca:skins/female/miner/minerf7_converted.png",
"mca:skins/female/miner/minerf8_converted.png",
"mca:skins/female/miner/minerf9_converted.png",
"mca:skins/female/miner/minerf10_converted.png",
"mca:skins/female/miner/minerf11_converted.png",
"mca:skins/female/miner/minerf12_converted.png",
"mca:skins/female/miner/minerf13_converted.png",
"mca:skins/female/miner/minerf14_converted.png",
"mca:skins/female/miner/minerf15_converted.png"
]
},
{
"gender": "male",
"profession": "mca:guard",
"paths": [
"mca:skins/male/warrior/warriorm1_converted.png",
"mca:skins/male/warrior/warriorm2_converted.png",
"mca:skins/male/warrior/warriorm3_converted.png",
"mca:skins/male/warrior/warriorm4_converted.png",
"mca:skins/male/warrior/warriorm5_converted.png"
]
},
{
"gender": "female",
"profession": "mca:guard",
"paths": [
"mca:skins/female/warrior/warriorf1_converted.png",
"mca:skins/female/warrior/warriorf2_converted.png",
"mca:skins/female/warrior/warriorf3_converted.png",
"mca:skins/female/warrior/warriorf4_converted.png",
"mca:skins/female/warrior/warriorf5_converted.png",
"mca:skins/female/warrior/warriorf6_converted.png"
]
},
{
"gender": "male",
"profession": "mca:child",
"paths": [
"mca:skins/male/child/childm1_converted.png",
"mca:skins/male/child/childm2_converted.png",
"mca:skins/male/child/childm3_converted.png",
"mca:skins/male/child/childm4_converted.png",
"mca:skins/male/child/childm5_converted.png",
"mca:skins/male/child/childm6_converted.png",
"mca:skins/male/child/childm7_converted.png",
"mca:skins/male/child/childm8_converted.png",
"mca:skins/male/child/childm9_converted.png",
"mca:skins/male/child/childm10_converted.png",
"mca:skins/male/child/childm11_converted.png",
"mca:skins/male/child/childm12_converted.png",
"mca:skins/male/child/childm13_converted.png",
"mca:skins/male/child/childm14_converted.png",
"mca:skins/male/child/childm15_converted.png",
"mca:skins/male/child/childm16_converted.png",
"mca:skins/male/child/childm17_converted.png",
"mca:skins/male/child/childm18_converted.png",
"mca:skins/male/child/childm19_converted.png",
"mca:skins/male/child/childm20_converted.png",
"mca:skins/male/child/childm21_converted.png",
"mca:skins/male/child/childm22_converted.png",
"mca:skins/male/child/childm23_converted.png",
"mca:skins/male/child/childm24_converted.png",
"mca:skins/male/child/childm25_converted.png",
"mca:skins/male/child/childm26_converted.png",
"mca:skins/male/child/childm27_converted.png"
]
},
{
"gender": "female",
"profession": "mca:child",
"paths": [
"mca:skins/female/child/childf1_converted.png",
"mca:skins/female/child/childf2_converted.png",
"mca:skins/female/child/childf3_converted.png",
"mca:skins/female/child/childf4_converted.png",
"mca:skins/female/child/childf5_converted.png",
"mca:skins/female/child/childf6_converted.png",
"mca:skins/female/child/childf7_converted.png",
"mca:skins/female/child/childf8_converted.png",
"mca:skins/female/child/childf9_converted.png",
"mca:skins/female/child/childf10_converted.png",
"mca:skins/female/child/childf11_converted.png",
"mca:skins/female/child/childf12_converted.png",
"mca:skins/female/child/childf13_converted.png",
"mca:skins/female/child/childf14_converted.png",
"mca:skins/female/child/childf15_converted.png",
"mca:skins/female/child/childf16_converted.png",
"mca:skins/female/child/childf17_converted.png",
"mca:skins/female/child/childf18_converted.png",
"mca:skins/female/child/childf19_converted.png",
"mca:skins/female/child/childf20_converted.png",
"mca:skins/female/child/childf21_converted.png"
]
}
]
================================================
FILE: src/main/resources/assets/mca/blockstates/rose_gold_block.json
================================================
{
"forge_marker": 1,
"defaults": {
"model": "mca:rose_gold_block"
},
"variants": {
"normal": [{}],
"inventory": [{}]
}
}
================================================
FILE: src/main/resources/assets/mca/blockstates/rose_gold_ore.json
================================================
{
"forge_marker": 1,
"defaults": {
"model": "mca:rose_gold_ore"
},
"variants": {
"normal": [{}],
"inventory": [{}]
}
}
================================================
FILE: src/main/resources/assets/mca/blockstates/villager_spawner.json
================================================
{
"forge_marker": 1,
"defaults": {
"model": "mca:villager_spawner"
},
"variants": {
"normal": [{}],
"inventory": [{}]
}
}
================================================
FILE: src/main/resources/assets/mca/lang/en_us.lang
================================================
#X-Generator: crowdin.com
itemGroup.MCA=Minecraft Comes Alive
enum.agestate.baby=Baby
enum.agestate.toddler=Toddler
enum.agestate.child=Child
enum.agestate.teen=Teen
enum.agestate.adult=Adult
entity.Villager.marauder=Marauder
entity.Villager.outlaw=Outlaw
entity.Villager.pillager=Pillager
entity.Villager.miner=Miner
entity.Villager.baker=Baker
entity.Villager.warrior=Warrior
entity.Villager.archer=Archer
entity.Villager.hero=Hero
entity.Villager.child=Child
##############################
# Items & Blocks
##############################
item.wedding_ring.name=Wedding Ring
item.wedding_ring_rg.name=Rose Gold Wedding Ring
item.engagement_ring.name=Engagement Ring
item.engagement_ring_rg.name=Rose Gold Engagement Ring
item.matchmakers_ring.name=Matchmaker's Ring
item.baby_boy.name=Baby Boy
item.baby_girl.name=Baby Girl
item.egg_male.name=Spawn Male Villager
item.egg_female.name=Spawn Female Villager
item.divorce_papers.name=Divorce Papers
item.rose_gold_ingot.name=Rose Gold Ingot
item.new_outfit.name=New Outfit
item.tombstone.name=Tombstone
item.rose_gold_dust.name=Rose Gold Dust
item.gold_dust.name=Gold Dust
item.whistle.name=Whistle
item.villager_editor.name=Villager Editor
item.egg_grim_reaper.name=Spawn Grim Reaper
item.staff_of_life.name=Staff of Life
item.book_death.name=Death, and How to Cure It!
item.book_romance.name=Relationships and You
item.book_family.name=Managing Your Family Vol. XI
item.book_rose_gold.name=On Rose Gold
item.book_infection.name=Beware the Infection!
tile.rose_gold_ore.name=Rose Gold Ore
tile.rose_gold_block.name=Rose Gold Block
tile.mca:villager_spawner.name=Villager Spawner
tile.mca:rose_gold_block.name=Rose Gold Block
tile.mca:rose_gold_ore.name=Rose Gold Ore
################################
# Relations
################################
relation.spouse=Spouse
relation.daughter=Daughter
relation.son=Son
##########################
# Reactions
##########################
reaction.onhit1=Ow\! That hurt\!
reaction.onhit2=I'll get you for that\!
reaction.onhit3=Ouch\! Why did you hit me?
reaction.onhit4=That hurts, stop it\!
reaction.onhit5=Agh\! That really hurt\!
reaction.onhit6=Hey\! What do you think you're doing?\!
reaction.onhit7=*Oof*\! That better have been an accident\!
reaction.ranaway1=That's right, you'd better run\!
reaction.ranaway2=If you come back, I'm calling the guards\!
reaction.ranaway3=Come back and fight like a man\!
reaction.ranaway4=If I see you again, I'm going to punch you\!
reaction.ranaway5=I knew you were afraid of me\!
reaction.ranaway6=Why are you running? Get back here so I can hit you\!
reaction.ranaway7=I'm going to hit you if I see you again\!
reaction.ranaway8=I'll get my friends and beat you up\!
reaction.drawnweapon1=No\! Please don't hurt me\!
reaction.drawnweapon2=Stop\! No\!
reaction.drawnweapon3=Someone help me\!
reaction.drawnweapon4=They're going to kill me\! Someone help\!
reaction.drawnweapon5=You can take whatever you want, just please don't hurt me\!
reaction.drawnweapon6=I don't want to die\! Stay away\!
reaction.drawnweapon7=Mother Notch, please help me\!
#########################
# Messages for chores
#########################
mining.search.none=There's no %v1% nearby.
mining.search.nearby=There's some %v1% nearby...
mining.search.value=There's some %v1% %a2% blocks away.
farming.nohoe=I'll need to have a hoe in order to farm.
fishing.norod=I don't have a fishing rod!
fishing.nowater=I don't see any water nearby...
fishing.finished=I've finished fishing.
cooking.nofood=I don't have any food to cook.
cooking.nofuel=I don't have any fuel.
cooking.nofurnace=There's no furnace nearby.
#################
# GUI
################################
gui.button.debug.startraid=Start Raid
gui.button.debug.spawnguards=Spawn Guards
gui.button.debug.selectnearestvillager=Get Nearest Villager
gui.button.debug.startmining=Start Mining
gui.button.debug.startfishing=Start Fishing
gui.button.debug.startchopping=Start Chopping
gui.button.debug.starthunting=Start Hunting
gui.button.debug.startharvesting=Start Harvest
gui.button.debug.unzombify=Unzombify
gui.button.debug.zombify=Zombify
gui.button.debug.marrytoplayer=Marry to Player
gui.button.debug.rebuildvillage=Rebuild Village
gui.button.debug.openinventory=Open Inventory
gui.button.yes=Yes
gui.button.no=No
gui.button.ok=Ok
gui.button.done=Done
gui.button.random=Random
gui.button.interact=Interact
gui.button.follow=Follow Me
gui.button.stay=Stay Here
gui.button.move=Move Freely
gui.button.trade=Trade
gui.button.sethome=Home
gui.button.gohome=Go Home
gui.button.setworkplace=Workplace
gui.button.sethangout=Hangout
gui.button.location=Locations
gui.button.ridehorse=Ride Horse
gui.button.special=Special
gui.button.procreate=Procreate
gui.button.work=Work
gui.button.inventory=Inventory
gui.button.chat=Chat
gui.button.joke=Joke
gui.button.gift=Gift
gui.button.shakehand=Shake Hand
gui.button.tellstory=Tell Story
gui.button.flirt=Flirt
gui.button.hug=Hug
gui.button.kiss=Kiss
gui.button.prospecting=Prospecting
gui.button.hunting=Hunting
gui.button.cooking=Cooking
gui.button.fishing=Fishing
gui.button.chopping=Chopping
gui.button.harvesting=Harvesting
gui.button.start=Start
gui.button.stop=Stop
gui.button.havebaby=Have Baby
gui.button.divorce=Divorce
gui.button.asktomarry=Ask to Marry
gui.button.hire=Hire
gui.button.hired=Hired
gui.button.accept=Accept
gui.button.combat=Combat
gui.button.extend=Extend
gui.button.dismiss=Dismiss
gui.button.divorcespouse=Divorce Spouse
gui.button.resetbaby=Reset Baby
gui.button.exit=Exit
gui.button.back=Back
gui.button.backarrow=<<
gui.button.adoptbaby=Adopt Baby
gui.button.revive=Revive
gui.button.infected=Change Infection
gui.button.gender=Change Gender
gui.button.texture.set=Set Skin
gui.button.texture.randomize=Randomize
gui.button.profession.set=Set Career
gui.button.profession.randomize=Randomize
gui.button.stopworking=Stop Work
gui.button.copyuuid=Copy UUID
gui.button.call=Call
gui.title.namebaby.male=It's a boy\!
gui.title.namebaby.female=It's a girl\!
gui.title.namebaby=Name your baby\:
gui.title.tombstone=Enter tombstone text\:
gui.title.editor=Villager Editor
gui.title.whistle=Call Family Member
gui.title.staffoflife=Select a Villager to Revive
gui.label.you=You
gui.label.readytogrow=Ready to grow!
gui.label.owner=Owner
gui.label.infected=Infected!
gui.label.name=Name:
gui.label.age=Age:
gui.label.unnamed=Unnamed
gui.label.rightclicktoname=Right-click to name
gui.label.minute=Minute
gui.label.minutes=Minutes
gui.label.parent=Parent:
gui.label.male=Male
gui.label.female=Female
gui.label.prospecting=Prospecting
gui.label.harvesting=Harvesting
gui.label.chopping=Chopping
gui.label.hunting=Hunting
gui.label.fishing=Fishing
gui.label.staying=Staying
gui.label.following=Following
gui.info.gift.line1=Gift Available
gui.info.gift.line2=(Click to take)
spouse.chore.mining.orenotify=There's some %v2% nearby...
spouse.chore.mining.nopick=I forgot my pickaxe, dear, did you bring an extra one?
spouse.chore.chopping.noaxe=Oh, I thought we were going for a picnic. I didn't bring an axe...
spouse.chore.fishing.norod=I'd love to! But, I can't find my fishing rod.
spouse.chore.hunting.nosword=I broke my sword yesterday. Do you have another one?
spouse.chore.harvesting.nohoe=Do you have an extra hoe I could use?
childp.chore.mining.orenotify=I think there's some %v2% nearby...
childp.chore.mining.nopick=I can't do that without a pickaxe!
childp.chore.chopping.noaxe=I can't chop wood without an axe...
childp.chore.fishing.norod=I can't fish without a fishing rod!
childp.chore.hunting.nosword=Can you give me a sword first?
childp.chore.harvesting.nohoe=I don't have a hoe to harvest with.
child.chore.mining.orenotify=I think there's some %v2% nearby...
child.chore.mining.nopick=I can't do that without a pickaxe!
child.chore.chopping.noaxe=I can't chop wood without an axe...
child.chore.fishing.norod=I can't fish without a fishing rod!
child.chore.hunting.nosword=Can you give me a sword first?
child.chore.harvesting.nohoe=I don't have a hoe to harvest with.
adult.chore.mining.orenotify=Found something! There's some %v2% nearby.
adult.chore.mining.nopick=I don't have a pickaxe anymore.
adult.chore.chopping.noaxe=I don't have an axe anymore.
adult.chore.fishing.norod=I don't have a fishing rod anymore.
adult.chore.hunting.nosword=I lost my sword! Do you have another?
adult.chore.harvesting.nohoe=I don't have a hoe to harvest with.
gui.interact.label.married=Married to %v1%
gui.interact.label.engaged=Engaged to %v1%
gui.interact.label.notmarried=Not married
gui.interact.label.parents=Parents: %v1% and %v2%
gui.interact.label.gift=Gift available. Click to claim.
spouse.interaction.marry.fail.marriedtogiver1=It's a pretty ring, but I am already married to you, silly.
spouse.interaction.marry.fail.marriedtogiver2=We are already married. Did you forget?
adult.interaction.marry.fail.marriedtoother1=I'm sorry, no...I'm already married.
adult.interaction.marry.fail.marriedtoother2=Oh, I thought you knew...I'm already married to someone.
adult.interaction.marry.fail.marriedtoother3=What?\! I'm already married\!
adult.interaction.marry.fail.playermarried1=Uh...I see that ring on your finger. You're already married\!
adult.interaction.marry.fail.playermarried2=Just what are you trying to do? You're already married\!
adult.interaction.marry.fail.playermarried3=What? Really? I think you're married to someone else, aren't you?
adult.interaction.marry.fail.playermarried4=I'm appalled\! You already have a spouse.
adult.interaction.marry.fail.lowhearts1=What? No\! I don't like you\!
adult.interaction.marry.fail.lowhearts2=Oh, pretty ring\! Oh wait...it's for me? Um...no.
adult.interaction.marry.fail.lowhearts3=Is that for me? Sorry, I just don't know you enough.
adult.interaction.marry.fail.lowhearts4=I'm flattered, but I don't really know you.
spouse.interaction.engage.success1=Yes\! I will marry you\! I love you\!
spouse.interaction.engage.success2=Of course I'll marry you\!
spouse.interaction.engage.success3=About time...just kidding\! Love you\!
spouse.interaction.engage.success4=Is...is this real? I mean, this moment, not the ring. But the ring is real, right?
spouse.interaction.marry.success1=It's a dream come true\! I'll love you forever\!
spouse.interaction.marry.success2=We're finally married\! Now what?
spouse.interaction.marry.success3=I'm happy to be married to you, %v1%.
spouse.interaction.marry.success4=I can't wait to start our life together\!
adult.interaction.matchmaker.fail.married1=I am already married to someone.
adult.interaction.matchmaker.fail.married2=I'm happily married, I do not want another spouse.
adult.interaction.matchmaker.fail.married3=I don't want that - I'm already married.
adult.interaction.matchmaker.fail.engaged1=I am engaged to someone already, I can't take that ring.
adult.interaction.matchmaker.fail.engaged2=I've promised to marry someone else.
adult.interaction.matchmaker.fail.engaged3=Oh, thanks but I think I'm okay. I'm already engaged to someone.
adult.interaction.matchmaker.fail.needtwo1=Don't you need two rings to arrange a marriage?
adult.interaction.matchmaker.fail.needtwo2=Oh, okay\! But you need two rings first.
adult.interaction.matchmaker.fail.needtwo3=My spouse and I will both need a ring, but you only have one.
adult.interaction.matchmaker.fail.novillagers1=I don't see anyone close by. Who did you want me to marry?
adult.interaction.matchmaker.fail.novillagers2=I just don't know...move me closer to the one you think is right for me.
adult.interaction.matchmaker.fail.novillagers3=Oh, but there doesn't seem to be anyone close by. Who should I marry?
adult.interaction.sethome.success1=Okay, this will be my new home point.
adult.interaction.sethome.success2=I understand, I'll be sleeping here at night.
adult.interaction.sethome.success3=Sure thing, %v1%.
spouse.interaction.sethome.success1=I really like this place, good job %v1%!
spouse.interaction.sethome.success2=This is like a dream home!
childp.interaction.sethome.success1=Okay fine, where's my room?
childp.interaction.sethome.success2=This is cool I guess. Can I go play now?
childp.interaction.sethome.success3=Okay, but I want the biggest room!
child.interaction.sethome.success2=This is cool I guess.
adult.interaction.sethome.fail1=This doesn't look like a safe home point for me. There's some %v1% in the way.
adult.interaction.sethome.fail2=Is there another place nearby? There's some %v1% in the way.
adult.interaction.sethome.fail3=I can't have my home point here. There's some %v1% in the way.
adult.interaction.setworkplace.success1=Sure thing, %v1%.
spouse.interaction.setworkplace.success1=I really like this place.
child.interaction.setworkplace.success1=Okay fine!
childp.interaction.setworkplace.success1=Okay fine!
adult.interaction.sethangout.success1=This is my favorite spot. I'm often here in the evening.
spouse.interaction.sethangout.success1=I really like this place.
child.interaction.sethangout.success1=Okay fine! I will play here before bedtime.
childp.interaction.sethangout.success1=Okay fine! I will play here before bedtime.
adult.interaction.gohome.success1=Alright, I'll go there immediately!
adult.interaction.gohome.success2=Sure, I'll go home now.
adult.interaction.gohome.success3=I'm going home. Goodbye!
spouse.interaction.gohome.success1=Sure, dear, I'll head home now.
spouse.interaction.gohome.success2=See you there, dear!
childp.interaction.gohome.success1=See ya!
childp.interaction.gohome.success2=Okay! Bye!
child.interaction.gohome.success1=Okay! I think I remember where I live...
adult.interaction.gohome.fail.nohome=I don't have a home...
spouse.interaction.gohome.fail.nohome=Remind me again where our house was?
child.interaction.gohome.fail.nohome=I don't remember where I live...
childp.interaction.gohome.fail.nohome=I don't remember where home is! We move too much!
child.interaction.ridehorse.fail.notnearby=Where are the horses? I want to ride!
childp.interaction.ridehorse.fail.notnearby=Where is my horse? I hope I didn't lose it again...
adult.interaction.ridehorse.fail.notnearby=I don't see any rideable horses nearby.
spouse.interaction.ridehorse.fail.notnearby=Where is my horse, dear? I can't find it.
spouse.interaction.procreate.fail.hasbaby1=We already have a baby...you didn't lose it did you?!
spouse.interaction.procreate.fail.hasbaby2=...you lost baby Joby didn't you? Wait...was his name Joby?
spouse.interaction.procreate.fail.lowhearts1=Spend more time with me! I'm not ready for a child.
spouse.interaction.procreate.fail.lowhearts2=Hmm...not just yet. I think we need to spend more time together first.
notify.spouseendedmarriage=%Name% has ended their marriage with you.
notify.spousedied=Your spouse %v1% has died by %v2%
notify.childdied=Your child %v1% has died by %v2%
notify.child.grownup=%v1% has grown into an adult!
notify.revival.disabled=Revivals have been disabled by the server administrator.
notify.trading.disabled=Trading is disabled by the server administrator.
gift.cake.fail=I will only eat cake if my spouse is nearby...please find them!
##################################
# Responses to interactions
##################################
adult.gift.fail1=This isn't a good gift...
adult.gift.fail2=What made you think that I would like this?
adult.gift.fail3=No thanks.
adult.gift.fail4=I don't want that, why would I?
adult.gift.fail5=Why are you giving me that?
adult.gift.fail6=Is this supposed to be a gift? No thanks.
adult.gift.good1=How considerate\! Thank you.
adult.gift.good2=Thanks\!
adult.gift.good3=How thoughtful\!
adult.gift.good4=Oh, I love these\!
adult.gift.good5=A gift? For me? How nice\!
adult.gift.better1=Hey, this is pretty cool\!
adult.gift.better2=Thanks, friend\!
adult.gift.better3=%v1%, you're such a good friend\!
adult.gift.better4=Oh wow, I actually needed one of these\!
adult.gift.better5=This is a pretty good gift\!
adult.gift.best1=I...I don't know what to say. Thank you so much, %v1%\!
adult.gift.best2=How did you...nevermind, this is amazing\!
adult.gift.best3=Oh wow, I've always wanted one of these\!
adult.gift.best4=This is fantastic\! I'll put it to good use.
adult.gift.best5=Thank you so much. I will remember this forever.
adult.chat.success1=Man, cookies and milk does sound delicious right now.
adult.chat.success2=Yes, I suppose the weather is nice today.
adult.chat.success3=I'm doing just fine\! Hit my toe when I woke up, though.
adult.chat.success4=An apple a day keeps the zombies away\!
adult.chat.success5=My dream is to build my own village, but I'm so lazy.
adult.chat.success6=I think I saw %Supporter% the other day in Diamond armor.
adult.chat.success7=My friend %Supporter% told me that they found a chest full of diamonds yesterday!
adult.chat.fail1=Did you seriously just say that?
adult.chat.fail2=I don't believe it exploded on its own.
adult.chat.fail3=You know, you're not that cool.
adult.chat.fail4=Show off.
adult.chat.fail5=You should be thrown in a dungeon\!
adult.joke.success1=Haha\! Serves that Skelly right\!
adult.joke.success2=*Laughs* That's hilarious\!
adult.joke.success3=That's funny\! Did you hear the one about the cows?
adult.joke.success4=Unfortunate for the sheep to lose its wool, but funny\!
adult.joke.success5=That's the best I have ever heard\!
adult.joke.success6=You might be funnier than %Supporter%\!
adult.joke.fail1=Don't speak about my pig like that\!
adult.joke.fail2=Ha. Ha. Not funny.
adult.joke.fail3=Ah, you're not the funniest in town.
adult.joke.fail4=That's low.
adult.joke.fail5=You shouldn't joke about that.
adult.shakehand.success1=You have a nice grip\!
adult.shakehand.success2=Your grip shows me you have great power\!
adult.shakehand.success3=Wow, you're so polite\!
adult.shakehand.success4=Good day\!
adult.shakehand.success5=Why, hello there\!
adult.shakehand.fail1=Seriously? After you slaughtered the cow?
adult.shakehand.fail2=Um, no that's okay.
adult.shakehand.fail3=I'm not a stranger, you don't have to be so polite.
adult.shakehand.fail4=Wow really? This isn't like you.
adult.shakehand.fail5=Go away.
adult.tellstory.success1=Really? I can't believe that all happened\!
adult.tellstory.success2=I wish I was brave enough to take on a creeper.
adult.tellstory.success3=That was a really good story\! Is it original?
adult.tellstory.success4=All of that happened yesterday? No way\!
adult.tellstory.success5=I was near there yesterday, I can't believe I didn't hear this already.
adult.tellstory.success6=Haha! That definitely sounds like %Supporter%! Such an awesome person.
adult.tellstory.success7=I've heard the Legend of %Supporter% almost a million times. Tell me again!
adult.tellstory.fail1=*Ahem* That's my mother you're talking about.
adult.tellstory.fail2=This is why the village talks about you.
adult.tellstory.fail3=I don't get it...
adult.tellstory.fail4=You're terrible\! Creepers have feelings too\!
adult.tellstory.fail5=How could you kill a poor sheep?\!
adult.flirt.success1=You're sooo brave\!
adult.flirt.success2=Oh, you\! Stop being so cute\!
adult.flirt.success3=*Blushes* Do you mean it?
adult.flirt.success4=Oh, my...
adult.flirt.success5=That was so adorable\! You had me at "hello"\!
adult.flirt.fail1=If you mean that, then prove it.
adult.flirt.fail2=Aw.... Wait, you told the baker the same thing\!
adult.flirt.fail3=Not in a million years.
adult.flirt.fail4=Pathetic much?
adult.flirt.fail5=A zombie has a better chance than you.
adult.hug.success1=Long time no see\!
adult.hug.success2=Thank you, I needed that.
adult.hug.success3=At least one thing made my day today.
adult.hug.success4=You're as snuggly as a sheep\!
adult.hug.fail1=You're covered in soot and mud\!
adult.hug.fail2=No thanks.
adult.hug.fail3=Uh, why?
adult.hug.fail4=After you called me a dinosaur last week? No.
adult.hug.fail5=Quite frankly, you don't deserve a hug after you did that.
adult.kiss.success1=I wish this moment would last forever.
adult.kiss.success2=I think I love you...
adult.kiss.success3=Mmm, tastes like pumpkin pie\!
adult.kiss.fail1=Not if someone can see.
adult.kiss.fail2=You call that a kiss?
adult.kiss.fail3=Ash kisses better than you.
adult.kiss.fail4=Two words... breath mints\!
adult.kiss.fail5=Thank you?
adult.greeting1=Why, hello there\!
adult.greeting2=Hey\! How are you today?
adult.greeting3=Hey, good to see you\!
adult.greeting4=What's going on with you today?
adult.greeting5=How are you today?
child.chat.success1=I heard stories about you\! Are you a hero?
child.chat.success2=Hi. I was going to go try and climb to the roof.
child.chat.success3=Do you wanna go burn stuff with me?
child.chat.success4=I'm going to be a hunter like you and kill many things\!
child.chat.success5=Hi\! What are you doing today? I'm going swimmin'\!
child.chat.fail1=If you don't give me cookies I'll hold my breath.
child.chat.fail2=My parents said not to talk to you, that you're bad.
child.chat.fail3=*Laughs* You look smelly\!
child.chat.fail4=Oh yeah? Well I'm gonna egg your house\!
child.chat.fail5=Lalala, I'm not listening\! Lalala.
child.joke.success1=You're funnier than daddy\!
child.joke.success2=Tell me another one\!
child.joke.success3=You're the funniest person alive\!
child.joke.success4=I'm tellin' my momma that one\! *Laughs*
child.joke.success5=It should eat a leaf\!
child.joke.fail1=I don't get it.
child.joke.fail2=You're not funny. Really.
child.joke.fail3=You need to stop...
child.joke.fail4=But, who's apple?
child.joke.fail5=Don't be mean\!
child.shakehand.success1=Hiya\! Someone I know likes you...
child.shakehand.success2=Dad said this is a very nice thing to do.
child.shakehand.success3=Now high five\! Down low... too slow\!
child.shakehand.success4=Hi stranger\!
child.shakehand.success5=*Giggles* I just cleaned a cow with this hand.
child.shakehand.fail1=Stranger danger...
child.shakehand.fail2=Mom, dad\! This person is trying to kidnap me\!
child.shakehand.fail3=Don't touch me I'm famous\!
child.shakehand.fail4=Ew, your hand has black stuff on it.
child.shakehand.fail5=I'll only shake your hand if you give me a diamond.
child.tellstory.success1=Wow\! You're a beast\!
child.tellstory.success2=I want to be just like you when I grow up. Shh, don't tell dad.
child.tellstory.success3=Can you adopt me?\! You're awesome\!
child.tellstory.success4=I went fishing and almost drowned.
child.tellstory.success5=Does this mean I can take whatever I want? I mean, "borrow?"
child.tellstory.success6=Tell me again about %Supporter%!!
child.tellstory.fail1=You're a meanie\!
child.tellstory.fail2=I'm telling my mom what you said about her...
child.tellstory.fail3=I believe you're speaking about my grandpa...
child.tellstory.fail4=You're nothing but a scaredycat like dad said\!
child.tellstory.fail5=How could you kill a poor chicken?
child.greeting1=Hi, who are you?
child.greeting2=Hi, what's your name?
child.greeting3=Eek\! You look scary\!
child.gift.fail1=Ew, I don't like this\!
child.gift.fail2=Yuck\! I don't want this.
child.gift.fail3=Why did you bring me this? It's dumb\!
child.gift.fail4=I don't even know what this is\!
child.gift.good1=Is it...is it all mine?
child.gift.good2=Is this really for me?
child.gift.good3=This is cool\!
child.gift.better1=Awesome\! I'm going to show this to all my friends.
child.gift.better2=You found it\! I lost this a few minutes ago.
child.gift.better3=My friend stole one of these from me. Did you beat him up for me?
child.gift.best1=%v1%, you give the best presents\!
child.gift.best2=Finally\! My friend will stop bragging now.
child.gift.best3=Wow\! Where did you get this thing?
child.gift.best4=My Dad has one of these. Now I have one too\!
childp.chat.success1=Oh, I was just going to go explorin' later.
childp.chat.success2=Can we go camping? Please?\!
childp.chat.success3=Hi, can you make me a cake?
childp.chat.success4=Can I have my own room away from our house? That would be cool\!
childp.chat.success5=Let's move into a cave\! That sounds so fun\!
childp.chat.fail2=I don't think I'd like that very much.
childp.chat.fail3=Is that why I've heard so much about "divorce"? What does that mean?
childp.chat.fail4=I want a new daddy.
childp.chat.fail5=I don't want a baby sister.
childp.joke.success1=*Laughs* Tell that one again\!
childp.joke.success2=I've got to tell my friend that one\!
childp.joke.success3=How did the creeper explode?\!
childp.joke.success4=*Laughs*Why is there no longer 3 of them?
childp.joke.success5=*Laughs* ... *Laughs*... *Laughs*
childp.joke.fail1=I thought you were funny, though...
childp.joke.fail2=I like knock knock jokes better.
childp.joke.fail3=I don't get it, that was dumb.
childp.joke.fail4=*Yawn* My friend's dad is cooler and funnier than you.
childp.joke.fail5=I'd rather have cake.
childp.shakehand.success1=Why do I need to learn this stuff?
childp.shakehand.success2=I heard that this is a polite thing to do.
childp.shakehand.success3=I'm gonna be just like you when I grow up\!
childp.shakehand.success4=Can I have cake now?
childp.shakehand.success5=I don't get it, but okay\!
childp.shakehand.fail1=I spit on my hand.
childp.shakehand.fail2=You're such an old person.
childp.shakehand.fail3=Only losers shake hands.
childp.shakehand.fail4=I'll shake your hand if you give me cake.
childp.shakehand.fail5=No, you'll slip and hit me.
childp.tellstory.success1=What!? You really did that?\! But...what happened to your friend?
childp.tellstory.success2=I want to explore a cave, too\! Let's go\!
childp.tellstory.success3=One day I'll kill more creepers than you\!
childp.tellstory.success4=Oh, oh, oh\! Can we climb a tree, too?\!
childp.tellstory.success5=Did the lava hurt?
childp.tellstory.fail1=I don't want to hear about grandma.
childp.tellstory.fail2=You always say that. I just want a pet.
childp.tellstory.fail3=You're just fibbing. I don't belive that.
childp.tellstory.fail4=You said you didn't eat the cake and cookies...
childp.tellstory.fail5=Someone said you were a bad person, and I believe them\!
childp.hug.success1=*Kisses* You're the best ever\!
childp.hug.success2=I'm going to be as strong as you are one day\!
childp.hug.success3=hug anymore?
childp.hug.success4=I love hugs\! You're soft and warm\!
childp.hug.fail1=I'm too old for hugs\!
childp.hug.fail2=Stop it\! I don't want people to see\!
childp.hug.fail3=Go away, you're so annoying\!
childp.hug.fail4=Just leave me alone or give me some cookies\!
childp.hug.fail5=I'd rather hug a skeleton.
childp.greeting1=Hey there\!
childp.greeting2=Hey, what's going on?
childp.greeting3=What are you doing?
childp.greeting4=Where are you going?
childp.gift.fail1=This...is a really bad gift.
childp.gift.fail2=Ew, I've gotten so much better before!
childp.gift.fail3=Didn't you give me this like, last year?
childp.gift.fail4=I could get this easily, no thanks.
childp.gift.good1=Oh, cool\! Thank you!
childp.gift.good2=Is it my birthday? This is awesome!
childp.gift.good3=This is much better than the last gift I got\!
childp.gift.good4=Woo hoo\! It's mine, all mine\!
childp.gift.good5=Can I...can I eat it?
childp.gift.better1=For me? For free?\!
childp.gift.better2=Ooh\! Shiny\!
childp.gift.better3=I really like this one, can I have another?
childp.gift.better4=All of my friends will be jealous now\!
childp.gift.better5=This is so cool! I've wanted one of these forever!
childp.gift.best1=This must have cost a fortune\!
childp.gift.best2=I knew you would get me one of these. I just knew it\!
childp.gift.best3=Yay\! I have the best parents in the world\!
childp.gift.best4=This is so amazing\! I can't believe this is all mine\!
childp.gift.best5=Thank you so much\! You're the best ever\!
spouse.chat.success1=I cleaned the entire house. How was your day?
spouse.chat.success2=Honey, let's go camping sometime. Doesn't that sound like fun?
spouse.chat.success3=So today I saw a spider. It was huge so I ran away.
spouse.chat.success4=We should build a new house together\!
spouse.chat.success5=I almost walked into a lava pit the other day. That wouldn't have been good\!
spouse.chat.fail1=I know we're not the poorest family, but...
spouse.chat.fail2=I love being around you but I need some space.
spouse.chat.fail3=Sometimes I wish I had my own "cave" to escape from you and everyone.
spouse.chat.fail4=Go away, I'm not in the mood.
spouse.chat.fail5=Where have you been? Are you seeing someone behind my back?
spouse.joke.success1=*Laughs* I married you for your humor\!
spouse.joke.success2=You should throw an egg at him next time\!
spouse.joke.success3=Then the wolf fell in love with the sheep.
spouse.joke.success4=That never gets old\!
spouse.joke.success5=Here's one for you... How many chickens does a creeper blow up?
spouse.joke.fail1=Lame...
spouse.joke.fail2=Sweetheart, you're not funny.
spouse.joke.fail3=Ha...Ha...Ha...Not funny.
spouse.joke.fail4=You need to erase that from your mind.
spouse.joke.fail5=Okay...
spouse.shakehand.success1=Your hand is so soft\!
spouse.shakehand.success2=Our hands fit perfectly together.
spouse.shakehand.success3=One day people will forget to shake hands.
spouse.shakehand.success4=Our children will need to be this polite.
spouse.shakehand.success5=*Continues to shake hand* Tell me when to stop\!
spouse.shakehand.fail1=shakehand? How about a kiss, instead?
spouse.shakehand.fail2=*Squeezes hand hard*
spouse.shakehand.fail3=Your hand is nasty, no way.
spouse.shakehand.fail4=They have germs on them.
spouse.shakehand.fail5=Why don't you get a decent job instead of shaking my hand?
spouse.tellstory.success1=Let's not tell our children that one...
spouse.tellstory.success2=You were so rebellious\! I love it\!
spouse.tellstory.success3=Did you ever tell your parents about losing their rings?
spouse.tellstory.success4=It was that moment when I fell in love with you\!
spouse.tellstory.success5=Wow, you're the best hunter ever\!
spouse.tellstory.fail1=Talk to me when you kill something other than a harmless cow.
spouse.tellstory.fail2=Don't do something that reckless\!
spouse.tellstory.fail3=You have a family to think about\!
spouse.tellstory.fail4=...If you liked them why didn't you marry them, instead?
spouse.tellstory.fail5=Why did you wear the pink fluffy underwear? Whose were they?
spouse.flirt.success1=*Blushes* Well, how about we do something like that, then\!
spouse.flirt.success2=Aw, you said that when we first met.
spouse.flirt.success3=Baby, you're so cute\!
spouse.flirt.success4=You bet I am\!
spouse.flirt.success5=*Winks* You still got it\!
spouse.flirt.fail1=*Sighs*
spouse.flirt.fail2=This one is getting old... like you.
spouse.flirt.fail3=We're married, we don't have to do this anymore.
spouse.flirt.fail4=Talk to the tree, it cares more.
spouse.flirt.fail5=Yeah, yeah... What was it you were saying?
spouse.hug.success1=I love being entangled in your arms\!
spouse.hug.success2=Wait, don't leave... you're warm.
spouse.hug.success3=Would you rather only being able to hug or kiss?
spouse.hug.success4=*Kisses*
spouse.hug.success5=Let's stay like this forever\!
spouse.hug.fail1=Why don't you go hug your ex?
spouse.hug.fail2=No thanks.
spouse.hug.fail3=Man, you stink.
spouse.hug.fail4=What do you want?
spouse.hug.fail5=Huge someone else.
spouse.kiss.success1=I fall in love all over again when our lips meet\!
spouse.kiss.success2=Time stops ticking when I'm with you.
spouse.kiss.success3=Sweet as cake\!
spouse.kiss.success4=I love you, baby\!
spouse.kiss.success5=I wouldn't trade you for anyone in the world\!
spouse.kiss.fail1=Not where someone can see us...
spouse.kiss.fail2=We don't have to if you don't want to.
spouse.kiss.fail3=Your breath smells like wolf kibble.
spouse.kiss.fail4=Go take a drink from the lake.
spouse.kiss.fail5=Now that we're married I can tell you how lousy you are at kissing.
spouse.greeting1=Hi honey, where have you been?
spouse.greeting2=Hello dear, how is your day going?
spouse.greeting3=Oh, %v1%\! You look tired.
spouse.greeting4=Hey %v1%\! You look hungry. Would you like me to cook something?
spouse.greeting5=%v1%, you're back\! I missed you.
spouse.lowhearts.greeting1=There you are. Where did you go? You never tell me anything anymore.
spouse.lowhearts.greeting2=Are you going to say hi to me this time?
spouse.lowhearts.greeting3=Um, hi! I still exist, you know!
spouse.lowhearts.greeting4=%v1%, are you ignoring me on purpose?
spouse.lowhearts.greeting5=I'm starting to feel like you don't pay attention to me.
spouse.endmarriage1=I've had it. You don't treat me well enough. I'm leaving you!
spouse.endmarriage2=I'm leaving. Forever! Don't look for me.
spouse.endmarriage3=I'm sorry - I thought we could work things out, but it's not working for me. Goodbye.
spouse.endmarriage4=%v1%, this is goodbye. Don't try to follow me.
spouse.gift.fail1=Oh honey...this is just terrible.
spouse.gift.fail2=Um, is this supposed to be a gift for me?
spouse.gift.fail3=Throw away your own junk\! Oh, this was a gift?...sorry.
spouse.gift.fail4=I thought you knew me better than that. I hate these.
spouse.gift.good1=%v1%, you're so sweet.
spouse.gift.good2=Ah\! You're too good to me.
spouse.gift.good3=This is unexpected, thank you, dear\!
spouse.gift.good4=Aw, how sweet of you.
spouse.gift.good5=Thanks, hun\!
spouse.gift.better1=Oh wow, this is actually really nice\!
spouse.gift.better2=I love it\! Thank you\!
spouse.gift.better3=This is amazing, dear\!
spouse.gift.better4=You got this for me? How sweet\!
spouse.gift.better5=Oh, thank you %v1%\!
spouse.gift.best1=Oh %v1%, I love you\!
spouse.gift.best2=You are *way* too good to me\!
spouse.gift.best3=This must have been extremely expensive\! Thank you\!
spouse.gift.best4=I...can't believe you'd get me something so thoughtful\!
================================================
FILE: src/main/resources/assets/mca/lang/names.lang
================================================
name.male1=Aaron
name.male2=Abdul
name.male3=Abe
name.male4=Abel
name.male5=Abraham
name.male6=Abram
name.male7=Adalberto
name.male8=Adam
name.male9=Adan
name.male10=Adolfo
name.male11=Adolph
name.male12=Adrian
name.male13=Agustin
name.male14=Ahmad
name.male15=Ahmed
name.male16=Alan
name.male17=Alaric
name.male18=Albert
name.male19=Alberto
name.male20=Alden
name.male21=Aldo
name.male22=Alec
name.male23=Alejandro
name.male24=Alex
name.male25=Alexander
name.male26=Alexis
name.male27=Alfonso
name.male28=Alfonzo
name.male29=Alfred
name.male30=Alfredo
name.male31=Ali
name.male32=Allan
name.male33=Allen
name.male34=Alonso
name.male35=Alonzo
name.male36=Alphonse
name.male37=Alphonso
name.male38=Alton
name.male39=Alva
name.male40=Alvaro
name.male41=Alvin
name.male42=Amado
name.male43=Ambrose
name.male44=Amos
name.male45=Anderson
name.male46=Andre
name.male47=Andrea
name.male48=Andreas
name.male49=Andres
name.male50=Andrew
name.male51=Andy
name.male52=Angel
name.male53=Angelo
name.male54=Anibal
name.male55=Anthony
name.male56=Antoine
name.male57=Anton
name.male58=Antone
name.male59=Antonia
name.male60=Antonio
name.male61=Antony
name.male62=Antwan
name.male63=Archie
name.male64=Arden
name.male65=Ariel
name.male66=Arlen
name.male67=Arlie
name.male68=Armand
name.male69=Armando
name.male70=Armon
name.male71=Arnold
name.male72=Arnoldo
name.male73=Arnulfo
name.male74=Aron
name.male75=Arron
name.male76=Art
name.male77=Arthur
name.male78=Arturo
name.male79=Asa
name.male80=Ashley
name.male81=Aubrey
name.male82=August
name.male83=Augustine
name.male84=Augustus
name.male85=Aurelio
name.male86=Austin
name.male87=Avery
name.male88=Ayden
name.male89=Bailey
name.male90=Barney
name.male91=Barrett
name.male92=Barry
name.male93=Bart
name.male94=Barton
name.male95=Basil
name.male96=Beau
name.male97=Ben
name.male98=Benedict
name.male99=Benito
name.male100=Benjamin
name.male101=Bennett
name.male102=Bennie
name.male103=Benny
name.male104=Benton
name.male105=Bernard
name.male106=Bernardo
name.male107=Bernie
name.male108=Berry
name.male109=Bert
name.male110=Bertram
name.male111=Bill
name.male112=Billie
name.male113=Billy
name.male114=Blaine
name.male115=Blair
name.male116=Blake
name.male117=Bob
name.male118=Bobbie
name.male119=Bobby
name.male120=Booker
name.male121=Boris
name.male122=Boyce
name.male123=Boyd
name.male124=Bracken
name.male125=Brad
name.male126=Bradford
name.male127=Bradley
name.male128=Bradly
name.male129=Brady
name.male130=Brain
name.male131=Branden
name.male132=Brandon
name.male133=Brant
name.male134=Brayden
name.male135=Brendan
name.male136=Brendon
name.male137=Brent
name.male138=Brenton
name.male139=Bret
name.male140=Brett
name.male141=Brian
name.male142=Brice
name.male143=Britt
name.male144=Brock
name.male145=Broderick
name.male146=Brooks
name.male147=Bruce
name.male148=Bruno
name.male149=Bryan
name.male150=Bryant
name.male151=Bryce
name.male152=Bryon
name.male153=Bryson
name.male154=Buck
name.male155=Bud
name.male156=Buddy
name.male157=Buford
name.male158=Burl
name.male159=Burt
name.male160=Burton
name.male161=Buster
name.male162=Byron
name.male163=Caleb
name.male164=Calvin
name.male165=Cameron
name.male166=Carey
name.male167=Carl
name.male168=Carlo
name.male169=Carlos
name.male170=Carlton
name.male171=Carmelo
name.male172=Carmen
name.male173=Carmine
name.male174=Carol
name.male175=Carrol
name.male176=Carroll
name.male177=Carson
name.male178=Carter
name.male179=Cary
name.male180=Casey
name.male181=Cason
name.male182=Cecil
name.male183=Cedric
name.male184=Cedrick
name.male185=Cesar
name.male186=Chad
name.male187=Chadwick
name.male188=Chance
name.male189=Chancey
name.male190=Chang
name.male191=Charles
name.male192=Charley
name.male193=Charlie
name.male194=Chas
name.male195=Chase
name.male196=Chauncey
name.male197=Chester
name.male198=Chet
name.male199=Chi
name.male200=Chong
name.male201=Chris
name.male202=Christian
name.male203=Christop
name.male204=Christoper
name.male205=Christopher
name.male206=Chuck
name.male207=Chung
name.male208=Clair
name.male209=Clarence
name.male210=Clark
name.male211=Claud
name.male212=Claude
name.male213=Claudio
name.male214=Clay
name.male215=Clayton
name.male216=Clement
name.male217=Clemente
name.male218=Cleo
name.male219=Cletus
name.male220=Cleveland
name.male221=Cliff
name.male222=Clifford
name.male223=Clifton
name.male224=Clint
name.male225=Clinton
name.male226=Clyde
name.male227=Cody
name.male228=Colby
name.male229=Cole
name.male230=Coleman
name.male231=Colin
name.male232=Collin
name.male233=Colton
name.male234=Columbus
name.male235=Connie
name.male236=Connor
name.male237=Conrad
name.male238=Cordell
name.male239=Corey
name.male240=Coriander
name.male241=Cornelius
name.male242=Cornell
name.male243=Cortez
name.male244=Cory
name.male245=Courtney
name.male246=Coy
name.male247=Craig
name.male248=Cristobal
name.male249=Cristopher
name.male250=Cruz
name.male251=Curt
name.male252=Curtis
name.male253=Cyril
name.male254=Cyrus
name.male255=Dale
name.male256=Dallas
name.male257=Dallis
name.male258=Dalton
name.male259=Damian
name.male260=Damien
name.male261=Damion
name.male262=Damon
name.male263=Dan
name.male264=Dana
name.male265=Dane
name.male266=Danial
name.male267=Daniel
name.male268=Danilo
name.male269=Dannie
name.male270=Danny
name.male271=Dante
name.male272=Darell
name.male273=Daren
name.male274=Darin
name.male275=Dario
name.male276=Darius
name.male277=Darnell
name.male278=Daron
name.male279=Darrel
name.male280=Darrell
name.male281=Darren
name.male282=Darrick
name.male283=Darrin
name.male284=Darron
name.male285=Darryl
name.male286=Darwin
name.male287=Daryl
name.male288=Dave
name.male289=David
name.male290=Davis
name.male291=Dean
name.male292=Deandre
name.male293=Deangelo
name.male294=Dee
name.male295=Del
name.male296=Delbert
name.male297=Delmar
name.male298=Delmer
name.male299=Demarcus
name.male300=Demetrius
name.male301=Denis
name.male302=Dennis
name.male303=Denny
name.male304=Denver
name.male305=Deon
name.male306=Derek
name.male307=Derick
name.male308=Derrick
name.male309=Deshawn
name.male310=Desmond
name.male311=Devin
name.male312=Devon
name.male313=Dewayne
name.male314=Dewey
name.male315=Dewitt
name.male316=Dexter
name.male317=Dick
name.male318=Diego
name.male319=Dillon
name.male320=Dino
name.male321=Dion
name.male322=Dirk
name.male323=Domenic
name.male324=Domingo
name.male325=Dominic
name.male326=Dominick
name.male327=Dominique
name.male328=Don
name.male329=Donald
name.male330=Dong
name.male331=Donn
name.male332=Donnell
name.male333=Donnie
name.male334=Donny
name.male335=Donovan
name.male336=Donte
name.male337=Dorian
name.male338=Dorsey
name.male339=Doug
name.male340=Douglas
name.male341=Douglass
name.male342=Doyle
name.male343=Draven
name.male344=Drew
name.male345=Duane
name.male346=Dudley
name.male347=Duncan
name.male348=Dustin
name.male349=Dusty
name.male350=Dwain
name.male351=Dwayne
name.male352=Dwight
name.male353=Dylan
name.male354=Earl
name.male355=Earle
name.male356=Earnest
name.male357=Eddie
name.male358=Eddy
name.male359=Edgar
name.male360=Edgardo
name.male361=Edison
name.male362=Edmond
name.male363=Edmund
name.male364=Edmundo
name.male365=Eduardo
name.male366=Edward
name.male367=Edwardo
name.male368=Edwin
name.male369=Efrain
name.male370=Efren
name.male371=Elbert
name.male372=Elden
name.male373=Eldon
name.male374=Eldridge
name.male375=Eli
name.male376=Elias
name.male377=Elijah
name.male378=Eliseo
name.male379=Elisha
name.male380=Elliot
name.male381=Elliott
name.male382=Ellis
name.male383=Ellsworth
name.male384=Elmer
name.male385=Elmo
name.male386=Eloy
name.male387=Elroy
name.male388=Elton
name.male389=Elvin
name.male390=Elvis
name.male391=Elwood
name.male392=Emanuel
name.male393=Emerson
name.male394=Emery
name.male395=Emil
name.male396=Emile
name.male397=Emilio
name.male398=Emit
name.male399=Emmanuel
name.male400=Emmett
name.male401=Emmitt
name.male402=Emory
name.male403=Enoch
name.male404=Enrique
name.male405=Erasmo
name.male406=Eric
name.male407=Erich
name.male408=Erick
name.male409=Erik
name.male410=Erin
name.male411=Ernest
name.male412=Ernesto
name.male413=Ernie
name.male414=Errol
name.male415=Ervin
name.male416=Erwin
name.male417=Esteban
name.male418=Ethan
name.male419=Eugene
name.male420=Eugenio
name.male421=Eusebio
name.male422=Evan
name.male423=Everett
name.male424=Everette
name.male425=Ezekiel
name.male426=Ezequiel
name.male427=Ezra
name.male428=Fabian
name.male429=Faustino
name.male430=Fausto
name.male431=Federico
name.male432=Felipe
name.male433=Felix
name.male434=Felton
name.male435=Ferdinand
name.male436=Fermin
name.male437=Fernando
name.male438=Fidel
name.male439=Filiberto
name.male440=Fletcher
name.male441=Florencio
name.male442=Florentino
name.male443=Floyd
name.male444=Ford
name.male445=Forest
name.male446=Forrest
name.male447=Foster
name.male448=Frances
name.male449=Francesco
name.male450=Francis
name.male451=Francisco
name.male452=Frank
name.male453=Frankie
name.male454=Franklin
name.male455=Franklyn
name.male456=Fred
name.male457=Freddie
name.male458=Freddy
name.male459=Frederic
name.male460=Frederick
name.male461=Fredric
name.male462=Fredrick
name.male463=Freeman
name.male464=Fritz
name.male465=Gabriel
name.male466=Gage
name.male467=Gail
name.male468=Gale
name.male469=Galen
name.male470=Garfield
name.male471=Garland
name.male472=Garret
name.male473=Garrett
name.male474=Garry
name.male475=Garth
name.male476=Gary
name.male477=Gaston
name.male478=Gavin
name.male479=Gayle
name.male480=Gaylord
name.male481=Genaro
name.male482=Gene
name.male483=Geoffrey
name.male484=George
name.male485=Gerald
name.male486=Geraldo
name.male487=Gerard
name.male488=Gerardo
name.male489=German
name.male490=Gerry
name.male491=Gil
name.male492=Gilbert
name.male493=Gilberto
name.male494=Gino
name.male495=Giovanni
name.male496=Giuseppe
name.male497=Glen
name.male498=Glenn
name.male499=Gonzalo
name.male500=Gordon
name.male501=Grady
name.male502=Graham
name.male503=Graig
name.male504=Grant
name.male505=Granville
name.male506=Grayson
name.male507=Greg
name.male508=Gregg
name.male509=Gregorio
name.male510=Gregory
name.male511=Grover
name.male512=Guadalupe
name.male513=Guillermo
name.male514=Gus
name.male515=Gustavo
name.male516=Guy
name.male517=Hai
name.male518=Hal
name.male519=Hank
name.male520=Hans
name.male521=Harlan
name.male522=Harland
name.male523=Harley
name.male524=Harold
name.male525=Harris
name.male526=Harrison
name.male527=Harry
name.male528=Harvey
name.male529=Hassan
name.male530=Hayden
name.male531=Haywood
name.male532=Heath
name.male533=Hector
name.male534=Henry
name.male535=Herb
name.male536=Herbert
name.male537=Heriberto
name.male538=Herman
name.male539=Herschel
name.male540=Hershel
name.male541=Hilario
name.male542=Hilton
name.male543=Hipolito
name.male544=Hiram
name.male545=Hobert
name.male546=Hollis
name.male547=Homer
name.male548=Hong
name.male549=Horace
name.male550=Horacio
name.male551=Hosea
name.male552=Houston
name.male553=Howard
name.male554=Hoyt
name.male555=Hubert
name.male556=Huey
name.male557=Hugh
name.male558=Hugo
name.male559=Humberto
name.male560=Hung
name.male561=Hunter
name.male562=Hyman
name.male563=Ian
name.male564=Ignacio
name.male565=Ike
name.male566=Ira
name.male567=Irvin
name.male568=Irving
name.male569=Irwin
name.male570=Isaac
name.male571=Isaiah
name.male572=Isaias
name.male573=Isiah
name.male574=Isidro
name.male575=Ismael
name.male576=Israel
name.male577=Isreal
name.male578=Issac
name.male579=Ivan
name.male580=Ivory
name.male581=Jacinto
name.male582=Jack
name.male583=Jackie
name.male584=Jackson
name.male585=Jacob
name.male586=Jacques
name.male587=Jae
name.male588=Jaime
name.male589=Jake
name.male590=Jamaal
name.male591=Jamal
name.male592=Jamar
name.male593=Jame
name.male594=Jamel
name.male595=James
name.male596=Jamey
name.male597=Jamie
name.male598=Jamison
name.male599=Jan
name.male600=Jared
name.male601=Jarod
name.male602=Jarred
name.male603=Jarrett
name.male604=Jarrod
name.male605=Jarvis
name.male606=Jason
name.male607=Jasper
name.male608=Javier
name.male609=Jaxon
name.male610=Jay
name.male611=Jaylen
name.male612=Jaylon
name.male613=Jayson
name.male614=Jean
name.male615=Jed
name.male616=Jeferson
name.male617=Jeff
name.male618=Jefferey
name.male619=Jefferson
name.male620=Jeffery
name.male621=Jeffrey
name.male622=Jeffry
name.male623=Jerald
name.male624=Jeramy
name.male625=Jere
name.male626=Jeremiah
name.male627=Jeremy
name.male628=Jerimiah
name.male629=Jermaine
name.male630=Jerold
name.male631=Jerome
name.male632=Jeromy
name.male633=Jerrell
name.male634=Jerrod
name.male635=Jerrold
name.male636=Jerry
name.male637=Jess
name.male638=Jesse
name.male639=Jessie
name.male640=Jesus
name.male641=Jewel
name.male642=Jewell
name.male643=Jim
name.male644=Jimmie
name.male645=Jimmy
name.male646=Joan
name.male647=Joaquin
name.male648=Jody
name.male649=Joe
name.male650=Joel
name.male651=Joesph
name.male652=Joey
name.male653=John
name.male654=Johnathan
name.male655=Johnathon
name.male656=Johnie
name.male657=Johnnie
name.male658=Johnny
name.male659=Johnson
name.male660=Jon
name.male661=Jonah
name.male662=Jonas
name.male663=Jonathan
name.male664=Jonathon
name.male665=Jordan
name.male666=Jordon
name.male667=Jorge
name.male668=Jose
name.male669=Josef
name.male670=Joseph
name.male671=Josh
name.male672=Joshua
name.male673=Josiah
name.male674=Jospeh
name.male675=Josue
name.male676=Juan
name.male677=Jude
name.male678=Judson
name.male679=Jules
name.male680=Julian
name.male681=Julio
name.male682=Julius
name.male683=Junior
name.male684=Justin
name.male685=Kareem
name.male686=Karl
name.male687=Kasey
name.male688=Keenan
name.male689=Keith
name.male690=Kelley
name.male691=Kelly
name.male692=Kelvin
name.male693=Ken
name.male694=Kendall
name.male695=Kendrick
name.male696=Keneth
name.male697=Kenneth
name.male698=Kennith
name.male699=Kenny
name.male700=Kent
name.male701=Kenton
name.male702=Kermit
name.male703=Kerry
name.male704=Keven
name.male705=Kevin
name.male706=Kieth
name.male707=Kim
name.male708=King
name.male709=Kip
name.male710=Kirby
name.male711=Kirk
name.male712=Korey
name.male713=Kory
name.male714=Kraig
name.male715=Kris
name.male716=Kristofer
name.male717=Kristopher
name.male718=Kurt
name.male719=Kurtis
name.male720=Kyle
name.male721=Lacy
name.male722=Lamar
name.male723=Lamont
name.male724=Lance
name.male725=Landon
name.male726=Lane
name.male727=Lanny
name.male728=Larry
name.male729=Latyn
name.male730=Lauren
name.male731=Laurence
name.male732=Lavern
name.male733=Laverne
name.male734=Lawerence
name.male735=Lawrence
name.male736=Lazaro
name.male737=Leandro
name.male738=Lee
name.male739=Leif
name.male740=Leigh
name.male741=Leland
name.male742=Lemuel
name.male743=Len
name.male744=Lenard
name.male745=Lenny
name.male746=Leo
name.male747=Leon
name.male748=Leonard
name.male749=Leonardo
name.male750=Leonel
name.male751=Leopoldo
name.male752=Leroy
name.male753=Les
name.male754=Lesley
name.male755=Leslie
name.male756=Lester
name.male757=Levi
name.male758=Lewis
name.male759=Liam
name.male760=Lincoln
name.male761=Linden
name.male762=Lindsay
name.male763=Lindsey
name.male764=Linel
name.male765=Lino
name.male766=Linwood
name.male767=Lionel
name.male768=Lloyd
name.male769=Logan
name.male770=Lon
name.male771=Long
name.male772=Lonnie
name.male773=Lonny
name.male774=Loren
name.male775=Lorenzo
name.male776=Lou
name.male777=Louie
name.male778=Louis
name.male779=Lowell
name.male780=Loyd
name.male781=Lucas
name.male782=Luciano
name.male783=Lucien
name.male784=Lucio
name.male785=Lucius
name.male786=Luigi
name.male787=Luis
name.male788=Luke
name.male789=Lupe
name.male790=Luther
name.male791=Lyle
name.male792=Lyman
name.male793=Lyndon
name.male794=Lynn
name.male795=Lynwood
name.male796=Mac
name.male797=Mack
name.male798=Major
name.male799=Malcolm
name.male800=Malcom
name.male801=Malik
name.male802=Man
name.male803=Manual
name.male804=Manuel
name.male805=Marc
name.male806=Marcel
name.male807=Marcelino
name.male808=Marcellus
name.male809=Marcelo
name.male810=March
name.male811=Marco
name.male812=Marcos
name.male813=Marcus
name.male814=Margarito
name.male815=Maria
name.male816=Mariano
name.male817=Mario
name.male818=Marion
name.male819=Mark
name.male820=Markus
name.male821=Marlin
name.male822=Marlon
name.male823=Marquis
name.male824=Marshall
name.male825=Martin
name.male826=Marty
name.male827=Marvin
name.male828=Mary
name.male829=Mason
name.male830=Mathew
name.male831=Matt
name.male832=Matthew
name.male833=Maurice
name.male834=Mauricio
name.male835=Mauro
name.male836=Maverick
name.male837=Max
name.male838=Maximo
name.male839=Maxwell
name.male840=Maynard
name.male841=Mckinley
name.male842=Mel
name.male843=Melvin
name.male844=Merle
name.male845=Merlin
name.male846=Merrill
name.male847=Mervin
name.male848=Micah
name.male849=Michael
name.male850=Michal
name.male851=Michale
name.male852=Micheal
name.male853=Michel
name.male854=Mickey
name.male855=Miguel
name.male856=Mike
name.male857=Mikel
name.male858=Milan
name.male859=Miles
name.male860=Milford
name.male861=Millard
name.male862=Milo
name.male863=Milton
name.male864=Minh
name.male865=Miquel
name.male866=Mitch
name.male867=Mitchel
name.male868=Mitchell
name.male869=Modesto
name.male870=Mohamed
name.male871=Mohammad
name.male872=Mohammed
name.male873=Moises
name.male874=Monroe
name.male875=Monte
name.male876=Monty
name.male877=Morgan
name.male878=Morris
name.male879=Morton
name.male880=Mose
name.male881=Moses
name.male882=Moshe
name.male883=Murray
name.male884=Myles
name.male885=Myron
name.male886=Napoleon
name.male887=Narcissus
name.male888=Nathan
name.male889=Nathanael
name.male890=Nathanial
name.male891=Nathaniel
name.male892=Neal
name.male893=Ned
name.male894=Neil
name.male895=Nelson
name.male896=Nestor
name.male897=Neville
name.male898=Newton
name.male899=Nicholas
name.male900=Nick
name.male901=Nickolas
name.male902=Nicky
name.male903=Nicolas
name.male904=Nigel
name.male905=Noah
name.male906=Noble
name.male907=Noe
name.male908=Noel
name.male909=Nolan
name.male910=Norbert
name.male911=Norberto
name.male912=Norman
name.male913=Normand
name.male914=Norris
name.male915=Numbers
name.male916=Octavio
name.male917=Odell
name.male918=Odis
name.male919=Olen
name.male920=Olin
name.male921=Oliver
name.male922=Ollie
name.male923=Omar
name.male924=Omer
name.male925=Oren
name.male926=Orlando
name.male927=Orval
name.male928=Orville
name.male929=Oscar
name.male930=Osvaldo
name.male931=Oswaldo
name.male932=Otha
name.male933=Otis
name.male934=Otto
name.male935=Owen
name.male936=Pablo
name.male937=Palmer
name.male938=Paris
name.male939=Parker
name.male940=Pasquale
name.male941=Pat
name.male942=Patricia
name.male943=Patrick
name.male944=Paul
name.male945=Pedro
name.male946=Percy
name.male947=Perry
name.male948=Pete
name.male949=Peter
name.male950=Phil
name.male951=Philip
name.male952=Phillip
name.male953=Pierre
name.male954=Porfirio
name.male955=Porter
name.male956=Preston
name.male957=Prince
name.male958=Quentin
name.male959=Quincy
name.male960=Quinn
name.male961=Quintin
name.male962=Quinton
name.male963=Rafael
name.male964=Raleigh
name.male965=Ralph
name.male966=Ramiro
name.male967=Ramon
name.male968=Ramsay
name.male969=Randal
name.male970=Randall
name.male971=Randell
name.male972=Randolph
name.male973=Randy
name.male974=Raphael
name.male975=Rashad
name.male976=Raul
name.male977=Ray
name.male978=Rayford
name.male979=Raymon
name.male980=Raymond
name.male981=Raymundo
name.male982=Reed
name.male983=Reese
name.male984=Refugio
name.male985=Reggie
name.male986=Reginald
name.male987=Reid
name.male988=Reinaldo
name.male989=Renaldo
name.male990=Renato
name.male991=Rene
name.male992=Reuben
name.male993=Rex
name.male994=Rey
name.male995=Reyes
name.male996=Reynaldo
name.male997=Rhett
name.male998=Ricardo
name.male999=Rich
name.male1000=Richard
name.male1001=Richie
name.male1002=Rick
name.male1003=Rickey
name.male1004=Rickie
name.male1005=Ricky
name.male1006=Rico
name.male1007=Rigoberto
name.male1008=Riley
name.male1009=Rob
name.male1010=Robbie
name.male1011=Robby
name.male1012=Robert
name.male1013=Roberto
name.male1014=Robin
name.male1015=Robt
name.male1016=Rocco
name.male1017=Rocky
name.male1018=Rod
name.male1019=Roderick
name.male1020=Rodger
name.male1021=Rodney
name.male1022=Rodolfo
name.male1023=Rodrick
name.male1024=Rodrigo
name.male1025=Rogelio
name.male1026=Roger
name.male1027=Roland
name.male1028=Rolando
name.male1029=Rolf
name.male1030=Rolland
name.male1031=Roman
name.male1032=Romeo
name.male1033=Ron
name.male1034=Ronald
name.male1035=Ronnie
name.male1036=Ronny
name.male1037=Roosevelt
name.male1038=Rory
name.male1039=Rosario
name.male1040=Roscoe
name.male1041=Rosendo
name.male1042=Ross
name.male1043=Roxas
name.male1044=Roy
name.male1045=Royal
name.male1046=Royce
name.male1047=Ruben
name.male1048=Rubin
name.male1049=Rudolf
name.male1050=Rudolph
name.male1051=Rudy
name.male1052=Rueben
name.male1053=Rufus
name.male1054=Rupert
name.male1055=Russ
name.male1056=Russel
name.male1057=Russell
name.male1058=Rusty
name.male1059=Ryan
name.male1060=Rye
name.male1061=Rylan
name.male1062=Sal
name.male1063=Salvador
name.male1064=Salvatore
name.male1065=Sam
name.male1066=Sammie
name.male1067=Sammy
name.male1068=Samual
name.male1069=Samuel
name.male1070=Sandy
name.male1071=Sanford
name.male1072=Sang
name.male1073=Santiago
name.male1074=Santo
name.male1075=Santos
name.male1076=Sasha
name.male1077=Saul
name.male1078=Sawyer
name.male1079=Scot
name.male1080=Scott
name.male1081=Scottie
name.male1082=Scotty
name.male1083=Sean
name.male1084=Sebastian
name.male1085=Sergio
name.male1086=Seth
name.male1087=Seymore
name.male1088=Seymour
name.male1089=Shad
name.male1090=Shane
name.male1091=Shannon
name.male1092=Shaun
name.male1093=Shawn
name.male1094=Shayne
name.male1095=Shelby
name.male1096=Sheldon
name.male1097=Shelton
name.male1098=Sherman
name.male1099=Sherwood
name.male1100=Shirley
name.male1101=Shon
name.male1102=Sid
name.male1103=Sidney
name.male1104=Silas
name.male1105=Simon
name.male1106=Snake
name.male1107=Sol
name.male1108=Solomon
name.male1109=Son
name.male1110=Sonny
name.male1111=Soren
name.male1112=Sorrel
name.male1113=Spencer
name.male1114=Stacey
name.male1115=Stacy
name.male1116=Stan
name.male1117=Stanford
name.male1118=Stanley
name.male1119=Stanton
name.male1120=Stefan
name.male1121=Stephan
name.male1122=Stephen
name.male1123=Sterling
name.male1124=Steve
name.male1125=Steven
name.male1126=Stevie
name.male1127=Stewart
name.male1128=Stuart
name.male1129=Sung
name.male1130=Sydney
name.male1131=Sylvester
name.male1132=Tad
name.male1133=Tanner
name.male1134=Taylor
name.male1135=Ted
name.male1136=Teddy
name.male1137=Teodoro
name.male1138=Terence
name.male1139=Terrance
name.male1140=Terrell
name.male1141=Terrence
name.male1142=Terry
name.male1143=Thad
name.male1144=Thaddeus
name.male1145=Thanh
name.male1146=Theo
name.male1147=Theodore
name.male1148=Theron
name.male1149=Thomas
name.male1150=Thorn
name.male1151=Thurman
name.male1152=Tim
name.male1153=Timmy
name.male1154=Timon
name.male1155=Timonthy
name.male1156=Timothy
name.male1157=Titus
name.male1158=Tobias
name.male1159=Toby
name.male1160=Tod
name.male1161=Todd
name.male1162=Tom
name.male1163=Tomas
name.male1164=Tommie
name.male1165=Tommy
name.male1166=Toney
name.male1167=Tony
name.male1168=Tory
name.male1169=Tracey
name.male1170=Tracy
name.male1171=Travis
name.male1172=Trent
name.male1173=Trenton
name.male1174=Trevor
name.male1175=Trey
name.male1176=Trinidad
name.male1177=Tristan
name.male1178=Troy
name.male1179=Truman
name.male1180=Tuan
name.male1181=Tyler
name.male1182=Tyree
name.male1183=Tyrell
name.male1184=Tyron
name.male1185=Tyrone
name.male1186=Tyson
name.male1187=Ulysses
name.male1188=Val
name.male1189=Valentin
name.male1190=Valentine
name.male1191=Van
name.male1192=Vance
name.male1193=Vaughn
name.male1194=Vern
name.male1195=Vernon
name.male1196=Vicente
name.male1197=Victor
name.male1198=Vince
name.male1199=Vincent
name.male1200=Vincenzo
name.male1201=Virgil
name.male1202=Virgilio
name.male1203=Vito
name.male1204=Von
name.male1205=Wade
name.male1206=Waldo
name.male1207=Walker
name.male1208=Wallace
name.male1209=Wallis
name.male1210=Wally
name.male1211=Walter
name.male1212=Walton
name.male1213=Ward
name.male1214=Warner
name.male1215=Warren
name.male1216=Waylon
name.male1217=Wayne
name.male1218=Weldon
name.male1219=Wendell
name.male1220=Werner
name.male1221=Wes
name.male1222=Wesley
name.male1223=Wesley
name.male1224=Weston
name.male1225=Weston
name.male1226=Whit
name.male1227=Whit
name.male1228=Whitney
name.male1229=Whitney
name.male1230=Wilber
name.male1231=Wilber
name.male1232=Wilbert
name.male1233=Wilbert
name.male1234=Wilbur
name.male1235=Wilbur
name.male1236=Wilburn
name.male1237=Wilburn
name.male1238=Wiley
name.male1239=Wiley
name.male1240=Wilford
name.male1241=Wilford
name.male1242=Wilfred
name.male1243=Wilfred
name.male1244=Wilfredo
name.male1245=Wilfredo
name.male1246=Will
name.male1247=Will
name.male1248=Willard
name.male1249=Willard
name.male1250=William
name.male1251=William
name.male1252=Williams
name.male1253=Williams
name.male1254=Willian
name.male1255=Willian
name.male1256=Willie
name.male1257=Willie
name.male1258=Willis
name.male1259=Willis
name.male1260=Willy
name.male1261=Willy
name.male1262=Wilmer
name.male1263=Wilmer
name.male1264=Wilson
name.male1265=Wilson
name.male1266=Wilton
name.male1267=Wilton
name.male1268=Winford
name.male1269=Winford
name.male1270=Winfred
name.male1271=Winfred
name.male1272=Winston
name.male1273=Winston
name.male1274=Woodrow
name.male1275=Woodrow
name.male1276=Wyatt
name.male1277=Wyatt
name.male1278=Wyatt
name.male1279=Xavier
name.male1280=Xavier
name.male1281=Yong
name.male1282=Yong
name.male1283=Young
name.male1284=Young
name.male1285=Yustin
name.male1286=Yustin
name.male1287=Zach
name.male1288=Zach
name.male1289=Zachariah
name.male1290=Zachariah
name.male1291=Zachary
name.male1292=Zachary
name.male1293=Zachery
name.male1294=Zachery
name.male1295=Zack
name.male1296=Zack
name.male1297=Zackary
name.male1298=Zackary
name.male1299=Zane
name.male1300=Zane
name.male1301=Zephyr
name.male1302=Zephyr
name.female1=Aaron
name.female2=Abbey
name.female3=Abbie
name.female4=Abby
name.female5=Abigail
name.female6=Ada
name.female7=Adah
name.female8=Adaline
name.female9=Adam
name.female10=Addie
name.female11=Addison
name.female12=Adel
name.female13=Adela
name.female14=Adelaida
name.female15=Adelaide
name.female16=Adele
name.female17=Adelia
name.female18=Adelina
name.female19=Adeline
name.female20=Adella
name.female21=Adelle
name.female22=Adena
name.female23=Adina
name.female24=Adria
name.female25=Adrian
name.female26=Adriana
name.female27=Adriane
name.female28=Adrianna
name.female29=Adrianne
name.female30=Adrien
name.female31=Adriene
name.female32=Adrienne
name.female33=Adrina
name.female34=Afton
name.female35=Agatha
name.female36=Agnes
name.female37=Agnus
name.female38=Agripina
name.female39=Agueda
name.female40=Agustina
name.female41=Aida
name.female42=Aide
name.female43=Aiko
name.female44=Aileen
name.female45=Ailene
name.female46=Aimee
name.female47=Aisha
name.female48=Akiko
name.female49=Akilah
name.female50=Alahondra
name.female51=Alaina
name.female52=Alaine
name.female53=Alana
name.female54=Alane
name.female55=Alanna
name.female56=Alayna
name.female57=Alba
name.female58=Albert
name.female59=Alberta
name.female60=Albertha
name.female61=Albertina
name.female62=Albertine
name.female63=Albina
name.female64=Alda
name.female65=Alease
name.female66=Alecia
name.female67=Aleen
name.female68=Aleida
name.female69=Aleisha
name.female70=Alejandra
name.female71=Alejandrina
name.female72=Alena
name.female73=Alene
name.female74=Alesha
name.female75=Aleshia
name.female76=Alesia
name.female77=Alessandra
name.female78=Aleta
name.female79=Aletha
name.female80=Alethea
name.female81=Alethia
name.female82=Alex
name.female83=Alexa
name.female84=Alexander
name.female85=Alexandra
name.female86=Alexandria
name.female87=Alexia
name.female88=Alexis
name.female89=Alfreda
name.female90=Alfredia
name.female91=Ali
name.female92=Alia
name.female93=Alica
name.female94=Alice
name.female95=Alicia
name.female96=Alida
name.female97=Alina
name.female98=Aline
name.female99=Alisa
name.female100=Alise
name.female101=Alisha
name.female102=Alishia
name.female103=Alisia
name.female104=Alison
name.female105=Alissa
name.female106=Alita
name.female107=Alix
name.female108=Aliza
name.female109=Alla
name.female110=Alleen
name.female111=Allegra
name.female112=Allen
name.female113=Allena
name.female114=Allene
name.female115=Allie
name.female116=Alline
name.female117=Allison
name.female118=Allyn
name.female119=Allyson
name.female120=Alma
name.female121=Almeda
name.female122=Almeta
name.female123=Alona
name.female124=Alpha
name.female125=Alta
name.female126=Altagracia
name.female127=Altha
name.female128=Althea
name.female129=Alva
name.female130=Alvera
name.female131=Alverta
name.female132=Alvina
name.female133=Alyce
name.female134=Alycia
name.female135=Alysa
name.female136=Alyse
name.female137=Alysha
name.female138=Alysia
name.female139=Alyson
name.female140=Alyssa
name.female141=Amada
name.female142=Amal
name.female143=Amalia
name.female144=Amanda
name.female145=Amaryllis
name.female146=Amber
name.female147=Amberly
name.female148=Amee
name.female149=Amelia
name.female150=America
name.female151=Amethyst
name.female152=Ami
name.female153=Amie
name.female154=Amiee
name.female155=Amina
name.female156=Amira
name.female157=Ammie
name.female158=Amparo
name.female159=Amy
name.female160=Ana
name.female161=Anabel
name.female162=Analisa
name.female163=Anamaria
name.female164=Anastacia
name.female165=Anastasia
name.female166=Andera
name.female167=Andra
name.female168=Andre
name.female169=Andrea
name.female170=Andree
name.female171=Andrew
name.female172=Andria
name.female173=Anette
name.female174=Angel
name.female175=Angela
name.female176=Angele
name.female177=Angelena
name.female178=Angeles
name.female179=Angelia
name.female180=Angelic
name.female181=Angelica
name.female182=Angelika
name.female183=Angelina
name.female184=Angeline
name.female185=Angelique
name.female186=Angelita
name.female187=Angella
name.female188=Angelo
name.female189=Angelyn
name.female190=Angie
name.female191=Angila
name.female192=Angla
name.female193=Angle
name.female194=Anglea
name.female195=Anh
name.female196=Anika
name.female197=Anisa
name.female198=Anisha
name.female199=Anissa
name.female200=Anita
name.female201=Anitra
name.female202=Anja
name.female203=Anjanette
name.female204=Anjelica
name.female205=Ann
name.female206=Anna
name.female207=Annabel
name.female208=Annabell
name.female209=Annabelle
name.female210=Annabellie
name.female211=Annalee
name.female212=Annalisa
name.female213=Annamae
name.female214=Annamaria
name.female215=Annamarie
name.female216=Anne
name.female217=Anneliese
name.female218=Annelle
name.female219=Annemarie
name.female220=Annett
name.female221=Annetta
name.female222=Annette
name.female223=Annice
name.female224=Annie
name.female225=Annika
name.female226=Annis
name.female227=Annita
name.female228=Annmarie
name.female229=Anthony
name.female230=Antionette
name.female231=Antoinette
name.female232=Antonetta
name.female233=Antonette
name.female234=Antonia
name.female235=Antonietta
name.female236=Antonina
name.female237=Antonio
name.female238=Anya
name.female239=Apolonia
name.female240=April
name.female241=Apryl
name.female242=Ara
name.female243=Araceli
name.female244=Aracelis
name.female245=Aracely
name.female246=Arcelia
name.female247=Ardath
name.female248=Ardelia
name.female249=Ardell
name.female250=Ardella
name.female251=Ardelle
name.female252=Ardis
name.female253=Ardith
name.female254=Areona
name.female255=Aretha
name.female256=Argelia
name.female257=Argentina
name.female258=Ariana
name.female259=Ariane
name.female260=Arianna
name.female261=Arianne
name.female262=Arica
name.female263=Arie
name.female264=Ariel
name.female265=Arielle
name.female266=Arla
name.female267=Arlean
name.female268=Arleen
name.female269=Arlena
name.female270=Arlene
name.female271=Arletha
name.female272=Arletta
name.female273=Arlette
name.female274=Arlinda
name.female275=Arline
name.female276=Arlyne
name.female277=Armanda
name.female278=Armandina
name.female279=Armida
name.female280=Arminda
name.female281=Arnetta
name.female282=Arnette
name.female283=Arnita
name.female284=Arthur
name.female285=Artie
name.female286=Arvilla
name.female287=Asha
name.female288=Ashanti
name.female289=Ashely
name.female290=Ashlea
name.female291=Ashlee
name.female292=Ashleigh
name.female293=Ashley
name.female294=Ashli
name.female295=Ashlie
name.female296=Ashly
name.female297=Ashlyn
name.female298=Ashton
name.female299=Asia
name.female300=Asley
name.female301=Assunta
name.female302=Astrid
name.female303=Asuncion
name.female304=Athena
name.female305=Aubrey
name.female306=Audie
name.female307=Audra
name.female308=Audrea
name.female309=Audrey
name.female310=Audria
name.female311=Audrie
name.female312=Audry
name.female313=August
name.female314=Augusta
name.female315=Augustina
name.female316=Augustine
name.female317=Aundrea
name.female318=Aura
name.female319=Aurea
name.female320=Aurelia
name.female321=Aurora
name.female322=Aurore
name.female323=Austin
name.female324=Autumn
name.female325=Ava
name.female326=Avelina
name.female327=Avery
name.female328=Avis
name.female329=Avril
name.female330=Awilda
name.female331=Ayako
name.female332=Ayana
name.female333=Ayanna
name.female334=Ayesha
name.female335=Azalea
name.female336=Azalee
name.female337=Azucena
name.female338=Azzie
name.female339=Babara
name.female340=Babette
name.female341=Bailey
name.female342=Bambi
name.female343=Bao
name.female344=Barabara
name.female345=Barb
name.female346=Barbar
name.female347=Barbara
name.female348=Barbara-Anne
name.female349=Barbera
name.female350=Barbie
name.female351=Barbra
name.female352=Bari
name.female353=Barrie
name.female354=Basilia
name.female355=Bea
name.female356=Beata
name.female357=Beatrice
name.female358=Beatris
name.female359=Beatriz
name.female360=Beaulah
name.female361=Bebe
name.female362=Becki
name.female363=Beckie
name.female364=Becky
name.female365=Bee
name.female366=Belen
name.female367=Belia
name.female368=Belinda
name.female369=Belkis
name.female370=Bell
name.female371=Bella
name.female372=Belle
name.female373=Belva
name.female374=Benita
name.female375=Bennie
name.female376=Berenice
name.female377=Berna
name.female378=Bernadette
name.female379=Bernadine
name.female380=Bernarda
name.female381=Bernardina
name.female382=Bernardine
name.female383=Berneice
name.female384=Bernetta
name.female385=Bernice
name.female386=Bernie
name.female387=Berniece
name.female388=Bernita
name.female389=Berry
name.female390=Berta
name.female391=Bertha
name.female392=Bertie
name.female393=Beryl
name.female394=Bess
name.female395=Bessie
name.female396=Beth
name.female397=Bethanie
name.female398=Bethann
name.female399=Bethany
name.female400=Bethel
name.female401=Betsey
name.female402=Betsy
name.female403=Bette
name.female404=Bettie
name.female405=Bettina
name.female406=Betty
name.female407=Bettyann
name.female408=Bettye
name.female409=Beula
name.female410=Beulah
name.female411=Bev
name.female412=Beverlee
name.female413=Beverley
name.female414=Beverly
name.female415=Bianca
name.female416=Bibi
name.female417=Billi
name.female418=Billie
name.female419=Billy
name.female420=Billye
name.female421=Birdie
name.female422=Birgit
name.female423=Blair
name.female424=Blake
name.female425=Blanca
name.female426=Blanch
name.female427=Blanche
name.female428=Blondell
name.female429=Blossom
name.female430=Blythe
name.female431=Bobbi
name.female432=Bobbie
name.female433=Bobby
name.female434=Bobbye
name.female435=Bobette
name.female436=Bok
name.female437=Bong
name.female438=Bonita
name.female439=Bonnie
name.female440=Bonny
name.female441=Branda
name.female442=Brande
name.female443=Brandee
name.female444=Brandi
name.female445=Brandie
name.female446=Brandon
name.female447=Brandy
name.female448=Breana
name.female449=Breann
name.female450=Breanna
name.female451=Breanne
name.female452=Bree
name.female453=Brenda
name.female454=Brenna
name.female455=Brett
name.female456=Brian
name.female457=Briana
name.female458=Brianna
name.female459=Brianne
name.female460=Briar
name.female461=Bridget
name.female462=Bridgett
name.female463=Bridgette
name.female464=Brielle
name.female465=Brigette
name.female466=Brigid
name.female467=Brigida
name.female468=Brigitte
name.female469=Brinda
name.female470=Britany
name.female471=Britney
name.female472=Britni
name.female473=Britt
name.female474=Britta
name.female475=Brittaney
name.female476=Brittani
name.female477=Brittanie
name.female478=Brittany
name.female479=Britteny
name.female480=Brittney
name.female481=Brittni
name.female482=Brittny
name.female483=Bronwyn
name.female484=Brook
name.female485=Brooke
name.female486=Bruna
name.female487=Brunilda
name.female488=Bryanna
name.female489=Brynn
name.female490=Buena
name.female491=Buffy
name.female492=Bula
name.female493=Bulah
name.female494=Bunny
name.female495=Burma
name.female496=Caitlin
name.female497=Caitlyn
name.female498=Calandra
name.female499=Calista
name.female500=Calla
name.female501=Callie
name.female502=Camelia
name.female503=Camellia
name.female504=Cameron
name.female505=Cami
name.female506=Camie
name.female507=Camila
name.female508=Camilla
name.female509=Camille
name.female510=Cammie
name.female511=Cammy
name.female512=Candace
name.female513=Candance
name.female514=Candelaria
name.female515=Candi
name.female516=Candice
name.female517=Candida
name.female518=Candie
name.female519=Candis
name.female520=Candra
name.female521=Candy
name.female522=Candyce
name.female523=Caprice
name.female524=Cara
name.female525=Caren
name.female526=Carey
name.female527=Cari
name.female528=Caridad
name.female529=Carie
name.female530=Carin
name.female531=Carina
name.female532=Carisa
name.female533=Carissa
name.female534=Carita
name.female535=Carl
name.female536=Carla
name.female537=Carlee
name.female538=Carleen
name.female539=Carlena
name.female540=Carlene
name.female541=Carletta
name.female542=Carley
name.female543=Carli
name.female544=Carlie
name.female545=Carline
name.female546=Carlita
name.female547=Carlos
name.female548=Carlota
name.female549=Carlotta
name.female550=Carly
name.female551=Carlyn
name.female552=Carma
name.female553=Carman
name.female554=Carmel
name.female555=Carmela
name.female556=Carmelia
name.female557=Carmelina
name.female558=Carmelita
name.female559=Carmella
name.female560=Carmen
name.female561=Carmina
name.female562=Carmon
name.female563=Carol
name.female564=Carola
name.female565=Carolann
name.female566=Carole
name.female567=Carolee
name.female568=Carolin
name.female569=Carolina
name.female570=Caroline
name.female571=Caroll
name.female572=Carolyn
name.female573=Carolyne
name.female574=Carolynn
name.female575=Caron
name.female576=Caroyln
name.female577=Carri
name.female578=Carrie
name.female579=Carrol
name.female580=Carroll
name.female581=Carry
name.female582=Cary
name.female583=Caryl
name.female584=Carylon
name.female585=Caryn
name.female586=Casandra
name.female587=Casey
name.female588=Casie
name.female589=Casimira
name.female590=Cassandra
name.female591=Cassaundra
name.female592=Cassey
name.female593=Cassi
name.female594=Cassidy
name.female595=Cassie
name.female596=Cassondra
name.female597=Cassy
name.female598=Catalina
name.female599=Catarina
name.female600=Caterina
name.female601=Catharine
name.female602=Catherin
name.female603=Catherina
name.female604=Catherine
name.female605=Cathern
name.female606=Catheryn
name.female607=Cathey
name.female608=Cathi
name.female609=Cathie
name.female610=Cathleen
name.female611=Cathrine
name.female612=Cathryn
name.female613=Cathy
name.female614=Catina
name.female615=Catrice
name.female616=Catrina
name.female617=Cayla
name.female618=Cecelia
name.female619=Cecil
name.female620=Cecila
name.female621=Cecile
name.female622=Cecilia
name.female623=Cecille
name.female624=Cecily
name.female625=Celena
name.female626=Celesta
name.female627=Celeste
name.female628=Celestina
name.female629=Celestine
name.female630=Celia
name.female631=Celina
name.female632=Celinda
name.female633=Celine
name.female634=Celsa
name.female635=Ceola
name.female636=Chae
name.female637=Chan
name.female638=Chana
name.female639=Chanda
name.female640=Chandra
name.female641=Chanel
name.female642=Chanell
name.female643=Chanelle
name.female644=Chang
name.female645=Chantal
name.female646=Chantay
name.female647=Chante
name.female648=Chantel
name.female649=Chantell
name.female650=Chantelle
name.female651=Chara
name.female652=Chariisa
name.female653=Charis
name.female654=Charise
name.female655=Charissa
name.female656=Charisse
name.female657=Charita
name.female658=Charity
name.female659=Charla
name.female660=Charleen
name.female661=Charlena
name.female662=Charlene
name.female663=Charles
name.female664=Charlesetta
name.female665=Charlette
name.female666=Charlie
name.female667=Charline
name.female668=Charlott
name.female669=Charlotte
name.female670=Charlsie
name.female671=Charlyn
name.female672=Charmain
name.female673=Charmaine
name.female674=Charolette
name.female675=Chasidy
name.female676=Chasity
name.female677=Chassidy
name.female678=Chassity
name.female679=Chastity
name.female680=Chau
name.female681=Chaya
name.female682=Chelsea
name.female683=Chelsey
name.female684=Chelsie
name.female685=Cher
name.female686=Chere
name.female687=Cheree
name.female688=Cherelle
name.female689=Cheri
name.female690=Cherie
name.female691=Cherilyn
name.female692=Cherise
name.female693=Cherish
name.female694=Cherly
name.female695=Cherlyn
name.female696=Cherri
name.female697=Cherrie
name.female698=Cherry
name.female699=Cherryl
name.female700=Chery
name.female701=Cheryl
name.female702=Cheryle
name.female703=Cheryll
name.female704=Cheyenne
name.female705=Chi
name.female706=Chia
name.female707=Chieko
name.female708=Chin
name.female709=China
name.female710=Ching
name.female711=Chiquita
name.female712=Chloe
name.female713=Chong
name.female714=Chris
name.female715=Chrissy
name.female716=Christa
name.female717=Christal
name.female718=Christeen
name.female719=Christel
name.female720=Christen
name.female721=Christena
name.female722=Christene
name.female723=Christi
name.female724=Christia
name.female725=Christian
name.female726=Christiana
name.female727=Christiane
name.female728=Christie
name.female729=Christin
name.female730=Christina
name.female731=Christine
name.female732=Christinia
name.female733=Christopher
name.female734=Christy
name.female735=Chrystal
name.female736=Chu
name.female737=Chun
name.female738=Chung
name.female739=Ciara
name.female740=Cicely
name.female741=Ciera
name.female742=Cierra
name.female743=Cinda
name.female744=Cinderella
name.female745=Cindi
name.female746=Cindie
name.female747=Cindy
name.female748=Cinthia
name.female749=Cira
name.female750=Clair
name.female751=Claire
name.female752=Clara
name.female753=Clare
name.female754=Clarence
name.female755=Claretha
name.female756=Claretta
name.female757=Claribel
name.female758=Clarice
name.female759=Clarinda
name.female760=Clarine
name.female761=Claris
name.female762=Clarisa
name.female763=Clarissa
name.female764=Clarita
name.female765=Classie
name.female766=Claude
name.female767=Claudette
name.female768=Claudia
name.female769=Claudie
name.female770=Claudine
name.female771=Clelia
name.female772=Clemencia
name.female773=Clementina
name.female774=Clementine
name.female775=Clemmie
name.female776=Cleo
name.female777=Cleopatra
name.female778=Cleora
name.female779=Cleotilde
name.female780=Cleta
name.female781=Clora
name.female782=Clorinda
name.female783=Clotilde
name.female784=Clover
name.female785=Clyde
name.female786=Codi
name.female787=Cody
name.female788=Colby
name.female789=Coleen
name.female790=Colene
name.female791=Coletta
name.female792=Colette
name.female793=Colleen
name.female794=Collen
name.female795=Collene
name.female796=Collette
name.female797=Concepcion
name.female798=Conception
name.female799=Concetta
name.female800=Concha
name.female801=Conchita
name.female802=Connie
name.female803=Constance
name.female804=Consuela
name.female805=Consuelo
name.female806=Contessa
name.female807=Cora
name.female808=Coral
name.female809=Coralee
name.female810=Coralie
name.female811=Corazon
name.female812=Cordelia
name.female813=Cordia
name.female814=Cordie
name.female815=Coreen
name.female816=Corene
name.female817=Coretta
name.female818=Corey
name.female819=Cori
name.female820=Corie
name.female821=Corina
name.female822=Corine
name.female823=Corinna
name.female824=Corinne
name.female825=Corliss
name.female826=Cornelia
name.female827=Corrie
name.female828=Corrin
name.female829=Corrina
name.female830=Corrine
name.female831=Corrinne
name.female832=Cortney
name.female833=Cory
name.female834=Courtney
name.female835=Creola
name.female836=Cris
name.female837=Criselda
name.female838=Crissy
name.female839=Crista
name.female840=Cristal
name.female841=Cristen
name.female842=Cristi
name.female843=Cristie
name.female844=Cristin
name.female845=Cristina
name.female846=Cristine
name.female847=Cristy
name.female848=Cruz
name.female849=Crysta
name.female850=Crystal
name.female851=Crystle
name.female852=Curtis
name.female853=Cyndi
name.female854=Cyndy
name.female855=Cynthia
name.female856=Cyrstal
name.female857=Cythia
name.female858=Dacia
name.female859=Dagmar
name.female860=Dagny
name.female861=Dahlia
name.female862=Daina
name.female863=Daine
name.female864=Daisey
name.female865=Daisy
name.female866=Daisy-Mae
name.female867=Dakota
name.female868=Dale
name.female869=Dalene
name.female870=Dalia
name.female871=Dalie
name.female872=Dalila
name.female873=Dallas
name.female874=Dallis
name.female875=Damaris
name.female876=Dan
name.female877=Dana
name.female878=Danae
name.female879=Danelle
name.female880=Danette
name.female881=Dani
name.female882=Dania
name.female883=Danica
name.female884=Daniel
name.female885=Daniela
name.female886=Daniele
name.female887=Daniell
name.female888=Daniella
name.female889=Danielle
name.female890=Danika
name.female891=Danille
name.female892=Danita
name.female893=Dann
name.female894=Danna
name.female895=Dannette
name.female896=Dannie
name.female897=Dannielle
name.female898=Danuta
name.female899=Danyel
name.female900=Danyell
name.female901=Danyelle
name.female902=Daphine
name.female903=Daphne
name.female904=Dara
name.female905=Darby
name.female906=Darcel
name.female907=Darcey
name.female908=Darci
name.female909=Darcie
name.female910=Darcy
name.female911=Daria
name.female912=Darla
name.female913=Darleen
name.female914=Darlena
name.female915=Darlene
name.female916=Darline
name.female917=Darnell
name.female918=Daryl
name.female919=David
name.female920=Davida
name.female921=Davina
name.female922=Dawn
name.female923=Dawna
name.female924=Dawne
name.female925=Dayle
name.female926=Dayna
name.female927=Daysi
name.female928=Deadra
name.female929=Dean
name.female930=Deana
name.female931=Deandra
name.female932=Deandrea
name.female933=Deane
name.female934=Deann
name.female935=Deanna
name.female936=Deanne
name.female937=Deb
name.female938=Debbi
name.female939=Debbie
name.female940=Debbra
name.female941=Debby
name.female942=Debera
name.female943=Debi
name.female944=Debie
name.female945=Debora
name.female946=Deborah
name.female947=Debra
name.female948=Debrah
name.female949=Debroah
name.female950=Dede
name.female951=Dedra
name.female952=Dee
name.female953=Deeann
name.female954=Deeanna
name.female955=Deedee
name.female956=Deedra
name.female957=Deena
name.female958=Deetta
name.female959=Deidra
name.female960=Deidre
name.female961=Deirdre
name.female962=Deja
name.female963=Delaine
name.female964=Delana
name.female965=Delaney
name.female966=Delcie
name.female967=Delena
name.female968=Delfina
name.female969=Delia
name.female970=Delicia
name.female971=Delila
name.female972=Delilah
name.female973=Delinda
name.female974=Delisa
name.female975=Dell
name.female976=Della
name.female977=Delma
name.female978=Delmy
name.female979=Delois
name.female980=Deloise
name.female981=Delora
name.female982=Deloras
name.female983=Delores
name.female984=Deloris
name.female985=Delorse
name.female986=Delpha
name.female987=Delphia
name.female988=Delphine
name.female989=Delsie
name.female990=Delta
name.female991=Demetra
name.female992=Demetria
name.female993=Demetrice
name.female994=Demetrius
name.female995=Dena
name.female996=Denae
name.female997=Deneen
name.female998=Denese
name.female999=Denice
name.female1000=Denise
name.female1001=Denisha
name.female1002=Denisse
name.female1003=Denita
name.female1004=Denna
name.female1005=Dennis
name.female1006=Dennise
name.female1007=Denny
name.female1008=Denyse
name.female1009=Deon
name.female1010=Deonna
name.female1011=Desirae
name.female1012=Desire
name.female1013=Desiree
name.female1014=Despina
name.female1015=Dessi
name.female1016=Dessie
name.female1017=Destiny
name.female1018=Detra
name.female1019=Devin
name.female1020=Devon
name.female1021=Devona
name.female1022=Devora
name.female1023=Devorah
name.female1024=Dia
name.female1025=Diamond
name.female1026=Dian
name.female1027=Diana
name.female1028=Diane
name.female1029=Diann
name.female1030=Dianna
name.female1031=Dianne
name.female1032=Diedra
name.female1033=Diedre
name.female1034=Dierdre
name.female1035=Digna
name.female1036=Dimple
name.female1037=Dina
name.female1038=Dinah
name.female1039=Dinorah
name.female1040=Dion
name.female1041=Dione
name.female1042=Dionna
name.female1043=Dionne
name.female1044=Divina
name.female1045=Dixie
name.female1046=Dodie
name.female1047=Dollie
name.female1048=Dolly
name.female1049=Dolores
name.female1050=Doloris
name.female1051=Domenica
name.female1052=Dominga
name.female1053=Dominica
name.female1054=Dominique
name.female1055=Dominque
name.female1056=Domitila
name.female1057=Domonique
name.female1058=Dona
name.female1059=Donald
name.female1060=Donella
name.female1061=Donetta
name.female1062=Donette
name.female1063=Dong
name.female1064=Donita
name.female1065=Donna
name.female1066=Donna-Jo
name.female1067=Donnetta
name.female1068=Donnette
name.female1069=Donnie
name.female1070=Donya
name.female1071=Dora
name.female1072=Dorathy
name.female1073=Dorcas
name.female1074=Doreatha
name.female1075=Doreen
name.female1076=Dorene
name.female1077=Doretha
name.female1078=Dorethea
name.female1079=Doretta
name.female1080=Dori
name.female1081=Doria
name.female1082=Dorian
name.female1083=Dorie
name.female1084=Dorinda
name.female1085=Dorine
name.female1086=Doris
name.female1087=Dorla
name.female1088=Dorotha
name.female1089=Dorothea
name.female1090=Dorothy
name.female1091=Dorris
name.female1092=Dortha
name.female1093=Dorthea
name.female1094=Dorthey
name.female1095=Dorthy
name.female1096=Dot
name.female1097=Dottie
name.female1098=Dotty
name.female1099=Dovie
name.female1100=Dreama
name.female1101=Drema
name.female1102=Drew
name.female1103=Drucilla
name.female1104=Drusilla
name.female1105=Dulce
name.female1106=Dulcie
name.female1107=Dung
name.female1108=Dusti
name.female1109=Dusty
name.female1110=Dwana
name.female1111=Dyan
name.female1112=Earlean
name.female1113=Earleen
name.female1114=Earlene
name.female1115=Earlie
name.female1116=Earline
name.female1117=Earnestine
name.female1118=Eartha
name.female1119=Easter
name.female1120=Eboni
name.female1121=Ebonie
name.female1122=Ebony
name.female1123=Echo
name.female1124=Eda
name.female1125=Edda
name.female1126=Eddie
name.female1127=Edelmira
name.female1128=Eden
name.female1129=Edie
name.female1130=Edith
name.female1131=Edna
name.female1132=Edra
name.female1133=Edris
name.female1134=Edward
name.female1135=Edwina
name.female1136=Edyth
name.female1137=Edythe
name.female1138=Effie
name.female1139=Ehtel
name.female1140=Eileen
name.female1141=Eilene
name.female1142=Ela
name.female1143=Eladia
name.female1144=Elaina
name.female1145=Elaine
name.female1146=Elana
name.female1147=Elane
name.female1148=Elanor
name.female1149=Elayne
name.female1150=Elba
name.female1151=Elda
name.female1152=Eldora
name.female1153=Eleanor
name.female1154=Eleanora
name.female1155=Eleanore
name.female1156=Elease
name.female1157=Elena
name.female1158=Elene
name.female1159=Eleni
name.female1160=Elenor
name.female1161=Elenora
name.female1162=Elenore
name.female1163=Eleonor
name.female1164=Eleonora
name.female1165=Eleonore
name.female1166=Elfreda
name.female1167=Elfrieda
name.female1168=Elfriede
name.female1169=Elia
name.female1170=Eliana
name.female1171=Elicia
name.female1172=Elida
name.female1173=Elidia
name.female1174=Elin
name.female1175=Elina
name.female1176=Elinor
name.female1177=Elinore
name.female1178=Elisa
name.female1179=Elisabeth
name.female1180=Elise
name.female1181=Elisha
name.female1182=Elissa
name.female1183=Eliz
name.female1184=Eliza
name.female1185=Elizabet
name.female1186=Elizabeth
name.female1187=Elizbeth
name.female1188=Elizebeth
name.female1189=Elke
name.female1190=Ella
name.female1191=Ellamae
name.female1192=Ellan
name.female1193=Ellen
name.female1194=Ellena
name.female1195=Elli
name.female1196=Ellie
name.female1197=Ellis
name.female1198=Elly
name.female1199=Ellyn
name.female1200=Elma
name.female1201=Elmer
name.female1202=Elmira
name.female1203=Elna
name.female1204=Elnora
name.female1205=Elodia
name.female1206=Elois
name.female1207=Eloisa
name.female1208=Eloise
name.female1209=Elouise
name.female1210=Elsa
name.female1211=Else
name.female1212=Elsie
name.female1213=Elsy
name.female1214=Elva
name.female1215=Elvera
name.female1216=Elvia
name.female1217=Elvie
name.female1218=Elvina
name.female1219=Elvira
name.female1220=Elwanda
name.female1221=Elyse
name.female1222=Elza
name.female1223=Ema
name.female1224=Emelda
name.female1225=Emelia
name.female1226=Emelina
name.female1227=Emeline
name.female1228=Emely
name.female1229=Emerald
name.female1230=Emerita
name.female1231=Emiko
name.female1232=Emilee
name.female1233=Emilia
name.female1234=Emilie
name.female1235=Emily
name.female1236=Emma
name.female1237=Emmaline
name.female1238=Emmie
name.female1239=Emmy
name.female1240=Emogene
name.female1241=Ena
name.female1242=Enda
name.female1243=Enedina
name.female1244=Eneida
name.female1245=Enid
name.female1246=Enola
name.female1247=Enriqueta
name.female1248=Epifania
name.female1249=Era
name.female1250=Eric
name.female1251=Erica
name.female1252=Ericka
name.female1253=Erika
name.female1254=Erin
name.female1255=Erinn
name.female1256=Erlene
name.female1257=Erlinda
name.female1258=Erline
name.female1259=Erma
name.female1260=Ermelinda
name.female1261=Erminia
name.female1262=Erna
name.female1263=Ernestina
name.female1264=Ernestine
name.female1265=Eryn
name.female1266=Esmeralda
name.female1267=Esperanza
name.female1268=Essie
name.female1269=Esta
name.female1270=Estefana
name.female1271=Estela
name.female1272=Estell
name.female1273=Estella
name.female1274=Estelle
name.female1275=Ester
name.female1276=Esther
name.female1277=Estrella
name.female1278=Etha
name.female1279=Ethel
name.female1280=Ethelene
name.female1281=Ethelyn
name.female1282=Ethyl
name.female1283=Etsuko
name.female1284=Etta
name.female1285=Ettie
name.female1286=Eufemia
name.female1287=Eugena
name.female1288=Eugene
name.female1289=Eugenia
name.female1290=Eugenie
name.female1291=Eula
name.female1292=Eulah
name.female1293=Eulalia
name.female1294=Eun
name.female1295=Euna
name.female1296=Eunice
name.female1297=Eura
name.female1298=Eusebia
name.female1299=Eustolia
name.female1300=Eva
name.female1301=Evadne
name.female1302=Evalyn
name.female1303=Evan
name.female1304=Evangelina
name.female1305=Evangeline
name.female1306=Eve
name.female1307=Evelia
name.female1308=Evelin
name.female1309=Evelina
name.female1310=Eveline
name.female1311=Evelyn
name.female1312=Evelyne
name.female1313=Evelynn
name.female1314=Evette
name.female1315=Evia
name.female1316=Evie
name.female1317=Evita
name.female1318=Evon
name.female1319=Evonne
name.female1320=Ewa
name.female1321=Exie
name.female1322=Fabiola
name.female1323=Fae
name.female1324=Fairy
name.female1325=Faith
name.female1326=Fall
name.female1327=Fallon
name.female1328=Fannie
name.female1329=Fanny
name.female1330=Farah
name.female1331=Farrah
name.female1332=Fatima
name.female1333=Fatimah
name.female1334=Faustina
name.female1335=Faviola
name.female1336=Fawn
name.female1337=Fay
name.female1338=Faye
name.female1339=Felecia
name.female1340=Felica
name.female1341=Felice
name.female1342=Felicia
name.female1343=Felicidad
name.female1344=Felicita
name.female1345=Felicitas
name.female1346=Felipa
name.female1347=Felisa
name.female1348=Felisha
name.female1349=Fermina
name.female1350=Fern
name.female1351=Fernanda
name.female1352=Fernande
name.female1353=Ferne
name.female1354=Fidela
name.female1355=Fidelia
name.female1356=Filomena
name.female1357=Fiona
name.female1358=Flavia
name.female1359=Fleta
name.female1360=Flo
name.female1361=Flor
name.female1362=Flora
name.female1363=Florance
name.female1364=Florence
name.female1365=Florencia
name.female1366=Florene
name.female1367=Florentina
name.female1368=Floretta
name.female1369=Floria
name.female1370=Florida
name.female1371=Florinda
name.female1372=Florine
name.female1373=Florrie
name.female1374=Flossie
name.female1375=Floy
name.female1376=Fonda
name.female1377=Fran
name.female1378=France
name.female1379=Francene
name.female1380=Frances
name.female1381=Francesca
name.female1382=Franchesca
name.female1383=Francie
name.female1384=Francina
name.female1385=Francine
name.female1386=Francis
name.female1387=Francisca
name.female1388=Francisco
name.female1389=Francoise
name.female1390=Frank
name.female1391=Frankie
name.female1392=Fransisca
name.female1393=Fred
name.female1394=Freda
name.female1395=Fredda
name.female1396=Freddie
name.female1397=Frederica
name.female1398=Fredericka
name.female1399=Fredia
name.female1400=Fredricka
name.female1401=Freeda
name.female1402=Freida
name.female1403=Frida
name.female1404=Frieda
name.female1405=Fumiko
name.female1406=Gabriel
name.female1407=Gabriela
name.female1408=Gabriele
name.female1409=Gabriella
name.female1410=Gabrielle
name.female1411=Gail
name.female1412=Gala
name.female1413=Gale
name.female1414=Galina
name.female1415=Garnet
name.female1416=Garnett
name.female1417=Gary
name.female1418=Gaye
name.female1419=Gayla
name.female1420=Gayle
name.female1421=Gaylene
name.female1422=Gaynell
name.female1423=Gaynelle
name.female1424=Gearldine
name.female1425=Gema
name.female1426=Gemma
name.female1427=Gena
name.female1428=Gene
name.female1429=Genesis
name.female1430=Geneva
name.female1431=Genevie
name.female1432=Genevieve
name.female1433=Genevive
name.female1434=Genia
name.female1435=Genie
name.female1436=Genna
name.female1437=Gennie
name.female1438=Genny
name.female1439=Genoveva
name.female1440=Georgann
name.female1441=George
name.female1442=Georgeann
name.female1443=Georgeanna
name.female1444=Georgene
name.female1445=Georgetta
name.female1446=Georgette
name.female1447=Georgia
name.female1448=Georgiana
name.female1449=Georgiann
name.female1450=Georgianna
name.female1451=Georgianne
name.female1452=Georgie
name.female1453=Georgina
name.female1454=Georgine
name.female1455=Gerald
name.female1456=Geraldine
name.female1457=Geralyn
name.female1458=Gerda
name.female1459=Geri
name.female1460=Germaine
name.female1461=Gerri
name.female1462=Gerry
name.female1463=Gertha
name.female1464=Gertie
name.female1465=Gertrud
name.female1466=Gertrude
name.female1467=Gertrudis
name.female1468=Gertude
name.female1469=Ghislaine
name.female1470=Gia
name.female1471=Gianna
name.female1472=Gidget
name.female1473=Gigi
name.female1474=Gilberte
name.female1475=Gilda
name.female1476=Gillian
name.female1477=Gilma
name.female1478=Gina
name.female1479=Ginette
name.female1480=Ginger
name.female1481=Ginny
name.female1482=Giovanna
name.female1483=Gisela
name.female1484=Gisele
name.female1485=Giselle
name.female1486=Gita
name.female1487=Giuseppina
name.female1488=Gladis
name.female1489=Glady
name.female1490=Gladys
name.female1491=Glayds
name.female1492=Glenda
name.female1493=Glendora
name.female1494=Glenn
name.female1495=Glenna
name.female1496=Glennie
name.female1497=Glennis
name.female1498=Glinda
name.female1499=Gloria
name.female1500=Glory
name.female1501=Glynda
name.female1502=Glynis
name.female1503=Golda
name.female1504=Golden
name.female1505=Goldie
name.female1506=Grace
name.female1507=Gracia
name.female1508=Gracie
name.female1509=Graciela
name.female1510=Grayce
name.female1511=Grazyna
name.female1512=Gregoria
name.female1513=Gregory
name.female1514=Greta
name.female1515=Gretchen
name.female1516=Gretta
name.female1517=Gricelda
name.female1518=Grisel
name.female1519=Griselda
name.female1520=Guadalupe
name.female1521=Gudrun
name.female1522=Guillermina
name.female1523=Gurpreet
name.female1524=Gussie
name.female1525=Gwen
name.female1526=Gwenda
name.female1527=Gwendolyn
name.female1528=Gwenn
name.female1529=Gwyn
name.female1530=Gwyneth
name.female1531=Hae
name.female1532=Hailey
name.female1533=Haley
name.female1534=Halina
name.female1535=Halley
name.female1536=Hallie
name.female1537=Han
name.female1538=Hana
name.female1539=Hang
name.female1540=Hanh
name.female1541=Hanna
name.female1542=Hannah
name.female1543=Hannelore
name.female1544=Harmony
name.female1545=Harold
name.female1546=Harriet
name.female1547=Harriett
name.female1548=Harriette
name.female1549=Hassie
name.female1550=Hattie
name.female1551=Haydee
name.female1552=Hayley
name.female1553=Haylie-Anne
name.female1554=Hazel
name.female1555=Heather
name.female1556=Hedwig
name.female1557=Hedy
name.female1558=Heide
name.female1559=Heidi
name.female1560=Heidy
name.female1561=Heike
name.female1562=Helaine
name.female1563=Helen
name.female1564=Helena
name.female1565=Helene
name.female1566=Helga
name.female1567=Hellen
name.female1568=Henrietta
name.female1569=Henriette
name.female1570=Henry
name.female1571=Herlinda
name.female1572=Herma
name.female1573=Hermelinda
name.female1574=Hermila
name.female1575=Hermina
name.female1576=Hermine
name.female1577=Herminia
name.female1578=Herta
name.female1579=Hertha
name.female1580=Hester
name.female1581=Hettie
name.female1582=Hiedi
name.female1583=Hien
name.female1584=Hilaria
name.female1585=Hilary
name.female1586=Hilda
name.female1587=Hilde
name.female1588=Hildegard
name.female1589=Hildegarde
name.female1590=Hildred
name.female1591=Hillary
name.female1592=Hilma
name.female1593=Hiroko
name.female1594=Hisako
name.female1595=Hoa
name.female1596=Holley
name.female1597=Holli
name.female1598=Hollie
name.female1599=Hollis
name.female1600=Holly
name.female1601=Honey
name.female1602=Hong
name.female1603=Hope
name.female1604=Hortencia
name.female1605=Hortense
name.female1606=Hortensia
name.female1607=Hsiu
name.female1608=Hue
name.female1609=Hui
name.female1610=Hulda
name.female1611=Huong
name.female1612=Hyacinth
name.female1613=Hyo
name.female1614=Hyon
name.female1615=Hyun
name.female1616=Ida
name.female1617=Idalia
name.female1618=Idell
name.female1619=Idella
name.female1620=Iesha
name.female1621=Ignacia
name.female1622=Ila
name.female1623=Ilana
name.female1624=Ilda
name.female1625=Ileana
name.female1626=Ileen
name.female1627=Ilene
name.female1628=Iliana
name.female1629=Illa
name.female1630=Ilona
name.female1631=Ilse
name.female1632=Iluminada
name.female1633=Ima
name.female1634=Imelda
name.female1635=Imogen
name.female1636=Imogene
name.female1637=Ina
name.female1638=India
name.female1639=Indigo
name.female1640=Indira
name.female1641=Inell
name.female1642=Ines
name.female1643=Inez
name.female1644=Inga
name.female1645=Inge
name.female1646=Ingeborg
name.female1647=Inger
name.female1648=Ingrid
name.female1649=Inocencia
name.female1650=Iola
name.female1651=Iona
name.female1652=Ione
name.female1653=Ira
name.female1654=Iraida
name.female1655=Irena
name.female1656=Irene
name.female1657=Irina
name.female1658=Iris
name.female1659=Irish
name.female1660=Irma
name.female1661=Irmgard
name.female1662=Isa
name.female1663=Isabel
name.female1664=Isabell
name.female1665=Isabella
name.female1666=Isabelle
name.female1667=Isadora
name.female1668=Isaura
name.female1669=Isela
name.female1670=Isidra
name.female1671=Isis
name.female1672=Isobel
name.female1673=Iva
name.female1674=Ivana
name.female1675=Ivelisse
name.female1676=Ivette
name.female1677=Ivey
name.female1678=Ivonne
name.female1679=Ivory
name.female1680=Ivy
name.female1681=Izetta
name.female1682=Izola
name.female1683=Jacalyn
name.female1684=Jacelyn
name.female1685=Jacinda
name.female1686=Jacinta
name.female1687=Jack
name.female1688=Jackeline
name.female1689=Jackelyn
name.female1690=Jacki
name.female1691=Jackie
name.female1692=Jacklyn
name.female1693=Jackqueline
name.female1694=Jaclyn
name.female1695=Jacqualine
name.female1696=Jacque
name.female1697=Jacquelin
name.female1698=Jacqueline
name.female1699=Jacquelyn
name.female1700=Jacquelyne
name.female1701=Jacquelynn
name.female1702=Jacquetta
name.female1703=Jacqui
name.female1704=Jacquie
name.female1705=Jacquiline
name.female1706=Jacquline
name.female1707=Jacqulyn
name.female1708=Jada
name.female1709=Jade
name.female1710=Jadwiga
name.female1711=Jae
name.female1712=Jaime
name.female1713=Jaimee
name.female1714=Jaimie
name.female1715=Jaleesa
name.female1716=Jalisa
name.female1717=Jama
name.female1718=Jame
name.female1719=Jamee
name.female1720=James
name.female1721=Jamey
name.female1722=Jami
name.female1723=Jamie
name.female1724=Jamika
name.female1725=Jamila
name.female1726=Jammie
name.female1727=Jan
name.female1728=Jana
name.female1729=Janae
name.female1730=Janay
name.female1731=Jane
name.female1732=Janean
name.female1733=Janee
name.female1734=Janeen
name.female1735=Janel
name.female1736=Janell
name.female1737=Janella
name.female1738=Janelle
name.female1739=Janene
name.female1740=Janessa
name.female1741=Janet
name.female1742=Janeth
name.female1743=Janett
name.female1744=Janetta
name.female1745=Janette
name.female1746=Janey
name.female1747=Jani
name.female1748=Janice
name.female1749=Janie
name.female1750=Janiece
name.female1751=Janina
name.female1752=Janine
name.female1753=Janis
name.female1754=Janise
name.female1755=Janita
name.female1756=Jann
name.female1757=Janna
name.female1758=Jannet
name.female1759=Jannette
name.female1760=Jannie
name.female1761=January
name.female1762=Janyce
name.female1763=Jaqueline
name.female1764=Jaquelyn
name.female1765=Jasmin
name.female1766=Jasmine
name.female1767=Jason
name.female1768=Jassie
name.female1769=Jaunita
name.female1770=Jay
name.female1771=Jaye
name.female1772=Jayme
name.female1773=Jaymie
name.female1774=Jayna
name.female1775=Jayne
name.female1776=Jazmin
name.female1777=Jazmine
name.female1778=Jean
name.female1779=Jeana
name.female1780=Jeane
name.female1781=Jeanelle
name.female1782=Jeanene
name.female1783=Jeanett
name.female1784=Jeanetta
name.female1785=Jeanette
name.female1786=Jeanice
name.female1787=Jeanie
name.female1788=Jeanine
name.female1789=Jeanmarie
name.female1790=Jeanna
name.female1791=Jeanne
name.female1792=Jeannetta
name.female1793=Jeannette
name.female1794=Jeannie
name.female1795=Jeannine
name.female1796=Jeffie
name.female1797=Jeffrey
name.female1798=Jen
name.female1799=Jena
name.female1800=Jenae
name.female1801=Jene
name.female1802=Jenee
name.female1803=Jenell
name.female1804=Jenelle
name.female1805=Jenette
name.female1806=Jeneva
name.female1807=Jeni
name.female1808=Jenice
name.female1809=Jenifer
name.female1810=Jeniffer
name.female1811=Jenine
name.female1812=Jenise
name.female1813=Jenna
name.female1814=Jennefer
name.female1815=Jennell
name.female1816=Jennette
name.female1817=Jenni
name.female1818=Jennie
name.female1819=Jennifer
name.female1820=Jenniffer
name.female1821=Jennine
name.female1822=Jenny
name.female1823=Jeraldine
name.female1824=Jeremy
name.female1825=Jeri
name.female1826=Jerica
name.female1827=Jerilyn
name.female1828=Jerlene
name.female1829=Jerri
name.female1830=Jerrica
name.female1831=Jerrie
name.female1832=Jerry
name.female1833=Jesenia
name.female1834=Jesica
name.female1835=Jesse
name.female1836=Jessenia
name.female1837=Jessi
name.female1838=Jessia
name.female1839=Jessica
name.female1840=Jessie
name.female1841=Jessika
name.female1842=Jessimine
name.female1843=Jestine
name.female1844=Jesus
name.female1845=Jesusa
name.female1846=Jesusita
name.female1847=Jetta
name.female1848=Jettie
name.female1849=Jewel
name.female1850=Jewell
name.female1851=Jill
name.female1852=Jillian
name.female1853=Jimmie
name.female1854=Jimmy
name.female1855=Jin
name.female1856=Jina
name.female1857=Jinny
name.female1858=Joan
name.female1859=Joana
name.female1860=Joane
name.female1861=Joanie
name.female1862=Joann
name.female1863=Joanna
name.female1864=Joanne
name.female1865=Joannie
name.female1866=Joaquina
name.female1867=Jocelyn
name.female1868=Jodee
name.female1869=Jodi
name.female1870=Jodie
name.female1871=Jody
name.female1872=Joeann
name.female1873=Joel
name.female1874=Joella
name.female1875=Joelle
name.female1876=Joellen
name.female1877=Joetta
name.female1878=Joette
name.female1879=Joey
name.female1880=Johana
name.female1881=Johanna
name.female1882=Johanne
name.female1883=John
name.female1884=Johna
name.female1885=Johnetta
name.female1886=Johnette
name.female1887=Johnie
name.female1888=Johnna
name.female1889=Johnnie
name.female1890=Johnny
name.female1891=Johnsie
name.female1892=Joie
name.female1893=Jolanda
name.female1894=Joleen
name.female1895=Jolene
name.female1896=Jolie
name.female1897=Joline
name.female1898=Jolyn
name.female1899=Jolynn
name.female1900=Jona
name.female1901=Jone
name.female1902=Jonell
name.female1903=Jonelle
name.female1904=Jong
name.female1905=Joni
name.female1906=Jonie
name.female1907=Jonna
name.female1908=Jonnie
name.female1909=Jordan
name.female1910=Jose
name.female1911=Josefa
name.female1912=Josefina
name.female1913=Josefine
name.female1914=Joselyn
name.female1915=Joseph
name.female1916=Josephina
name.female1917=Josephine
name.female1918=Josette
name.female1919=Joshua
name.female1920=Josie
name.female1921=Joslyn
name.female1922=Josphine
name.female1923=Jovan
name.female1924=Jovita
name.female1925=Joy
name.female1926=Joya
name.female1927=Joyce
name.female1928=Joycelyn
name.female1929=Joye
name.female1930=Juan
name.female1931=Juana
name.female1932=Juanita
name.female1933=Jubilee
name.female1934=Jude
name.female1935=Judi
name.female1936=Judie
name.female1937=Judith
name.female1938=Judy
name.female1939=Jule
name.female1940=Julee
name.female1941=Julene
name.female1942=Juli
name.female1943=Julia
name.female1944=Julian
name.female1945=Juliana
name.female1946=Juliane
name.female1947=Juliann
name.female1948=Julianna
name.female1949=Julianne
name.female1950=Julie
name.female1951=Julieann
name.female1952=Julienne
name.female1953=Juliet
name.female1954=Julieta
name.female1955=Julietta
name.female1956=Juliette
name.female1957=Julio
name.female1958=Julissa
name.female1959=June
name.female1960=Jung
name.female1961=Junie
name.female1962=Junita
name.female1963=Junko
name.female1964=Justa
name.female1965=Justin
name.female1966=Justina
name.female1967=Justine
name.female1968=Jutta
name.female1969=Kacey
name.female1970=Kaci
name.female1971=Kacie
name.female1972=Kacy
name.female1973=Kai
name.female1974=Kaila
name.female1975=Kaitlin
name.female1976=Kaitlyn
name.female1977=Kala
name.female1978=Kaleigh
name.female1979=Kaley
name.female1980=Kali
name.female1981=Kallie
name.female1982=Kalyn
name.female1983=Kamala
name.female1984=Kami
name.female1985=Kamilah
name.female1986=Kandace
name.female1987=Kandi
name.female1988=Kandice
name.female1989=Kandis
name.female1990=Kandra
name.female1991=Kandy
name.female1992=Kanesha
name.female1993=Kanisha
name.female1994=Kara
name.female1995=Kara-May
name.female1996=Karan
name.female1997=Kareen
name.female1998=Karen
name.female1999=Karena
name.female2000=Karey
name.female2001=Kari
name.female2002=Karie
name.female2003=Karima
name.female2004=Karin
name.female2005=Karina
name.female2006=Karine
name.female2007=Karisa
name.female2008=Karissa
name.female2009=Karl
name.female2010=Karla
name.female2011=Karleen
name.female2012=Karlene
name.female2013=Karly
name.female2014=Karlyn
name.female2015=Karma
name.female2016=Karmen
name.female2017=Karol
name.female2018=Karole
name.female2019=Karoline
name.female2020=Karolyn
name.female2021=Karon
name.female2022=Karren
name.female2023=Karri
name.female2024=Karrie
name.female2025=Karry
name.female2026=Kary
name.female2027=Karyl
name.female2028=Karyn
name.female2029=Kasandra
name.female2030=Kasey
name.female2031=Kasha
name.female2032=Kasi
name.female2033=Kasie
name.female2034=Kassandra
name.female2035=Kassie
name.female2036=Kate
name.female2037=Katelin
name.female2038=Katelyn
name.female2039=Katelynn
name.female2040=Katerine
name.female2041=Kathaleen
name.female2042=Katharina
name.female2043=Katharine
name.female2044=Katharyn
name.female2045=Kathe
name.female2046=Katheleen
name.female2047=Katherin
name.female2048=Katherina
name.female2049=Katherine
name.female2050=Kathern
name.female2051=Katheryn
name.female2052=Kathey
name.female2053=Kathi
name.female2054=Kathie
name.female2055=Kathleen
name.female2056=Kathlene
name.female2057=Kathline
name.female2058=Kathlyn
name.female2059=Kathrin
name.female2060=Kathrine
name.female2061=Kathryn
name.female2062=Kathryne
name.female2063=Kathy
name.female2064=Kathyrn
name.female2065=Kati
name.female2066=Katia
name.female2067=Katie
name.female2068=Katina
name.female2069=Katlyn
name.female2070=Katrice
name.female2071=Katrina
name.female2072=Kattie
name.female2073=Katy
name.female2074=Kay
name.female2075=Kayce
name.female2076=Kaycee
name.female2077=Kaye
name.female2078=Kayla
name.female2079=Kaylee
name.female2080=Kayleen
name.female2081=Kayleigh
name.female2082=Kaylene
name.female2083=Kazuko
name.female2084=Kecia
name.female2085=Keeley
name.female2086=Keely
name.female2087=Keena
name.female2088=Keesha
name.female2089=Keiko
name.female2090=Keila
name.female2091=Keira
name.female2092=Keisha
name.female2093=Keith
name.female2094=Keitha
name.female2095=Keli
name.female2096=Kelle
name.female2097=Kellee
name.female2098=Kelley
name.female2099=Kelli
name.female2100=Kellie
name.female2101=Kelly
name.female2102=Kellye
name.female2103=Kelsey
name.female2104=Kelsi
name.female2105=Kelsie
name.female2106=Kemberly
name.female2107=Kena
name.female2108=Kenda
name.female2109=Kendal
name.female2110=Kendall
name.female2111=Kendra
name.female2112=Kenia
name.female2113=Kenisha
name.female2114=Kenna
name.female2115=Kenneth
name.female2116=Kenya
name.female2117=Kenyatta
name.female2118=Kenyetta
name.female2119=Kera
name.female2120=Keren
name.female2121=Keri
name.female2122=Kerri
name.female2123=Kerrie
name.female2124=Kerry
name.female2125=Kerstin
name.female2126=Kesha
name.female2127=Keshia
name.female2128=Keturah
name.female2129=Keva
name.female2130=Kevin
name.female2131=Khadijah
name.female2132=Khalilah
name.female2133=Kia
name.female2134=Kiana
name.female2135=Kiara
name.female2136=Kiera
name.female2137=Kiersten
name.female2138=Kiesha
name.female2139=Kiley
name.female2140=Kim
name.female2141=Kimber
name.female2142=Kimberely
name.female2143=Kimberlee
name.female2144=Kimberley
name.female2145=Kimberli
name.female2146=Kimberlie
name.female2147=Kimberly
name.female2148=Kimbery
name.female2149=Kimbra
name.female2150=Kimi
name.female2151=Kimiko
name.female2152=Kina
name.female2153=Kindra
name.female2154=Kira
name.female2155=Kirby
name.female2156=Kirsten
name.female2157=Kirstie
name.female2158=Kirstin
name.female2159=Kisha
name.female2160=Kit
name.female2161=Kittie
name.female2162=Kitty
name.female2163=Kiyoko
name.female2164=Kizzie
name.female2165=Kizzy
name.female2166=Klara
name.female2167=Kori
name.female2168=Kortney
name.female2169=Kourtney
name.female2170=Kris
name.female2171=Krishna
name.female2172=Krissy
name.female2173=Krista
name.female2174=Kristal
name.female2175=Kristan
name.female2176=Kristeen
name.female2177=Kristel
name.female2178=Kristen
name.female2179=Kristi
name.female2180=Kristian
name.female2181=Kristie
name.female2182=Kristin
name.female2183=Kristina
name.female2184=Kristine
name.female2185=Kristle
name.female2186=Kristy
name.female2187=Kristyn
name.female2188=Krysta
name.female2189=Krystal
name.female2190=Krysten
name.female2191=Krystin
name.female2192=Krystina
name.female2193=Krystle
name.female2194=Krystyna
name.female2195=Kyla
name.female2196=Kyle
name.female2197=Kylee
name.female2198=Kylie
name.female2199=Kymberly
name.female2200=Kyoko
name.female2201=Kyong
name.female2202=Kyra
name.female2203=Kyung
name.female2204=Lacey
name.female2205=Lachelle
name.female2206=Laci
name.female2207=Lacie
name.female2208=Lacresha
name.female2209=Lacy
name.female2210=Ladawn
name.female2211=Ladonna
name.female2212=Lady
name.female2213=Lael
name.female2214=Lahoma
name.female2215=Lai
name.female2216=Laila
name.female2217=Laine
name.female2218=Lajuana
name.female2219=Lakeesha
name.female2220=Lakeisha
name.female2221=Lakendra
name.female2222=Lakenya
name.female2223=Lakesha
name.female2224=Lakeshia
name.female2225=Lakia
name.female2226=Lakiesha
name.female2227=Lakisha
name.female2228=Lakita
name.female2229=Lala
name.female2230=Lamonica
name.female2231=Lan
name.female2232=Lana
name.female2233=Lane
name.female2234=Lanell
name.female2235=Lanelle
name.female2236=Lanette
name.female2237=Lang
name.female2238=Lani
name.female2239=Lanie
name.female2240=Lanita
name.female2241=Lannie
name.female2242=Lanora
name.female2243=Laquanda
name.female2244=Laquita
name.female2245=Lara
name.female2246=Larae
name.female2247=Laraine
name.female2248=Laree
name.female2249=Larhonda
name.female2250=Larisa
name.female2251=Larissa
name.female2252=Larita
name.female2253=Laronda
name.female2254=Larraine
name.female2255=Larry
name.female2256=Larue
name.female2257=Lasandra
name.female2258=Lashanda
name.female2259=Lashandra
name.female2260=Lashaun
name.female2261=Lashaunda
name.female2262=Lashawn
name.female2263=Lashawna
name.female2264=Lashawnda
name.female2265=Lashay
name.female2266=Lashell
name.female2267=Lashon
name.female2268=Lashonda
name.female2269=Lashunda
name.female2270=Lasonya
name.female2271=Latanya
name.female2272=Latarsha
name.female2273=Latasha
name.female2274=Latashia
name.female2275=Latesha
name.female2276=Latia
name.female2277=Laticia
name.female2278=Latina
name.female2279=Latisha
name.female2280=Latonia
name.female2281=Latonya
name.female2282=Latoria
name.female2283=Latosha
name.female2284=Latoya
name.female2285=Latoyia
name.female2286=Latrice
name.female2287=Latricia
name.female2288=Latrina
name.female2289=Latrisha
name.female2290=Launa
name.female2291=Laura
name.female2292=Lauralee
name.female2293=Lauran
name.female2294=Laure
name.female2295=Laureen
name.female2296=Laurel
name.female2297=Lauren
name.female2298=Laurena
name.female2299=Laurence
name.female2300=Laurene
name.female2301=Lauretta
name.female2302=Laurette
name.female2303=Lauri
name.female2304=Laurice
name.female2305=Laurie
name.female2306=Laurinda
name.female2307=Laurine
name.female2308=Lauryn
name.female2309=Lavada
name.female2310=Lavelle
name.female2311=Lavenia
name.female2312=Lavera
name.female2313=Lavern
name.female2314=Laverna
name.female2315=Laverne
name.female2316=Laveta
name.female2317=Lavette
name.female2318=Lavina
name.female2319=Lavinia
name.female2320=Lavon
name.female2321=Lavona
name.female2322=Lavonda
name.female2323=Lavone
name.female2324=Lavonia
name.female2325=Lavonna
name.female2326=Lavonne
name.female2327=Lawana
name.female2328=Lawanda
name.female2329=Lawanna
name.female2330=Lawrence
name.female2331=Layla
name.female2332=Layne
name.female2333=Lea
name.female2334=Leah
name.female2335=Lean
name.female2336=Leana
name.female2337=Leandra
name.female2338=Leann
name.female2339=Leanna
name.female2340=Leanne
name.female2341=Leanora
name.female2342=Leatha
name.female2343=Leatrice
name.female2344=Lecia
name.female2345=Leda
name.female2346=Lee
name.female2347=Leeann
name.female2348=Leeanna
name.female2349=Leeanne
name.female2350=Leena
name.female2351=Leesa
name.female2352=Leia
name.female2353=Leida
name.female2354=Leigh
name.female2355=Leigha
name.female2356=Leighann
name.female2357=Leila
name.female2358=Leilani
name.female2359=Leisa
name.female2360=Leisha
name.female2361=Lekisha
name.female2362=Lela
name.female2363=Lelah
name.female2364=Lelia
name.female2365=Lena
name.female2366=Lenita
name.female2367=Lenna
name.female2368=Lennie
name.female2369=Lenora
name.female2370=Lenore
name.female2371=Leola
name.female2372=Leoma
name.female2373=Leon
name.female2374=Leona
name.female2375=Leonarda
name.female2376=Leone
name.female2377=Leonia
name.female2378=Leonida
name.female2379=Leonie
name.female2380=Leonila
name.female2381=Leonor
name.female2382=Leonora
name.female2383=Leonore
name.female2384=Leontine
name.female2385=Leora
name.female2386=Leota
name.female2387=Lera
name.female2388=Lesa
name.female2389=Lesha
name.female2390=Lesia
name.female2391=Leslee
name.female2392=Lesley
name.female2393=Lesli
name.female2394=Leslie
name.female2395=Leslie-Annie
name.female2396=Lessie
name.female2397=Lester
name.female2398=Leta
name.female2399=Letha
name.female2400=Leticia
name.female2401=Letisha
name.female2402=Letitia
name.female2403=Lettie
name.female2404=Letty
name.female2405=Lewis
name.female2406=Lexie
name.female2407=Lezlie
name.female2408=Lia
name.female2409=Liana
name.female2410=Liane
name.female2411=Lianne
name.female2412=Libbie
name.female2413=Libby
name.female2414=Liberty
name.female2415=Librada
name.female2416=Lida
name.female2417=Lidia
name.female2418=Lidya
name.female2419=Lien
name.female2420=Lieselotte
name.female2421=Ligia
name.female2422=Lila
name.female2423=Lili
name.female2424=Lilia
name.female2425=Lilian
name.female2426=Liliana
name.female2427=Lilith
name.female2428=Lilla
name.female2429=Lilli
name.female2430=Lillia
name.female2431=Lilliam
name.female2432=Lillian
name.female2433=Lilliana
name.female2434=Lillie
name.female2435=Lilly
name.female2436=Lily
name.female2437=Lin
name.female2438=Lina
name.female2439=Linda
name.female2440=Lindsay
name.female2441=Lindsey
name.female2442=Lindsy
name.female2443=Lindy
name.female2444=Linette
name.female2445=Ling
name.female2446=Linh
name.female2447=Linn
name.female2448=Linnea
name.female2449=Linnie
name.female2450=Linsey
name.female2451=Lisa
name.female2452=Lisabeth
name.female2453=Lisandra
name.female2454=Lisbeth
name.female2455=Lise
name.female2456=Lisette
name.female2457=Lisha
name.female2458=Lissa
name.female2459=Lissette
name.female2460=Lita
name.female2461=Livia
name.female2462=Liz
name.female2463=Liza
name.female2464=Lizabeth
name.female2465=Lizbeth
name.female2466=Lizeth
name.female2467=Lizette
name.female2468=Lizzette
name.female2469=Lizzie
name.female2470=Lizzy
name.female2471=Loan
name.female2472=Logan
name.female2473=Loida
name.female2474=Lois
name.female2475=Loise
name.female2476=Lola
name.female2477=Lolita
name.female2478=Loma
name.female2479=Lona
name.female2480=Londa
name.female2481=London
name.female2482=Loni
name.female2483=Lonna
name.female2484=Lonnie
name.female2485=Lora
name.female2486=Loraine
name.female2487=Loralee
name.female2488=Lore
name.female2489=Lorean
name.female2490=Loree
name.female2491=Loreen
name.female2492=Lorelei
name.female2493=Loren
name.female2494=Lorena
name.female2495=Lorene
name.female2496=Lorenza
name.female2497=Loreta
name.female2498=Loretta
name.female2499=Lorette
name.female2500=Lori
name.female2501=Loria
name.female2502=Loriann
name.female2503=Lorie
name.female2504=Lorilee
name.female2505=Lorina
name.female2506=Lorinda
name.female2507=Lorine
name.female2508=Loris
name.female2509=Lorita
name.female2510=Lorna
name.female2511=Lorraine
name.female2512=Lorretta
name.female2513=Lorri
name.female2514=Lorriane
name.female2515=Lorrie
name.female2516=Lorrine
name.female2517=Lory
name.female2518=Lottie
name.female2519=Lotus
name.female2520=Louann
name.female2521=Louanne
name.female2522=Louella
name.female2523=Louetta
name.female2524=Louie
name.female2525=Louis
name.female2526=Louisa
name.female2527=Louise
name.female2528=Loura
name.female2529=Lourdes
name.female2530=Lourie
name.female2531=Louvenia
name.female2532=Love
name.female2533=Lovella
name.female2534=Lovetta
name.female2535=Lovie
name.female2536=Loyce
name.female2537=Luana
name.female2538=Luann
name.female2539=Luanna
name.female2540=Luanne
name.female2541=Luba
name.female2542=Luci
name.female2543=Lucia
name.female2544=Luciana
name.female2545=Lucie
name.female2546=Lucienne
name.female2547=Lucila
name.female2548=Lucile
name.female2549=Lucilla
name.female2550=Lucille
name.female2551=Lucina
name.female2552=Lucinda
name.female2553=Lucine
name.female2554=Lucrecia
name.female2555=Lucretia
name.female2556=Lucy
name.female2557=Ludie
name.female2558=Ludivina
name.female2559=Lue
name.female2560=Luella
name.female2561=Luetta
name.female2562=Luis
name.female2563=Luisa
name.female2564=Luise
name.female2565=Lula
name.female2566=Lulu
name.female2567=Luna
name.female2568=Lupe
name.female2569=Lupita
name.female2570=Lura
name.female2571=Lurlene
name.female2572=Lurline
name.female2573=Luvenia
name.female2574=Lyda
name.female2575=Lydia
name.female2576=Lyla
name.female2577=Lyn
name.female2578=Lynda
name.female2579=Lyndia
name.female2580=Lyndsay
name.female2581=Lyndsey
name.female2582=Lynell
name.female2583=Lynelle
name.female2584=Lynetta
name.female2585=Lynette
name.female2586=Lynn
name.female2587=Lynna
name.female2588=Lynne
name.female2589=Lynnette
name.female2590=Lynsey
name.female2591=Lyric
name.female2592=Mabel
name.female2593=Mabelle
name.female2594=Mable
name.female2595=Macey
name.female2596=Machelle
name.female2597=Maci
name.female2598=Macie
name.female2599=Mackenzie
name.female2600=Macy
name.female2601=Madalene
name.female2602=Madaline
name.female2603=Madalyn
name.female2604=Maddie
name.female2605=Madelaine
name.female2606=Madeleine
name.female2607=Madelene
name.female2608=Madeline
name.female2609=Madelyn
name.female2610=Madge
name.female2611=Madie
name.female2612=Madison
name.female2613=Madlyn
name.female2614=Madonna
name.female2615=Mae
name.female2616=Maegan
name.female2617=Mafalda
name.female2618=Magali
name.female2619=Magaly
name.female2620=Magan
name.female2621=Magaret
name.female2622=Magda
name.female2623=Magdalen
name.female2624=Magdalena
name.female2625=Magdalene
name.female2626=Magen
name.female2627=Maggie
name.female2628=Magnolia
name.female2629=Mahalia
name.female2630=Mai
name.female2631=Maia
name.female2632=Maida
name.female2633=Maile
name.female2634=Maira
name.female2635=Maire
name.female2636=Maisha
name.female2637=Maisie
name.female2638=Majorie
name.female2639=Makeda
name.female2640=Malana
name.female2641=Malena
name.female2642=Malia
name.female2643=Malika
name.female2644=Malinda
name.female2645=Malisa
name.female2646=Malissa
name.female2647=Malka
name.female2648=Mallie
name.female2649=Mallory
name.female2650=Malorie
name.female2651=Malvina
name.female2652=Mamie
name.female2653=Mammie
name.female2654=Mana
name.female2655=Manda
name.female2656=Mandi
name.female2657=Mandie
name.female2658=Mandy
name.female2659=Manie
name.female2660=Manuela
name.female2661=Many
name.female2662=Mao
name.female2663=Maple
name.female2664=Mara
name.female2665=Maragaret
name.female2666=Maragret
name.female2667=Maranda
name.female2668=Marcela
name.female2669=Marcelene
name.female2670=Marcelina
name.female2671=Marceline
name.female2672=Marcell
name.female2673=Marcella
name.female2674=Marcelle
name.female2675=Marcene
name.female2676=Marchelle
name.female2677=Marci
name.female2678=Marcia
name.female2679=Marcie
name.female2680=Marcy
name.female2681=Mardell
name.female2682=Maren
name.female2683=Marg
name.female2684=Margaret
name.female2685=Margareta
name.female2686=Margarete
name.female2687=Margarett
name.female2688=Margaretta
name.female2689=Margarette
name.female2690=Margarita
name.female2691=Margarite
name.female2692=Margart
name.female2693=Marge
name.female2694=Margene
name.female2695=Margeret
name.female2696=Margert
name.female2697=Margery
name.female2698=Marget
name.female2699=Margherita
name.female2700=Margie
name.female2701=Margit
name.female2702=Margo
name.female2703=Margorie
name.female2704=Margot
name.female2705=Margret
name.female2706=Margrett
name.female2707=Marguerita
name.female2708=Marguerite
name.female2709=Margurite
name.female2710=Margy
name.female2711=Marhta
name.female2712=Mari
name.female2713=Maria
name.female2714=Mariah
name.female2715=Mariam
name.female2716=Marian
name.female2717=Mariana
name.female2718=Marianela
name.female2719=Mariann
name.female2720=Marianna
name.female2721=Marianne
name.female2722=Maribel
name.female2723=Maribeth
name.female2724=Marica
name.female2725=Maricela
name.female2726=Maricruz
name.female2727=Marie
name.female2728=Mariel
name.female2729=Mariela
name.female2730=Mariella
name.female2731=Marielle
name.female2732=Marietta
name.female2733=Mariette
name.female2734=Mariko
name.female2735=Marilee
name.female2736=Marilou
name.female2737=Marilu
name.female2738=Marilyn
name.female2739=Marilynn
name.female2740=Marin
name.female2741=Marina
name.female2742=Marinda
name.female2743=Marine
name.female2744=Mario
name.female2745=Marion
name.female2746=Marioth
name.female2747=Maris
name.female2748=Marisa
name.female2749=Marisela
name.female2750=Marisha
name.female2751=Marisol
name.female2752=Marissa
name.female2753=Marita
name.female2754=Maritza
name.female2755=Marivel
name.female2756=Marjorie
name.female2757=Marjory
name.female2758=Mark
name.female2759=Marketta
name.female2760=Markita
name.female2761=Marla
name.female2762=Marlana
name.female2763=Marleen
name.female2764=Marlen
name.female2765=Marlena
name.female2766=Marlene
name.female2767=Marlin
name.female2768=Marline
name.female2769=Marlo
name.female2770=Marlyn
name.female2771=Marlys
name.female2772=Marna
name.female2773=Marni
name.female2774=Marnie
name.female2775=Marquerite
name.female2776=Marquetta
name.female2777=Marquita
name.female2778=Marquitta
name.female2779=Marry
name.female2780=Marsha
name.female2781=Marshall
name.female2782=Marta
name.female2783=Marth
name.female2784=Martha
name.female2785=Marti
name.female2786=Martin
name.female2787=Martina
name.female2788=Martine
name.female2789=Marty
name.female2790=Marva
name.female2791=Marvel
name.female2792=Marvella
name.female2793=Marvis
name.female2794=Marx
name.female2795=Mary
name.female2796=Mary-Anne
name.female2797=Marya
name.female2798=Maryalice
name.female2799=Maryam
name.female2800=Maryann
name.female2801=Maryanna
name.female2802=Maryanne
name.female2803=Marybelle
name.female2804=Marybeth
name.female2805=Maryellen
name.female2806=Maryetta
name.female2807=Maryjane
name.female2808=Maryjo
name.female2809=Maryland
name.female2810=Marylee
name.female2811=Marylin
name.female2812=Maryln
name.female2813=Marylou
name.female2814=Marylouise
name.female2815=Marylyn
name.female2816=Marylynn
name.female2817=Maryrose
name.female2818=Masako
name.female2819=Matha
name.female2820=Mathilda
name.female2821=Mathilde
name.female2822=Matilda
name.female2823=Matilde
name.female2824=Matthew
name.female2825=Mattie
name.female2826=Maud
name.female2827=Maude
name.female2828=Maudie
name.female2829=Maura
name.female2830=Maureen
name.female2831=Maurice
name.female2832=Maurine
name.female2833=Maurita
name.female2834=Mavis
name.female2835=Maxie
name.female2836=Maxima
name.female2837=Maximina
name.female2838=Maxine
name.female2839=May
name.female2840=Maya
name.female2841=Maybell
name.female2842=Maybelle
name.female2843=Mayberry
name.female2844=Maye
name.female2845=Mayflower
name.female2846=Mayme
name.female2847=Mayola
name.female2848=Mayra
name.female2849=Mazie
name.female2850=Mckenzie
name.female2851=Meagan
name.female2852=Meaghan
name.female2853=Mechelle
name.female2854=Meda
name.female2855=Meg
name.female2856=Megan
name.female2857=Meggan
name.female2858=Meghan
name.female2859=Meghann
name.female2860=Mei
name.female2861=Melaine
name.female2862=Melani
name.female2863=Melania
name.female2864=Melanie
name.female2865=Melany
name.female2866=Melba
name.female2867=Melda
name.female2868=Melia
name.female2869=Melida
name.female2870=Melina
name.female2871=Melinda
name.female2872=Melisa
name.female2873=Melissa
name.female2874=Melissia
name.female2875=Melita
name.female2876=Mellie
name.female2877=Mellisa
name.female2878=Mellissa
name.female2879=Melodee
name.female2880=Melodi
name.female2881=Melodie
name.female2882=Melody
name.female2883=Melonie
name.female2884=Melony
name.female2885=Melva
name.female2886=Melvin
name.female2887=Melvina
name.female2888=Melynda
name.female2889=Mendy
name.female2890=Mercedes
name.female2891=Mercedez
name.female2892=Mercy
name.female2893=Meredith
name.female2894=Meri
name.female2895=Merideth
name.female2896=Meridith
name.female2897=Merilyn
name.female2898=Merissa
name.female2899=Merle
name.female2900=Merlene
name.female2901=Merlyn
name.female2902=Merna
name.female2903=Merri
name.female2904=Merrie
name.female2905=Merrilee
name.female2906=Merrill
name.female2907=Merry
name.female2908=Mertie
name.female2909=Meryl
name.female2910=Meta
name.female2911=Mia
name.female2912=Mica
name.female2913=Micaela
name.female2914=Micah
name.female2915=Micha
name.female2916=Michael
name.female2917=Michaela
name.female2918=Michaele
name.female2919=Michal
name.female2920=Micheal
name.female2921=Michel
name.female2922=Michele
name.female2923=Michelina
name.female2924=Micheline
name.female2925=Michell
name.female2926=Michelle
name.female2927=Michiko
name.female2928=Mickey
name.female2929=Micki
name.female2930=Mickie
name.female2931=Miesha
name.female2932=Migdalia
name.female2933=Mignon
name.female2934=Miguelina
name.female2935=Mika
name.female2936=Mikaela
name.female2937=Mike
name.female2938=Miki
name.female2939=Mikki
name.female2940=Mila
name.female2941=Milagro
name.female2942=Milagros
name.female2943=Milda
name.female2944=Mildred
name.female2945=Milissa
name.female2946=Millicent
name.female2947=Millie
name.female2948=Milly
name.female2949=Mimi
name.female2950=Min
name.female2951=Mina
name.female2952=Minda
name.female2953=Mindi
name.female2954=Mindy
name.female2955=Minerva
name.female2956=Ming
name.female2957=Minh
name.female2958=Minna
name.female2959=Minnie
name.female2960=Minta
name.female2961=Mira
name.female2962=Miranda
name.female2963=Mireille
name.female2964=Mirella
name.female2965=Mireya
name.female2966=Miriam
name.female2967=Mirian
name.female2968=Mirna
name.female2969=Mirta
name.female2970=Mirtha
name.female2971=Misha
name.female2972=Miss
name.female2973=Missy
name.female2974=Misti
name.female2975=Mistie
name.female2976=Misty
name.female2977=Mitchell
name.female2978=Mitsue
name.female2979=Mitsuko
name.female2980=Mittie
name.female2981=Mitzi
name.female2982=Mitzie
name.female2983=Miyoko
name.female2984=Modesta
name.female2985=Moira
name.female2986=Mollie
name.female2987=Molly
name.female2988=Mona
name.female2989=Monet
name.female2990=Monica
name.female2991=Monika
name.female2992=Monique
name.female2993=Monnie
name.female2994=Monserrate
name.female2995=Moon
name.female2996=Mora
name.female2997=Morgan
name.female2998=Morgana
name.female2999=Moriah
name.female3000=Mozell
name.female3001=Mozella
name.female3002=Mozelle
name.female3003=Mui
name.female3004=Muoi
name.female3005=Muriel
name.female3006=Mya
name.female3007=Myesha
name.female3008=Myong
name.female3009=Myra
name.female3010=Myriam
name.female3011=Myrl
name.female3012=Myrle
name.female3013=Myrna
name.female3014=Myrta
name.female3015=Myrtice
name.female3016=Myrtie
name.female3017=Myrtis
name.female3018=Myrtle
name.female3019=Myung
name.female3020=Nada
name.female3021=Nadene
name.female3022=Nadia
name.female3023=Nadine
name.female3024=Naida
name.female3025=Nakesha
name.female3026=Nakia
name.female3027=Nakisha
name.female3028=Nakita
name.female3029=Nam
name.female3030=Nan
name.female3031=Nana
name.female3032=Nancee
name.female3033=Nancey
name.female3034=Nanci
name.female3035=Nancie
name.female3036=Nancy
name.female3037=Nanette
name.female3038=Nani
name.female3039=Nannette
name.female3040=Nannie
name.female3041=Naoma
name.female3042=Naomi
name.female3043=Narcisa
name.female3044=Natacha
name.female3045=Natalia
name.female3046=Natalie
name.female3047=Natalya
name.female3048=Natasha
name.female3049=Natashia
name.female3050=Nathalie
name.female3051=Natisha
name.female3052=Natividad
name.female3053=Natosha
name.female3054=Necole
name.female3055=Neda
name.female3056=Nedra
name.female3057=Neely
name.female3058=Neida
name.female3059=Nelda
name.female3060=Nelia
name.female3061=Nelida
name.female3062=Nell
name.female3063=Nella
name.female3064=Nelle
name.female3065=Nellie
name.female3066=Nelly
name.female3067=Nena
name.female3068=Nenita
name.female3069=Neoma
name.female3070=Neomi
name.female3071=Nereida
name.female3072=Nerissa
name.female3073=Nery
name.female3074=Neta
name.female3075=Nettie
name.female3076=Neva
name.female3077=Nevada
name.female3078=Ngan
name.female3079=Ngoc
name.female3080=Nguyet
name.female3081=Nia
name.female3082=Nichelle
name.female3083=Nichol
name.female3084=Nichole
name.female3085=Nicholle
name.female3086=Nicki
name.female3087=Nickie
name.female3088=Nickole
name.female3089=Nicky
name.female3090=Nicol
name.female3091=Nicola
name.female3092=Nicolasa
name.female3093=Nicole
name.female3094=Nicolette
name.female3095=Nicolle
name.female3096=Nida
name.female3097=Nidia
name.female3098=Niesha
name.female3099=Nieves
name.female3100=Niki
name.female3101=Nikia
name.female3102=Nikita
name.female3103=Nikki
name.female3104=Nikole
name.female3105=Nila
name.female3106=Nilda
name.female3107=Nilsa
name.female3108=Nina
name.female3109=Ninfa
name.female3110=Nisha
name.female3111=Nita
name.female3112=Nobuko
name.female3113=Noel
name.female3114=Noelia
name.female3115=Noella
name.female3116=Noelle
name.female3117=Noemi
name.female3118=Nohemi
name.female3119=Nola
name.female3120=Noma
name.female3121=Nona
name.female3122=Nora
name.female3123=Norah
name.female3124=Noreen
name.female3125=Norene
name.female3126=Noriko
name.female3127=Norine
name.female3128=Norma
name.female3129=Norman
name.female3130=Nova
name.female3131=Novella
name.female3132=Nubia
name.female3133=Numbers
name.female3134=Nydia
name.female3135=Nyla
name.female3136=Obdulia
name.female3137=Ocie
name.female3138=Octavia
name.female3139=Oda
name.female3140=Odelia
name.female3141=Odell
name.female3142=Odessa
name.female3143=Odette
name.female3144=Odilia
name.female3145=Ofelia
name.female3146=Ola
name.female3147=Olene
name.female3148=Oleta
name.female3149=Olevia
name.female3150=Olga
name.female3151=Olimpia
name.female3152=Olinda
name.female3153=Oliva
name.female3154=Olive
name.female3155=Olivia
name.female3156=Ollie
name.female3157=Olympia
name.female3158=Oma
name.female3159=Omega
name.female3160=Ona
name.female3161=Oneida
name.female3162=Onie
name.female3163=Onita
name.female3164=Opal
name.female3165=Ophelia
name.female3166=Ora
name.female3167=Oralee
name.female3168=Oralia
name.female3169=Oretha
name.female3170=Orpha
name.female3171=Oscar
name.female3172=Ossie
name.female3173=Otelia
name.female3174=Otha
name.female3175=Otilia
name.female3176=Ouida
name.female3177=Ozell
name.female3178=Ozella
name.female3179=Ozie
name.female3180=Page
name.female3181=Paige
name.female3182=Palma
name.female3183=Palmira
name.female3184=Pam
name.female3185=Pamala
name.female3186=Pamela
name.female3187=Pamela-May
name.female3188=Pamelia
name.female3189=Pamella
name.female3190=Pamila
name.female3191=Pamula
name.female3192=Pandora
name.female3193=Pansy
name.female3194=Paola
name.female3195=Paris
name.female3196=Parthenia
name.female3197=Particia
name.female3198=Pasty
name.female3199=Pat
name.female3200=Patience
name.female3201=Patria
name.female3202=Patrica
name.female3203=Patrice
name.female3204=Patricia
name.female3205=Patrick
name.female3206=Patrina
name.female3207=Patsy
name.female3208=Patti
name.female3209=Pattie
name.female3210=Patty
name.female3211=Paul
name.female3212=Paula
name.female3213=Paulene
name.female3214=Pauletta
name.female3215=Paulette
name.female3216=Paulina
name.female3217=Pauline
name.female3218=Paulita
name.female3219=Paysley
name.female3220=Paz
name.female3221=Pearl
name.female3222=Pearle
name.female3223=Pearlene
name.female3224=Pearlie
name.female3225=Pearline
name.female3226=Pearly
name.female3227=Peg
name.female3228=Peggie
name.female3229=Peggy
name.female3230=Pei
name.female3231=Penelope
name.female3232=Penney
name.female3233=Penni
name.female3234=Pennie
name.female3235=Penny
name.female3236=Peony
name.female3237=Perla
name.female3238=Perry
name.female3239=Petal
name.female3240=Peter
name.female3241=Petra
name.female3242=Petrina
name.female3243=Petronila
name.female3244=Petunia
name.female3245=Phebe
name.female3246=Phillis
name.female3247=Philomena
name.female3248=Phoebe
name.female3249=Phung
name.female3250=Phuong
name.female3251=Phylicia
name.female3252=Phylis
name.female3253=Phyliss
name.female3254=Phyllis
name.female3255=Pia
name.female3256=Piedad
name.female3257=Pilar
name.female3258=Ping
name.female3259=Pinkie
name.female3260=Piper
name.female3261=Pok
name.female3262=Polly
name.female3263=Poppy
name.female3264=Porsche
name.female3265=Porsha
name.female3266=Portia
name.female3267=Precious
name.female3268=Presley
name.female3269=Pricilla
name.female3270=Princess
name.female3271=Priscila
name.female3272=Priscilla
name.female3273=Providencia
name.female3274=Prudence
name.female3275=Pura
name.female3276=Qiana
name.female3277=Queen
name.female3278=Queenie
name.female3279=Quiana
name.female3280=Quinn
name.female3281=Quyen
name.female3282=Rachael
name.female3283=Rachal
name.female3284=Racheal
name.female3285=Rachel
name.female3286=Rachele
name.female3287=Rachell
name.female3288=Rachelle
name.female3289=Racquel
name.female3290=Rae
name.female3291=Raeann
name.female3292=Raelene
name.female3293=Rafaela
name.female3294=Raguel
name.female3295=Raina
name.female3296=Raisa
name.female3297=Ramona
name.female3298=Ramonita
name.female3299=Rana
name.female3300=Ranae
name.female3301=Randa
name.female3302=Randee
name.female3303=Randi
name.female3304=Randy
name.female3305=Ranee
name.female3306=Raquel
name.female3307=Rasheeda
name.female3308=Rashida
name.female3309=Raven
name.female3310=Ray
name.female3311=Ray-Annie
name.female3312=Raye
name.female3313=Raylene
name.female3314=Raymond
name.female3315=Raymonde
name.female3316=Rayna
name.female3317=Rayne
name.female3318=Reagan
name.female3319=Reanna
name.female3320=Reatha
name.female3321=Reba
name.female3322=Rebbeca
name.female3323=Rebbecca
name.female3324=Rebeca
name.female3325=Rebecca
name.female3326=Rebecka
name.female3327=Rebekah
name.female3328=Reda
name.female3329=Reena
name.female3330=Refugia
name.female3331=Refugio
name.female3332=Regan
name.female3333=Regena
name.female3334=Regenia
name.female3335=Regina
name.female3336=Regine
name.female3337=Reginia
name.female3338=Reiko
name.female3339=Reina
name.female3340=Reita
name.female3341=Rema
name.female3342=Remedios
name.female3343=Remona
name.female3344=Rena
name.female3345=Renae
name.female3346=Renata
name.female3347=Renate
name.female3348=Renay
name.female3349=Renda
name.female3350=Rene
name.female3351=Renea
name.female3352=Renee
name.female3353=Renetta
name.female3354=Renita
name.female3355=Renna
name.female3356=Ressie
name.female3357=Reta
name.female3358=Retha
name.female3359=Retta
name.female3360=Reva
name.female3361=Reyna
name.female3362=Reynalda
name.female3363=Rhea
name.female3364=Rheba
name.female3365=Rhiannon
name.female3366=Rhoda
name.female3367=Rhona
name.female3368=Rhonda
name.female3369=Ria
name.female3370=Ricarda
name.female3371=Richard
name.female3372=Richelle
name.female3373=Ricki
name.female3374=Rickie
name.female3375=Rikki
name.female3376=Rima
name.female3377=Rina
name.female3378=Risa
name.female3379=Rita
name.female3380=Riva
name.female3381=Rivka
name.female3382=Robbi
name.female3383=Robbie
name.female3384=Robbin
name.female3385=Robbyn
name.female3386=Robena
name.female3387=Robert
name.female3388=Roberta
name.female3389=Roberto
name.female3390=Robin
name.female3391=Robyn
name.female3392=Rochel
name.female3393=Rochell
name.female3394=Rochelle
name.female3395=Rocio
name.female3396=Rolanda
name.female3397=Rolande
name.female3398=Roma
name.female3399=Romaine
name.female3400=Romana
name.female3401=Romelia
name.female3402=Romona
name.female3403=Rona
name.female3404=Ronald
name.female3405=Ronda
name.female3406=Roni
name.female3407=Ronna
name.female3408=Ronni
name.female3409=Ronnie
name.female3410=Rory
name.female3411=Rosa
name.female3412=Rosalba
name.female3413=Rosalee
name.female3414=Rosalia
name.female3415=Rosalie
name.female3416=Rosalina
name.female3417=Rosalind
name.female3418=Rosalinda
name.female3419=Rosaline
name.female3420=Rosalva
name.female3421=Rosalyn
name.female3422=Rosamaria
name.female3423=Rosamond
name.female3424=Rosana
name.female3425=Rosann
name.female3426=Rosanna
name.female3427=Rosanne
name.female3428=Rosaria
name.female3429=Rosario
name.female3430=Rosaura
name.female3431=Rose
name.female3432=Roseann
name.female3433=Roseanna
name.female3434=Roseanne
name.female3435=Roselee
name.female3436=Roselia
name.female3437=Roseline
name.female3438=Rosella
name.female3439=Roselle
name.female3440=Roselyn
name.female3441=Rosemarie
name.female3442=Rosemary
name.female3443=Rosena
name.female3444=Rosenda
name.female3445=Rosetta
name.female3446=Rosette
name.female3447=Rosia
name.female3448=Rosie
name.female3449=Rosina
name.female3450=Rosio
name.female3451=Rosita
name.female3452=Roslyn
name.female3453=Rossana
name.female3454=Rossie
name.female3455=Rosy
name.female3456=Rowena
name.female3457=Roxana
name.female3458=Roxane
name.female3459=Roxann
name.female3460=Roxanna
name.female3461=Roxanne
name.female3462=Roxie
name.female3463=Roxy
name.female3464=Roy
name.female3465=Royce
name.female3466=Rozanne
name.female3467=Rozella
name.female3468=Rubi
name.female3469=Rubie
name.female3470=Ruby
name.female3471=Rubye
name.female3472=Rudy
name.female3473=Rufina
name.female3474=Russell
name.female3475=Ruth
name.female3476=Rutha
name.female3477=Ruthann
name.female3478=Ruthanne
name.female3479=Ruthe
name.female3480=Ruthie
name.female3481=Ryan
name.female3482=Ryann
name.female3483=Sabina
name.female3484=Sabine
name.female3485=Sabra
name.female3486=Sabrina
name.female3487=Sacha
name.female3488=Sachiko
name.female3489=Sade
name.female3490=Sadie
name.female3491=Sadye
name.female3492=Saffron
name.female3493=Sage
name.female3494=Salena
name.female3495=Salina
name.female3496=Salley
name.female3497=Sallie
name.female3498=Sally
name.female3499=Salome
name.female3500=Sam
name.female3501=Samantha
name.female3502=Samara
name.female3503=Samatha
name.female3504=Samella
name.female3505=Samira
name.female3506=Sammie
name.female3507=Sammy
name.female3508=Samuel
name.female3509=Sana
name.female3510=Sanda
name.female3511=Sandee
name.female3512=Sandi
name.female3513=Sandie
name.female3514=Sandra
name.female3515=Sandy
name.female3516=Sang
name.female3517=Sanjuana
name.female3518=Sanjuanita
name.female3519=Sanora
name.female3520=Santa
name.female3521=Santana
name.female3522=Santina
name.female3523=Santos
name.female3524=Sapphire
name.female3525=Sara
name.female3526=Sarah
name.female3527=Sarai
name.female3528=Saran
name.female3529=Sari
name.female3530=Sarina
name.female3531=Sarita
name.female3532=Sasha
name.female3533=Saturnina
name.female3534=Sau
name.female3535=Saundra
name.female3536=Savanna
name.female3537=Savannah
name.female3538=Scarlet
name.female3539=Scarlett
name.female3540=Scott
name.female3541=Scottie
name.female3542=Sean
name.female3543=Season
name.female3544=Sebrina
name.female3545=Seema
name.female3546=Selena
name.female3547=Selene
name.female3548=Selina
name.female3549=Selma
name.female3550=Sena
name.female3551=Senaida
name.female3552=September
name.female3553=Serafina
name.female3554=Serena
name.female3555=Serina
name.female3556=Serita
name.female3557=Setsuko
name.female3558=Sha
name.female3559=Shae
name.female3560=Shaina
name.female3561=Shakia
name.female3562=Shakira
name.female3563=Shakita
name.female3564=Shala
name.female3565=Shalanda
name.female3566=Shalon
name.female3567=Shalonda
name.female3568=Shameka
name.female3569=Shamika
name.female3570=Shan
name.female3571=Shana
name.female3572=Shanae
name.female3573=Shanda
name.female3574=Shandi
name.female3575=Shandra
name.female3576=Shane
name.female3577=Shaneka
name.female3578=Shanel
name.female3579=Shanell
name.female3580=Shanelle
name.female3581=Shani
name.female3582=Shanice
name.female3583=Shanika
name.female3584=Shaniqua
name.female3585=Shanita
name.female3586=Shanna
name.female3587=Shannan
name.female3588=Shannon
name.female3589=Shanon
name.female3590=Shanta
name.female3591=Shantae
name.female3592=Shantay
name.female3593=Shante
name.female3594=Shantel
name.female3595=Shantell
name.female3596=Shantelle
name.female3597=Shanti
name.female3598=Shaquana
name.female3599=Shaquita
name.female3600=Shara
name.female3601=Sharan
name.female3602=Sharda
name.female3603=Sharee
name.female3604=Sharell
name.female3605=Sharen
name.female3606=Shari
name.female3607=Sharice
name.female3608=Sharie
name.female3609=Sharika
name.female3610=Sharilyn
name.female3611=Sharita
name.female3612=Sharla
name.female3613=Sharleen
name.female3614=Sharlene
name.female3615=Sharmaine
name.female3616=Sharolyn
name.female3617=Sharon
name.female3618=Sharonda
name.female3619=Sharri
name.female3620=Sharron
name.female3621=Sharyl
name.female3622=Sharyn
name.female3623=Shasta
name.female3624=Shaun
name.female3625=Shauna
name.female3626=Shaunda
name.female3627=Shaunna
name.female3628=Shaunta
name.female3629=Shaunte
name.female3630=Shavon
name.female3631=Shavonda
name.female3632=Shavonne
name.female3633=Shawana
name.female3634=Shawanda
name.female3635=Shawanna
name.female3636=Shawn
name.female3637=Shawna
name.female3638=Shawnda
name.female3639=Shawnee
name.female3640=Shawnna
name.female3641=Shawnta
name.female3642=Shawny
name.female3643=Shay
name.female3644=Shayla
name.female3645=Shayna
name.female3646=Shayne
name.female3647=Shea
name.female3648=Sheba
name.female3649=Sheena
name.female3650=Sheila
name.female3651=Sheilah
name.female3652=Shela
name.female3653=Shelba
name.female3654=Shelby
name.female3655=Shelia
name.female3656=Shella
name.female3657=Shelley
name.female3658=Shelli
name.female3659=Shellie
name.female3660=Shelly
name.female3661=Shemeka
name.female3662=Shemika
name.female3663=Shena
name.female3664=Shenika
name.female3665=Shenita
name.female3666=Shenna
name.female3667=Shera
name.female3668=Sheree
name.female3669=Sherell
name.female3670=Sheri
name.female3671=Sherice
name.female3672=Sheridan
name.female3673=Sherie
name.female3674=Sherika
name.female3675=Sherill
name.female3676=Sherilyn
name.female3677=Sherise
name.female3678=Sherita
name.female3679=Sherlene
name.female3680=Sherley
name.female3681=Sherly
name.female3682=Sherlyn
name.female3683=Sheron
name.female3684=Sherrell
name.female3685=Sherri
name.female3686=Sherrie
name.female3687=Sherril
name.female3688=Sherrill
name.female3689=Sherron
name.female3690=Sherry
name.female3691=Sherryl
name.female3692=Shery
name.female3693=Sheryl
name.female3694=Sheryll
name.female3695=Shiela
name.female3696=Shila
name.female3697=Shiloh
name.female3698=Shin
name.female3699=Shira
name.female3700=Shirely
name.female3701=Shirl
name.female3702=Shirlee
name.female3703=Shirleen
name.female3704=Shirlene
name.female3705=Shirley
name.female3706=Shirly
name.female3707=Shizue
name.female3708=Shizuko
name.female3709=Shona
name.female3710=Shonda
name.female3711=Shondra
name.female3712=Shonna
name.female3713=Shonta
name.female3714=Shoshana
name.female3715=Shu
name.female3716=Shyla
name.female3717=Sibyl
name.female3718=Sidney
name.female3719=Sierra
name.female3720=Signe
name.female3721=Sigrid
name.female3722=Silva
name.female3723=Silvana
name.female3724=Silvia
name.female3725=Sima
name.female3726=Simona
name.female3727=Simone
name.female3728=Simonne
name.female3729=Sina
name.female3730=Sindy
name.female3731=Siobhan
name.female3732=Sirena
name.female3733=Siu
name.female3734=Sixta
name.female3735=Skye
name.female3736=Slyvia
name.female3737=Socorro
name.female3738=Sofia
name.female3739=Soila
name.female3740=Sol
name.female3741=Solange
name.female3742=Soledad
name.female3743=Somer
name.female3744=Sommer
name.female3745=Son
name.female3746=Sona
name.female3747=Sondra
name.female3748=Song
name.female3749=Sonia
name.female3750=Sonja
name.female3751=Sonya
name.female3752=Soo
name.female3753=Sook
name.female3754=Soon
name.female3755=Sophia
name.female3756=Sophie
name.female3757=Soraya
name.female3758=Sparkle
name.female3759=Spring
name.female3760=Stacee
name.female3761=Stacey
name.female3762=Staci
name.female3763=Stacia
name.female3764=Stacie
name.female3765=Stacy
name.female3766=Star
name.female3767=Starla
name.female3768=Starling
name.female3769=Starr
name.female3770=Stasia
name.female3771=Stefani
name.female3772=Stefania
name.female3773=Stefanie
name.female3774=Stefany
name.female3775=Steffanie
name.female3776=Stella
name.female3777=Stepanie
name.female3778=Stephaine
name.female3779=Stephane
name.female3780=Stephani
name.female3781=Stephania
name.female3782=Stephanie
name.female3783=Stephany
name.female3784=Stephen
name.female3785=Stephenie
name.female3786=Stephine
name.female3787=Stephnie
name.female3788=Steven
name.female3789=Stevie
name.female3790=Stormy
name.female3791=Suanne
name.female3792=Sudie
name.female3793=Sue
name.female3794=Sueann
name.female3795=Suellen
name.female3796=Suk
name.female3797=Sulema
name.female3798=Sumiko
name.female3799=Summer
name.female3800=Sun
name.female3801=Sunday
name.female3802=Sung
name.female3803=Sunni
name.female3804=Sunny
name.female3805=Sunshine
name.female3806=Susan
name.female3807=Susana
name.female3808=Susann
name.female3809=Susanna
name.female3810=Susannah
name.female3811=Susanne
name.female3812=Susie
name.female3813=Susy
name.female3814=Suzan
name.female3815=Suzann
name.female3816=Suzanna
name.female3817=Suzanne
name.female3818=Suzette
name.female3819=Suzi
name.female3820=Suzie
name.female3821=Suzy
name.female3822=Svetlana
name.female3823=Sybil
name.female3824=Syble
name.female3825=Sydney
name.female3826=Sylvia
name.female3827=Sylvie
name.female3828=Synthia
name.female3829=Syreeta
name.female3830=Tabatha
name.female3831=Tabetha
name.female3832=Tabitha
name.female3833=Tai
name.female3834=Taina
name.female3835=Taisha
name.female3836=Tajuana
name.female3837=Takako
name.female3838=Takisha
name.female3839=Talia
name.female3840=Talisha
name.female3841=Talitha
name.female3842=Tally
name.female3843=Tam
name.female3844=Tama
name.female3845=Tamala
name.female3846=Tamar
name.female3847=Tamara
name.female3848=Tamatha
name.female3849=Tambra
name.female3850=Tameika
name.female3851=Tameka
name.female3852=Tamekia
name.female3853=Tamela
name.female3854=Tamera
name.female3855=Tamesha
name.female3856=Tami
name.female3857=Tamica
name.female3858=Tamie
name.female3859=Tamika
name.female3860=Tamiko
name.female3861=Tamisha
name.female3862=Tammara
name.female3863=Tammera
name.female3864=Tammi
name.female3865=Tammie
name.female3866=Tammy
name.female3867=Tamra
name.female3868=Tana
name.female3869=Tandra
name.female3870=Tandy
name.female3871=Taneka
name.female3872=Tanesha
name.female3873=Tangela
name.female3874=Tania
name.female3875=Tanika
name.female3876=Tanisha
name.female3877=Tanja
name.female3878=Tanna
name.female3879=Tansy
name.female3880=Tanya
name.female3881=Tara
name.female3882=Tarah
name.female3883=Taren
name.female3884=Tari
name.female3885=Tarra
name.female3886=Tarsha
name.female3887=Taryn
name.female3888=Tasha
name.female3889=Tashia
name.female3890=Tashina
name.female3891=Tasia
name.female3892=Tatiana
name.female3893=Tatum
name.female3894=Tatyana
name.female3895=Taunya
name.female3896=Tawana
name.female3897=Tawanda
name.female3898=Tawanna
name.female3899=Tawna
name.female3900=Tawny
name.female3901=Tawnya
name.female3902=Taylor
name.female3903=Tayna
name.female3904=Teena
name.female3905=Tegan
name.female3906=Teisha
name.female3907=Telma
name.female3908=Temeka
name.female3909=Temika
name.female3910=Tempie
name.female3911=Temple
name.female3912=Tena
name.female3913=Tenesha
name.female3914=Tenisha
name.female3915=Tennie
name.female3916=Tennille
name.female3917=Teodora
name.female3918=Teofila
name.female3919=Tequila
name.female3920=Tera
name.female3921=Tereasa
name.female3922=Teresa
name.female3923=Terese
name.female3924=Teresia
name.female3925=Teresita
name.female3926=Teressa
name.female3927=Teri
name.female3928=Terica
name.female3929=Terina
name.female3930=Terisa
name.female3931=Terra
name.female3932=Terrell
name.female3933=Terresa
name.female3934=Terri
name.female3935=Terrie
name.female3936=Terrilyn
name.female3937=Terry
name.female3938=Tesha
name.female3939=Tess
name.female3940=Tessa
name.female3941=Tessie
name.female3942=Thalia
name.female3943=Thanh
name.female3944=Thao
name.female3945=Thea
name.female3946=Theda
name.female3947=Thelma
name.female3948=Theo
name.female3949=Theodora
name.female3950=Theola
name.female3951=Theresa
name.female3952=Therese
name.female3953=Theresia
name.female3954=Theressa
name.female3955=Thersa
name.female3956=Thi
name.female3957=Thomas
name.female3958=Thomasena
name.female3959=Thomasina
name.female3960=Thomasine
name.female3961=Thora
name.female3962=Thresa
name.female3963=Thuy
name.female3964=Tia
name.female3965=Tiana
name.female3966=Tianna
name.female3967=Tiara
name.female3968=Tien
name.female3969=Tiera
name.female3970=Tierra
name.female3971=Tiesha
name.female3972=Tifany
name.female3973=Tiff
name.female3974=Tiffaney
name.female3975=Tiffani
name.female3976=Tiffanie
name.female3977=Tiffany
name.female3978=Tiffiny
name.female3979=Tijuana
name.female3980=Tilda
name.female3981=Tillie
name.female3982=Timika
name.female3983=Timothy
name.female3984=Tina
name.female3985=Tinisha
name.female3986=Tiny
name.female3987=Tisa
name.female3988=Tish
name.female3989=Tisha
name.female3990=Tobi
name.female3991=Tobie
name.female3992=Toby
name.female3993=Toccara
name.female3994=Toi
name.female3995=Tomasa
name.female3996=Tomeka
name.female3997=Tomi
name.female3998=Tomika
name.female3999=Tomiko
name.female4000=Tommie
name.female4001=Tommy
name.female4002=Tommye
name.female4003=Tomoko
name.female4004=Tona
name.female4005=Tonda
name.female4006=Tonette
name.female4007=Toni
name.female4008=Tonia
name.female4009=Tonie
name.female4010=Tonisha
name.female4011=Tonita
name.female4012=Tonja
name.female4013=Tony
name.female4014=Tonya
name.female4015=Topaz
name.female4016=Tora
name.female4017=Tori
name.female4018=Torie
name.female4019=Torri
name.female4020=Torrie
name.female4021=Tory
name.female4022=Tosha
name.female4023=Toshia
name.female4024=Toshiko
name.female4025=Tova
name.female4026=Towanda
name.female4027=Toya
name.female4028=Tracee
name.female4029=Tracey
name.female4030=Traci
name.female4031=Tracie
name.female4032=Tracy
name.female4033=Tran
name.female4034=Trang
name.female4035=Travis
name.female4036=Treasa
name.female4037=Treena
name.female4038=Trena
name.female4039=Tresa
name.female4040=Tressa
name.female4041=Tressie
name.female4042=Treva
name.female4043=Tricia
name.female4044=Trina
name.female4045=Trinh
name.female4046=Trinidad
name.female4047=Trinity
name.female4048=Trish
name.female4049=Trisha
name.female4050=Trista
name.female4051=Tristan
name.female4052=Troy
name.female4053=Trudi
name.female4054=Trudie
name.female4055=Trudy
name.female4056=Trula
name.female4057=Tula
name.female4058=Tuyet
name.female4059=Twana
name.female4060=Twanda
name.female4061=Twanna
name.female4062=Twila
name.female4063=Twyla
name.female4064=Tyesha
name.female4065=Tyisha
name.female4066=Tyler
name.female4067=Tynisha
name.female4068=Tyra
name.female4069=Ula
name.female4070=Ulrike
name.female4071=Una
name.female4072=Unique
name.female4073=Ursula
name.female4074=Usha
name.female4075=Vada
name.female4076=Val
name.female4077=Valarie
name.female4078=Valda
name.female4079=Valencia
name.female4080=Valene
name.female4081=Valentina
name.female4082=Valentine
name.female4083=Valeri
name.female4084=Valeria
name.female4085=Valerie
name.female4086=Valery
name.female4087=Vallie
name.female4088=Valorie
name.female4089=Valrie
name.female4090=Van
name.female4091=Vanda
name.female4092=Vanesa
name.female4093=Vanessa
name.female4094=Vanetta
name.female4095=Vania
name.female4096=Vanita
name.female4097=Vanna
name.female4098=Vannesa
name.female4099=Vannessa
name.female4100=Vashti
name.female4101=Vasiliki
name.female4102=Veda
name.female4103=Velda
name.female4104=Velia
name.female4105=Vella
name.female4106=Velma
name.female4107=Velva
name.female4108=Velvet
name.female4109=Vena
name.female4110=Venessa
name.female4111=Venetta
name.female4112=Venice
name.female4113=Venita
name.female4114=Vennie
name.female4115=Venus
name.female4116=Veola
name.female4117=Vera
name.female4118=Verda
name.female4119=Verdell
name.female4120=Verdie
name.female4121=Verena
name.female4122=Vergie
name.female4123=Verla
name.female4124=Verlene
name.female4125=Verlie
name.female4126=Verline
name.female4127=Verna
name.female4128=Vernell
name.female4129=Vernetta
name.female4130=Vernia
name.female4131=Vernice
name.female4132=Vernie
name.female4133=Vernita
name.female4134=Vernon
name.female4135=Verona
name.female4136=Veronica
name.female4137=Veronika
name.female4138=Veronique
name.female4139=Versie
name.female4140=Vertie
name.female4141=Vesta
name.female4142=Veta
name.female4143=Vicenta
name.female4144=Vickey
name.female4145=Vicki
name.female4146=Vickie
name.female4147=Vicky
name.female4148=Victor
name.female4149=Victoria
name.female4150=Victorina
name.female4151=Vida
name.female4152=Viki
name.female4153=Vikki
name.female4154=Vilma
name.female4155=Vina
name.female4156=Vincenza
name.female4157=Vinita
name.female4158=Vinnie
name.female4159=Viola
name.female4160=Violet
name.female4161=Violeta
name.female4162=Violette
name.female4163=Virgen
name.female4164=Virgie
name.female4165=Virgil
name.female4166=Virgina
name.female4167=Virginia
name.female4168=Vita
name.female4169=Viva
name.female4170=Vivan
name.female4171=Vivian
name.female4172=Viviana
name.female4173=Vivien
name.female4174=Vivienne
name.female4175=Voncile
name.female4176=Vonda
name.female4177=Vonnie
name.female4178=Wai
name.female4179=Walter
name.female4180=Waltraud
name.female4181=Wan
name.female4182=Wanda
name.female4183=Waneta
name.female4184=Wanetta
name.female4185=Wanita
name.female4186=Wava
name.female4187=Wei
name.female4188=Wen
name.female4189=Wendi
name.female4190=Wendie
name.female4191=Wendolyn
name.female4192=Wendy
name.female4193=Wenona
name.female4194=Wesley
name.female4195=Whitley
name.female4196=Whitney
name.female4197=Wilda
name.female4198=Wilhelmina
name.female4199=Wilhemina
name.female4200=Willa
name.female4201=Willena
name.female4202=Willene
name.female4203=Willetta
name.female4204=Willette
name.female4205=Willia
name.female4206=William
name.female4207=Willie
name.female4208=Williemae
name.female4209=Willodean
name.female4210=Willow
name.female4211=Wilma
name.female4212=Windy
name.female4213=Winifred
name.female4214=Winnie
name.female4215=Winnifred
name.female4216=Winona
name.female4217=Winter
name.female4218=Wonda
name.female4219=Wynell
name.female4220=Wynona
name.female4221=Xenia
name.female4222=Xiao
name.female4223=Xiomara
name.female4224=Xochitl
name.female4225=Xuan
name.female4226=Yadira
name.female4227=Yaeko
name.female4228=Yael
name.female4229=Yahaira
name.female4230=Yajaira
name.female4231=Yan
name.female4232=Yang
name.female4233=Yanira
name.female4234=Yasmin
name.female4235=Yasmine
name.female4236=Yasuko
name.female4237=Yelena
name.female4238=Yen
name.female4239=Yesenia
name.female4240=Yessenia
name.female4241=Yetta
name.female4242=Yevette
name.female4243=Ying
name.female4244=Yoko
name.female4245=Yolanda
name.female4246=Yolande
name.female4247=Yolando
name.female4248=Yolonda
name.female4249=Yon
name.female4250=Yong
name.female4251=Yoshie
name.female4252=Yoshiko
name.female4253=Youlanda
name.female4254=Young
name.female4255=Yuette
name.female4256=Yuk
name.female4257=Yuki
name.female4258=Yukiko
name.female4259=Yuko
name.female4260=Yulanda
name.female4261=Yun
name.female4262=Yung
name.female4263=Yuonne
name.female4264=Yuri
name.female4265=Yuriko
name.female4266=Yvette
name.female4267=Yvone
name.female4268=Yvonne
name.female4269=Zada
name.female4270=Zaida
name.female4271=Zana
name.female4272=Zandra
name.female4273=Zelda
name.female4274=Zella
name.female4275=Zelma
name.female4276=Zena
name.female4277=Zenaida
name.female4278=Zenia
name.female4279=Zenobia
name.female4280=Zetta
name.female4281=Zina
name.female4282=Zinnia
name.female4283=Zita
name.female4284=Zoe
name.female4285=Zofia
name.female4286=Zoila
name.female4287=Zola
name.female4288=Zona
name.female4289=Zonia
name.female4290=Zora
name.female4291=Zoraida
name.female4292=Zula
name.female4293=Zulema
name.female4294=Zulma
================================================
FILE: src/main/resources/assets/mca/models/block/rose_gold_block.json
================================================
{
"parent": "block/cube_all",
"textures": {
"all": "mca:blocks/rose_gold_block"
}
}
================================================
FILE: src/main/resources/assets/mca/models/block/rose_gold_ore.json
================================================
{
"parent": "block/cube_all",
"textures": {
"all": "mca:blocks/rose_gold_ore"
}
}
================================================
FILE: src/main/resources/assets/mca/models/block/villager_spawner.json
================================================
{
"parent": "block/cube_all",
"textures": {
"all": "mca:blocks/villager_spawner"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/baby_boy.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/baby_boy"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/baby_girl.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/baby_girl"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/book_death.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/book_death"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/book_family.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/book_family"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/book_infection.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/book_infection"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/book_romance.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/book_romance"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/book_rose_gold.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/book_rose_gold"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/egg_female.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/egg_female"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/egg_male.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/egg_male"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/engagement_ring.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/engagement_ring"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/engagement_ring_rg.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/engagement_ring_rg"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/gold_dust.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/gold_dust"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/matchmakers_ring.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/matchmakers_ring"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/rose_gold_block.json
================================================
{
"parent": "mca:block/rose_gold_block",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/rose_gold_dust.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/rose_gold_dust"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/rose_gold_ingot.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/rose_gold_ingot"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/staff_of_life.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/staff_of_life"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/villager_editor.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/villager_editor"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/wedding_ring.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/wedding_ring"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/wedding_ring_rg.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/wedding_ring_rg"
}
}
================================================
FILE: src/main/resources/assets/mca/models/item/whistle.json
================================================
{
"parent": "item/generated",
"textures": {
"layer0": "mca:items/whistle"
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/engagement_ring.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GDG",
"G G",
"GGG"
],
"key": {
"G": [
{
"item": "minecraft:gold_ingot"
}
],
"D": [
{
"item": "minecraft:diamond"
}
]
},
"result": {
"item": "mca:engagement_ring",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/engagement_ring_rg.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GDG",
"G G",
"GGG"
],
"key": {
"G": [
{
"item": "mca:rose_gold_ingot"
}
],
"D": [
{
"item": "minecraft:diamond"
}
]
},
"result": {
"item": "mca:engagement_ring_rg",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/gold_dust.json
================================================
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
{
"item": "mca:rose_gold_dust"
},
{
"item": "minecraft:water_bucket"
}
],
"result": {
"item": "mca:gold_dust",
"count": 6
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/gold_nugget_from_dust.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GGG",
"GGG",
"GGG"
],
"key": {
"G": [
{
"item": "mca:gold_dust"
}
]
},
"result": {
"item": "minecraft:gold_nugget",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/matchmakers_ring.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"III",
"I I",
"III"
],
"key": {
"I": [
{
"item": "minecraft:iron_ingot"
}
]
},
"result": {
"item": "mca:matchmakers_ring",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/rose_gold_block.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"III",
"III",
"III"
],
"key": {
"I": [
{
"item": "mca:rose_gold_ingot"
}
]
},
"result": {
"item": "mca:rose_gold_block",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/rose_gold_dust_from_ingot.json
================================================
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
{
"item": "mca:rose_gold_ingot"
}
],
"result": {
"item": "mca:rose_gold_dust",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/rose_gold_ingot_from_dust.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GGG",
"GGG",
"GGG"
],
"key": {
"G": [
{
"item": "mca:rose_gold_dust"
}
]
},
"result": {
"item": "mca:rose_gold_ingot",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/wedding_ring.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GGG",
"G G",
"GGG"
],
"key": {
"G": [
{
"item": "minecraft:gold_ingot"
}
]
},
"result": {
"item": "mca:wedding_ring",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/wedding_ring_rg.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
"GGG",
"G G",
"GGG"
],
"key": {
"G": [
{
"item": "mca:rose_gold_ingot"
}
]
},
"result": {
"item": "mca:wedding_ring_rg",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/recipes/whistle.json
================================================
{
"type": "minecraft:crafting_shaped",
"pattern": [
" W#",
"###"
],
"key": {
"#": [
{
"item": "minecraft:iron_ingot",
"data": 0
}
],
"W": [
{
"item": "minecraft:planks",
"data": 0
},
{
"item": "minecraft:planks",
"data": 1
},
{
"item": "minecraft:planks",
"data": 2
},
{
"item": "minecraft:planks",
"data": 3
},
{
"item": "minecraft:planks",
"data": 4
},
{
"item": "minecraft:planks",
"data": 5
}
]
},
"result": {
"item": "mca:whistle",
"count": 1
}
}
================================================
FILE: src/main/resources/assets/mca/sounds.json
================================================
{
"reaper.scythe.out": { "category": "hostile", "subtitle": "Draws scythe", "sounds": [ "mca:reaper-scythe-out" ] },
"reaper.scythe.swing": { "category": "hostile", "subtitle": "Swings scythe", "sounds": [ "mca:reaper-scythe-swing" ] },
"reaper.idle": { "category": "hostile", "subtitle": "Evil laughter", "sounds": [ "mca:reaper-idle" ] },
"reaper.death": { "category": "hostile", "subtitle": "Reaper death", "sounds": [ "mca:reaper-death" ] },
"reaper.block": { "category": "hostile", "subtitle": "Blocked attack", "sounds": [ "mca:reaper-block" ] },
"reaper.summon": { "category": "hostile", "subtitle": "Evil laughter", "sounds": [ "mca:reaper-summon" ] }
}
================================================
FILE: src/main/resources/mcmod.info
================================================
[
{
"modid": "mca",
"name": "Minecraft Comes Alive",
"description": "Replaces villagers with humans, adds marriage, children, and more!",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://minecraftcomesalive.com/",
"updateUrl": "",
"authorList": ["WildBamaBoy", "SheWolfDeadly"],
"credits": "Mezzodrinker, The_Nanobots, numerous others.",
"logoFile": "mca.png",
"screenshots": [],
"dependencies": []
}
]
================================================
FILE: src/main/resources/pack.mcmeta
================================================
{
"pack": {
"description": "Minecraft Comes Alive resources",
"pack_format": 3
}
}