Jump to content

Recommended Posts

Posted

This is quite hard to explain, and if I post all the code it will take you a very long time to read it all, so I will only post parts of it when requested (as I don't know the cause of this)

 

Basically, when I make an instance of the class that stores information about and entity, Minecraft freezes up. It doesn't stop responding, all the entities stop moving, and it's as if I have been 'disconnected' from the world (this is in singleplayer). Also, I have to force kill Minecraft as saving and quitting does nothing.

 

The class itself spawns the entity, and stores information about it (skill levels, etc). I have tried calling this from the client side, server side, and even went as far as creating a packet for it, but they all had the same result. There are a few parts I can show you: I can show you the entity class or the data class (that I am instancing).

 

Just a note, by instancing the class, I call this:

 

public FolkData(World theWorld)
    {
        Random rand = new Random();
        this.gender = rand.nextInt(2);
        this.name = generateName(gender, false, "");
        this.age = 18;

        if (gender == 0)
        {
            this.skinnumber = rand.nextInt(63) + 1; //1 to 63    male;
        }
        else
        {
            this.skinnumber = rand.nextInt(58) + 1; //1 to 58    female;
        }        

        location = getLocationCloseToPlayer();

        if (location == null)
        {
            return;
        }

        respawnEntity(theWorld);
        SimukraftReloaded.theFolks.add(this);
        SimukraftReloaded.sendChat(this.name + " has just wandered into the area.");
    }

Posted

There are a variety of times that the constructor is called. I will list them all:

 

Packet Class

public class GenerateFolkPacket implements IMessage
{

static World world;
static boolean isForced;

public GenerateFolkPacket(){}

public GenerateFolkPacket(World whirld, boolean forced)
{
	this.isForced = forced;
	this.world = whirld;
}

@Override
public void fromBytes(ByteBuf buf) 
{
	isForced = buf.readBoolean();
}

@Override
public void toBytes(ByteBuf buf) 
{
	buf.writeBoolean(isForced);
}

public static class Handler implements IMessageHandler<GenerateFolkPacket, IMessage> 
{

	 @Override
	 public IMessage onMessage(GenerateFolkPacket message, MessageContext ctx) 
	 {
		 if(!isForced)
		 {
			 FolkData.generateNewFolk(world);
		 }
		 else
		 {
			 FolkData.forceGenerateNewFolk(world);
		 }
		 return null;
	 }

}

}

 

Where packet is called from (A GUI class - Client sided)

@Override
    protected void actionPerformed(GuiButton guibutton)
    {
    	if(Minecraft.getMinecraft().theWorld.isRemote)
    	{
    		if (guibutton.id == 0)   //do not run
    		{
    			// SimukraftReloaded.states.runMod = 0;
    			SimukraftReloaded.states.gameModeNumber = 10;
    			System.out.println("Turning off Sim-U-Kraft Reloaded");
    		}
    		else if (guibutton.id == 1)      // normal
    		{
    			// SimukraftReloaded.states.runMod = 1;
    			SimukraftReloaded.states.gameModeNumber = 0;
    			//ModSimukraft.proxy.getClientWorld().playSound(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ, "ashjacksimukraftreloaded:welcome", 1.0f, 1.0f, false);
    			System.out.println("Playing Sim-U-Kraft Reloaded in normal mode");
    			PacketHandler.net.sendToServer(new GenerateFolkPacket(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld(), false));
    		}
    		else if (guibutton.id == 2)    //creative
    		{
    			// SimukraftReloaded.states.runMod = 1;
    			SimukraftReloaded.states.gameModeNumber = 1;
    			//ModSimukraft.proxy.getClientWorld().playSound(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ, "ashjacksimukraftreloaded:welcome", 1.0f, 1.0f, false);
    		}
    		else if (guibutton.id == 3)    //hardcore
    		{
    			//  SimukraftReloaded.states.runMod = 1;
    			SimukraftReloaded.states.gameModeNumber = 2;
    			//ModSimukraft.proxy.getClientWorld().playSound(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ, "ashjacksimukraftreloaded:welcome", 1.0f, 1.0f, false);
    		}

    		SimukraftReloaded.states.saveStates();
    		this.running = false;
    		mc.currentScreen = null;
    		mc.setIngameFocus();
    	}
    }

 

CommonTickHandler (Server sided - obviously)

// ***** ONCE A MINUTE
        if (serverWorld != null && System.currentTimeMillis() - lastMinuteTickAt > 60000)
        {
            if (lastMinuteTickAt > 0)
            {
                Long start = System.currentTimeMillis();
                FolkData.generateNewFolk(serverWorld);
                SimukraftReloaded.states.saveStates();
                Building.checkTennants();
                Building.saveAllBuildings();
                CourierTask.saveCourierTasksAndPoints();
                MiningBox.saveMiningBoxes();
                FarmingBox.saveFarmingBoxes();
                Relationship.saveRelationships();
                //PathBox.savePathBoxes();
                SimukraftReloaded.log.info("CTH: Saved game data in " + (System.currentTimeMillis() - start) + " ms");
            }

            lastMinuteTickAt = now;
        }

Posted

I know the code is very messy, the old mod dev who I took over from merged client and server commands and functions, meaning this mod is singleplayer only. I will post the whole class if you wish, but it is very long, and I do not wish to take up your time.

 

FolkData.class

package ashjack.simukraftreloaded.folk;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Random;

import ashjack.simukraftreloaded.common.Relationship;
import ashjack.simukraftreloaded.common.jobs.Job;
import ashjack.simukraftreloaded.common.jobs.JobBaker;
import ashjack.simukraftreloaded.common.jobs.JobBrickMaker;
import ashjack.simukraftreloaded.common.jobs.JobBuilder;
import ashjack.simukraftreloaded.common.jobs.JobBuildersMerchant;
import ashjack.simukraftreloaded.common.jobs.JobBurgersFryCook;
import ashjack.simukraftreloaded.common.jobs.JobBurgersManager;
import ashjack.simukraftreloaded.common.jobs.JobBurgersWaiter;
import ashjack.simukraftreloaded.common.jobs.JobButcher;
import ashjack.simukraftreloaded.common.jobs.JobCheesemaker;
import ashjack.simukraftreloaded.common.jobs.JobCourier;
import ashjack.simukraftreloaded.common.jobs.JobCropFarmer;
import ashjack.simukraftreloaded.common.jobs.JobDairyFarmer;
import ashjack.simukraftreloaded.common.jobs.JobEggFarmer;
import ashjack.simukraftreloaded.common.jobs.JobFisherman;
import ashjack.simukraftreloaded.common.jobs.JobGlassMaker;
import ashjack.simukraftreloaded.common.jobs.JobGrocer;
import ashjack.simukraftreloaded.common.jobs.JobLivestockFarmer;
import ashjack.simukraftreloaded.common.jobs.JobLumberjack;
import ashjack.simukraftreloaded.common.jobs.JobMiner;
import ashjack.simukraftreloaded.common.jobs.JobShepherd;
import ashjack.simukraftreloaded.common.jobs.JobSoldier;
import ashjack.simukraftreloaded.common.jobs.JobTerraformer;
import ashjack.simukraftreloaded.common.jobs.Job.Vocation;
import ashjack.simukraftreloaded.common.jobs.JobTerraformer.TerraformerType;
import ashjack.simukraftreloaded.core.ModSimukraft;
import ashjack.simukraftreloaded.core.building.Building;
import ashjack.simukraftreloaded.core.registry.SimukraftReloaded;
import ashjack.simukraftreloaded.core.registry.SimukraftReloadedConfig;
import ashjack.simukraftreloaded.entity.EntityFolk;
import ashjack.simukraftreloaded.folk.genetics.Race;
import ashjack.simukraftreloaded.folk.genetics.Races;
import ashjack.simukraftreloaded.folk.traits.Trait;
import ashjack.simukraftreloaded.folk.traits.Traits;
import ashjack.simukraftreloaded.packetsNEW.PacketHandler;
import ashjack.simukraftreloaded.packetsNEW.toClient.UpdateFolkPositionPacket;
import ashjack.simukraftreloaded.proxies.CommonProxy;
import ashjack.simukraftreloaded.proxies.CommonProxy.V3;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.relauncher.Side;

// THE FOLK'S Logic and properties, gets ticked even when EntityFolk is despawned.

public class FolkData implements Serializable
{
    private static final long serialVersionUID = -2617939828256928361L;

    /** the location the folk is employed at or NULL if they are unemployed */
    public V3 employedAt = null;
    /** their vocation type or null if unemployed - used to create theirJob object */
    public Vocation vocation = null;
    /** the reference to their Job (job class and subclasses) or null if unemployed - created on start up based
     * on their vocation field */
    protected ItemStack[] validTools = new ItemStack[0];
    public transient Job theirJob = null;
    /** their full name as a string */
    public String name = "";
    /** age of folk 0 to 17 = child    18+ adult */
    public int age = 18;
    /** gender of this folk 0=male 1=female */
    public int gender = 0;
    public int skinnumber = 1;
    public Race folkRace = null;
    public String folkRaceName = "";
    /** name of the folk they are partnered with */
   // public String partneredWith = "";
    public String trait1 = "";
    public String trait2 = "";
    public String trait3 = "";
    public String trait4 = "";
    /** their level of food  10=well fed   0=starving */
    public int levelFood = 10;
    /** their level of fun  10=having a blast   0=stressed */
    public int levelFun = 10;
    /** their level of fun  10=having a blast   0=stressed */
    public int levelSocial = 10;
    /** their level of fun  10=having a blast   0=stressed */
    public int levelEnvironment = 10;
    /** this folks building level, increases with experience which makes them build faster */
    public float levelBuilder = 1.0f;
    /** this folks mining level, increases with experience which makes the mine faster */
    public float levelMiner = 1.0f;
    /** the level of soldier, 1 to 10, higher level is less delay between kills */
    public float levelSoldier = 1.0f;
    /** their current action (atwork athome etc) */
    public FolkAction action = FolkAction.WANDER;
    /** NULL or the FolkAction they should be on upon arrival */
    public FolkAction actionArrival = null;
    /** should they be standing still on the spot */
    public Boolean stayPut = false;
    /** their destination as a V3 or null if they have none */
    public V3 destination = null;
    /** their current location including dimension (updates as they work and simulate work) */
    public V3 location = null;
    /** their status text that appears over their heads */
    public String statusText = "Wandering";
    public String status1 = "";
    public String status2 = "";
    public String status3 = "";
    public String status4 = "";
    public String funStatus = "";
    public String socialStatus = "";
    public String environmentStatus = "";
    public float pregnancyStage = 0.0f;
    public transient boolean isWorking = false;

    /** has this folk greeted the player today? */
    public boolean greetedToday = false;
    public static transient long anyFolkLastSpoke=0l;
    

    /////// VARIOUS WORK RELATED VARIABLES THAT CAN'T BE STORED IN THE JOB CLASS
    /** reference to the building they are building (if they are a builder) - bodge, but no where else to keep it */
    public Building theBuilding = null;
    public TerraformerType terraformerType = null;
    public int terraformerRadius = 1;

    /////// TRANSIENT VARIABLES NOT STORED WHEN SAVING THIS FOLK
    /** the folk's own inventory for carrying stuff around the world and dropping off stuff */
    public transient ArrayList<ItemStack> inventory = new ArrayList<ItemStack>();
    /** a reference to the entity so we can check it's isDead() and mess with it etc */
    public transient EntityFolk theEntity = null;
    /** set when they are GOTO'ing and walking/beaming, used to beam them if they can't get there within 40 seconds */
    public transient Long timeStartedGotoing = 0l;
    public transient GotoMethod gotoMethod = null;
    private transient long timeSinceLastSave = 0l;
    private transient long timeSinceLastStatusUpdate = 0l;
    private transient long timeSinceLastMinute = 0l;
    /** location they are beaming to or null if they are not beaming */
    public transient V3 beamingTo = null;

    private transient FolkData hangingWith = null;
    private transient int talkCounter = 0;
    public transient float matingStage = -1.0f; // -1 not had today  0.0 to 0.9=having     1.0=had
    private transient int entityId;


    public FolkData()
    {
        //used by sk2 file loading
    }

    /** called after deserializing the folk to activate them, respawns them and adds to arraylist */
    public void hasLoaded()
    {
        String voc = "none";
        String vocat = "";

        if (vocation != null && employedAt != null)
        {
            voc = vocation.toString();
            vocat = employedAt.toString();
        }

        if (employedAt == null)
        {
            vocation = null;
        }

        if (vocation == null)
        {
            employedAt = null;
        }

        // needed to upgrade to new folkdata structure
        if (levelMiner < 1.0f)
        {
            levelMiner = 1.0f;
        }

        if (levelBuilder < 1.0f)
        {
            levelBuilder = 1.0f;
        }

        if (levelSoldier < 1.0f)
        {
            levelSoldier = 1.0f;
        }

        try {
        SimukraftReloaded.log.info("FolkData: hasLoaded() " + this.name + " (" + voc + ") at "
                         + vocat + " location= " + this.location.toString() + "  "  + SimukraftReloaded.theFolks.size() + " folks in total");
        } catch(Exception e) {}
        this.inventory = new ArrayList<ItemStack>();
        this.setTheirJob(vocation);
        respawnEntity(MinecraftServer.getServer().worldServerForDimension(this.location.theDimension));
        SimukraftReloaded.theFolks.add(this);
    }

    /** create a new folk with random name, skin etc and drop into arrayList */
    public FolkData(World theWorld)
    {
        Random rand = new Random();
        this.gender = rand.nextInt(2);
        this.name = generateName(gender, false, "");
        this.age = 18;

        if (gender == 0)
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(63) + 1; //1 to 63    male;
        }
        else
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(58) + 1; //1 to 58    female;
        }
        
        //this.folkRaceName = Races.raceList.get(rand.nextInt(Races.raceList.size())).getRaceName();
        

        location = getLocationCloseToPlayer();

        if (location == null)
        {
            return;
        }
        
        //generateTraits();

        respawnEntity(theWorld);
        SimukraftReloaded.theFolks.add(this);
        SimukraftReloaded.sendChat(this.name + " has just wandered into the area.");
    }
    
    public FolkData(World theWorld, String theName)
    {
        Random rand = new Random();
        this.gender = rand.nextInt(2);
        this.name = theName;
        this.age = 18;

        if (gender == 0)
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(63) + 1; //1 to 63    male;
        }
        else
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(58) + 1; //1 to 58    female;
        }
        
        //this.folkRaceName = Races.raceList.get(rand.nextInt(Races.raceList.size())).getRaceName();
        

        location = getLocationCloseToPlayer();

        if (location == null)
        {
            return;
        }
        
        generateTraits();

        respawnEntity(theWorld);
        SimukraftReloaded.theFolks.add(this);
        SimukraftReloaded.sendChat(this.name + " has just wandered into the area.");
    }

    /** spawn a brand-new child into the world, passes back reference folkData */
    public FolkData(World theWorld, FolkData mother, FolkData father)
    {
        Random rand = new Random();
        String surname = "Unknown";
        
        generateTraits();

        if (father != null)
        {
            surname = father.name.substring(father.name.indexOf(" ") + 1).trim();
        }
        else if (mother != null)
        {
            surname = mother.name.substring(mother.name.indexOf(" ") + 1).trim();
        }

        this.gender = rand.nextInt(2);
        this.name = generateName(gender, true, surname) + " " + surname;
        this.age = 0;

        if (gender == 0)
        {
            this.skinnumber = rand.nextInt(63) + 1; 
        }
        else
        {
            this.skinnumber = rand.nextInt(58) + 1;
        }

        if (mother.getHome() !=null) {
        	mother.getHome().tennants.add(this.name);
        }

        mother.updateLocationFromEntity();
        World mworld=null;
        if (mother.isSpawned()) {
        	mworld=mother.theEntity.worldObj;
        }
        location=Job.findAdjacentSpace(mother.location,mworld);
        
        respawnEntity(theWorld);
        SimukraftReloaded.theFolks.add(this);
        SimukraftReloaded.sendChat(this.name + " has just been born!");
        World world = ModSimukraft.proxy.getClientWorld();

        if (world != null)
        {
            EntityPlayer p = Minecraft.getMinecraft().thePlayer;

            if (p != null)
            {
                ModSimukraft.proxy.getClientWorld().playSound(p.posX, p.posY, p.posZ, "ashjacksimukraftreloaded:birth", 1.0f, 1.0f, false);
            }
        }

        Relationship.setupBloodRelationships(this, father, mother);
        //inherit skills from father and mother
        try {
        this.levelBuilder = (float) Math.floor(father.levelBuilder / 2) + (float) Math.floor(mother.levelBuilder / 2);

        if (this.levelBuilder > 10.0f)
        {
            this.levelBuilder = 10.0f;
        }

        this.levelMiner = (float) Math.floor(father.levelMiner / 2) + (float) Math.floor(mother.levelMiner / 2);

        if (this.levelMiner > 10.0f)
        {
            this.levelMiner = 10.0f;
        }

        this.levelSoldier = (float) Math.floor(father.levelSoldier / 2) + (float) Math.floor(mother.levelSoldier / 2);

        if (this.levelSoldier > 10.0f)
        {
            this.levelSoldier = 10.0f;
        }
        }catch(Exception e) {} //one parent is dead
    }

    /** called from the esc menu to save this folks position based on where the entity is, if it has one */
    public void updateLocationFromEntity()
    {
        if (this.isSpawned())
        {
            this.location = new V3(theEntity.posX, theEntity.posY, theEntity.posZ, this.location.theDimension);
        }
    }

    /** spawn or respawn the entity, but only if they are within 50 blocks of a player */
    public void respawnEntity(World world)
    {
        if (world == null)
        {
            return;
        }

        if (beamingTo != null)
        {
            return;    //dont re-spawn mid beam
        }

        if (theEntity != null)
        {
            if (!theEntity.isDead)
            {
                return;
            }
        } //already spawned, so no need

        if (getDistanceToPlayer() < 50)
        {
            this.theEntity = new EntityFolk(world);
            this.theEntity.setLocationAndAngles(location.x, location.y, location.z, 0f, 0f);

            if (!world.isRemote)
            {
                world.spawnEntityInWorld(this.theEntity);
            }

            //this.theEntity=entity;
            entityId = this.theEntity.getEntityId();
            SimukraftReloaded.log.info("FolkData:repawnEntity() " + this.name + " at " + this.location.toString() + " in dim " + this.location.theDimension + " ENTITY:" + this.theEntity.getEntityId());
        }
    }

    /** this is called from CommonTickHandler to fire off all the folkData onUpdate()'s */
    public static void triggerAllUpdates()
    {
        for (int f = 0; f < SimukraftReloaded.theFolks.size(); f++)
        {
            FolkData fd = SimukraftReloaded.theFolks.get(f);
            fd.onUpdate();
        }
    }

    /** runs client side recivinng updates where this folk actual is - NOT IMPLIMENTED? */
    public void serverToClientLocationUpdate(V3 newLocation) {
    	this.location=newLocation.clone();
    	if (this.theEntity !=null) {
    		newLocation.x=Math.floor(newLocation.x)+0.5f;
    		newLocation.z=Math.floor(newLocation.z)+0.5f;
    		this.theEntity.posX=newLocation.x;
    		this.theEntity.posY=newLocation.y;
    		this.theEntity.posZ=newLocation.z;
    	}
    }
    
    //public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("SUKMain");
    
    
    
    /** update loop for this folk, gets called inDirectly and frequently from CommonTickHandler's inGameTick */
    public void onUpdate()
    {
        Random rand = new Random();
        Long now = System.currentTimeMillis();
        
        
        
        //////// ONCE A MINUTE TASKS
        if (now - timeSinceLastMinute > 60000)
        {
        	if(!this.statusText.contains("Hanging") && !this.statusText.startsWith("Shopping")&&!this.statusText.contains("Visiting") && !this.statusText.contains("Staying")&&!this.statusText.contains("Relaxing")&&this.levelFun > 1&&this.isWorking==false)
        	{
        		levelFun -= 1;
        	}
        	
        	if(this.isWorking == true&&this.levelFun > 1)
        	{
        		levelFun -= 1;
        	}
        	
            if (this.getHome() == null && timeSinceLastMinute > 0)
            {
                getHomeForHomeless();
            }
            
            if(!statusText.contains("Hanging")&&this.levelSocial > 1)
            {
            	levelSocial -= 1;
            }

            //if pregnant and day 9, give birth!
            long t = MinecraftServer.getServer().worldServers[0].getWorldTime() % 24000;

            if (t<2000 && this.pregnancyStage>=1.0f) {
            	for(Building build:SimukraftReloaded.theBuildings) {
            		if (build !=null && build.primaryXYZ !=null && build.displayName.contains("Clinic")) {
            			if (this.destination==null) {
            				if (!build.blockSpecial.isEmpty()) {
            					V3 bed=build.blockSpecial.get(0);
            					this.gotoXYZ(bed, null);
            					SimukraftReloaded.sendChat(this.name+" is about to have a baby, she's on her way to the clinic!");
            				}
            			}
            		}
            	}
            	this.action=FolkAction.HAVINGBABY;
            	
            } else if (t > 2000 && this.pregnancyStage >= 1.0f) {  
            	this.statusText="Just had a baby";
            	//this.action=FolkAction.WANDER;
                pregnancyStage = 0.0f;
                FolkData male = Relationship.isFolkLivingWithSomeone(this, true);
                new FolkData(MinecraftServer.getServer().worldServerForDimension(0), this, male);
            }

            // when staying at home or relaxin at home, make sure they don't wander too far away
            if (action == FolkAction.ATHOME || action == FolkAction.STAYINGHOME)
            {
                this.updateLocationFromEntity();

                try
                {
                    V3 liveAt = null;

                    if (this.getHome().livingXYZ != null)
                    {
                        liveAt = this.getHome().livingXYZ.clone();
                    }

                    if (liveAt == null)
                    {
                        liveAt = this.getHome().primaryXYZ.clone();
                    }

                    if (this.location.getDistanceTo(liveAt) > 5 && destination == null
                            || this.location.theDimension != this.getHome().primaryXYZ.theDimension)
                    {
                        this.actionArrival = action;
                        if (liveAt !=null) {
                        	gotoXYZ(liveAt, GotoMethod.WALK);
                        }
                    }
                }
                catch (Exception e)
                {
                    System.out.println("Non-critical Exception in Sim-U-Kraft:");
                    e.printStackTrace();
                }
            }

            //make them wander to shops and houses if they are wandering
            boolean gotWanderPoint = false;

            if (action == FolkAction.WANDER && this.isSpawned() && this.employedAt == null && this.age >= 18 && !this.statusText.contains("baby"))
            {
                for (int i = 0; i < SimukraftReloaded.theBuildings.size(); i++)
                {
                    Building b = SimukraftReloaded.theBuildings.get(rand.nextInt(SimukraftReloaded.theBuildings.size()));
                    double dist = this.location.getDistanceTo(b.primaryXYZ);

                    if (b.type.contentEquals("commercial") && dist < 40)
                    {
                        boolean hasShopKeeper = false;

                        for (int f = 0; f < SimukraftReloaded.theFolks.size(); f++)
                        {
                            FolkData keeper = SimukraftReloaded.theFolks.get(f);

                            if (keeper.employedAt != null && keeper.employedAt.isSameCoordsAs(b.primaryXYZ, true, true))
                            {
                                hasShopKeeper = true;
                                break;
                            }
                        }

                        if (hasShopKeeper)
                        {
                            SimukraftReloaded.log.info("FolkData:onUpdate() "+name + " is wandering to " + b.displayName + " " + dist + " blocks away.");
                            gotoXYZ(b.primaryXYZ, GotoMethod.WALK);
                            this.destination.doNotTimeout = true;
                            this.statusText = "Shopping at the " + b.displayName;
                            gotWanderPoint = true;

                            if (this.hangingWith != null)
                            {
                                hangingWith.statusText = "Wandering";
                                hangingWith.hangingWith = null;
                                hangingWith = null;
                            }

                            break;
                        }
                    }
                    else if (b.type.contentEquals("industrial") && dist < 40
                             && !b.displayName.toLowerCase().contains("farm"))
                    {
                        
                        try {
                        	SimukraftReloaded.log.info("FolkData: onUpdate() "+name + " is wandering to " + b.displayName + " " + dist + " blocks away.");
                            gotoXYZ(b.primaryXYZ, GotoMethod.WALK);
                        	this.destination.doNotTimeout = true;
                        this.statusText = "Visiting the " + b.displayName;
                        gotWanderPoint = true;
                        } catch(Exception e) {}// destination can be null, just before the building is built
                        
                        if (this.hangingWith != null)
                        {
                            hangingWith.statusText = "Wandering";
                            hangingWith.hangingWith = null;
                            hangingWith = null;
                        }

                        break;
                    }
                    else if (b.type.contentEquals("residential") && dist < 40 && hangingWith == null)
                    {
                        if (b.tennants != null && b.tennants.size() > 0)
                        {
                            FolkData resy = getFolkByName(b.tennants.get(0));
                            try {
                            if (!resy.name.contentEquals(this.name) && resy.hangingWith == null)
                            {
                                if (resy.action == FolkAction.WANDER || resy.action == FolkAction.STAYINGHOME)
                                {
                                    SimukraftReloaded.log.info("FolkData:onUpdate() "+name + " is wandering to " + b.displayName + " " + dist + " blocks away.");
                                    gotoXYZ(b.primaryXYZ, GotoMethod.WALK);
                                    gotWanderPoint = true;
                                    this.statusText = "Hanging out with " + resy.name;
                                    resy.gotoXYZ(b.primaryXYZ, GotoMethod.WALK);

                                    if (this.destination != null)
                                    {
                                        this.destination.doNotTimeout = true;
                                    }

                                    resy.statusText = "Hanging out with " + this.name;
                                    this.hangingWith = resy;
                                    resy.hangingWith = this;
                                    break;
                                }
                            }
                            }catch (Exception e) {} //really don't care if this NPEs
                        }
                    }
                }

                if (!gotWanderPoint)
                {
                    int xo = rand.nextInt(60) - 30;
                    int zo = rand.nextInt(60) - 30;
                    V3 wanderTo = new V3(location.x + xo, location.y, location.z + zo, location.theDimension);
                    World world = MinecraftServer.getServer().worldServerForDimension(location.theDimension);

                    while (world.getBlock(wanderTo.x.intValue(), wanderTo.y.intValue(), wanderTo.z.intValue()) != null
                            && wanderTo.y < 255)
                    {
                        wanderTo.y++;
                    }

                    SimukraftReloaded.log.info("FolkData:onUpdate() WANDER COMMAND FOR " + this.name + " to " + wanderTo.toString());
                    this.gotoXYZ(wanderTo, GotoMethod.WALK);

                    if (this.destination != null)
                    {
                        this.destination.doNotTimeout = true;
                    }

                    statusText = "Wandering";
                    this.stayPut = false;
                }
            }
            else if (action == FolkAction.WANDER && this.isSpawned() && this.age < 18)
            {
                FolkData mother = Relationship.getMotherOf(this);

                if (mother != null)
                {
                    this.gotoXYZ(mother.location, null);
                }
            }

            if (this.hangingWith != null)
            {
                if (!this.hangingWith.statusText.contains(this.name))
                {
                    this.hangingWith = null;
                    this.statusText = "Wandering";
                }
            }

            if (!SimukraftReloaded.isDayTime() && Relationship.isFolkLivingWithSomeone(this) && matingStage < 0)
            {
                tryForBaby();
            }

            timeSinceLastMinute = now - rand.nextInt(20000);
        }

        ///////// ONCE A SECOND TASKS
        if (now - timeSinceLastStatusUpdate > 1000)
        {
        	if(this.trait1 == "" || this.trait2 == "" || this.trait3 == "" || this.trait4 == "")
            {
        		generateTraits();
            }
            updateStatusLines();

            //if they were wandering to a folk house when you hire them, they get stuck on stayput once arrived
            if (this.statusText.contentEquals("Going to my new job..."))
            {
                this.stayPut = false;
            }

            ////////////RESPAWN THEM IF IN RANGE OF PLAYER
            if (!isSpawned())
            {
                int range = this.getDistanceToPlayer();

                if (range < 50)
                {
                    respawnEntity(MinecraftServer.getServer()
                                  .worldServerForDimension(this.location.theDimension));
                }
            }
            else      //if they are spawned, see if they're out of range and force a despawn
            {
                this.theEntity.dimension = this.location.theDimension;
                this.updateLocationFromEntity();
                int range = this.getDistanceToPlayer();

                if (range >= 50)
                {
                    if (theEntity != null)
                    {
                        SimukraftReloaded.log.info("FolkData: onSecTasks - Manually Despawned " + this.name + " as they are " + range + " blocks away");
                        theEntity.setDead();
                    }
                }
            }

            ////////////GOTO WORK IF ITS DAYTIME AND THEY HAVE A JOB
            if (SimukraftReloaded.isDayTime() && this.employedAt != null &&
                    (this.action != FolkAction.ONWAYTOWORK && this.action != FolkAction.ATWORK && pregnancyStage == 0.0f))
            {
                SimukraftReloaded.log.info("FolkData: "+this.name + " is going to work");
                this.statusText = "Going to work";
                action = FolkAction.ONWAYTOWORK;
                gotoXYZ(employedAt, null);
                return;
            }

            if (pregnancyStage > 0.0f && this.employedAt != null && SimukraftReloaded.isDayTime())
            {
                this.statusText = "On Maternity leave";
            }

            if (SimukraftReloaded.isDayTime() && this.employedAt != null && this.action != FolkAction.ATWORK
                    && this.destination == null && pregnancyStage == 0.0f)
            {
                this.statusText = "Going to work";
                action = FolkAction.ONWAYTOWORK;
                SimukraftReloaded.log.warning("FolkData:onUpdate() "+this.name + " is still going to work");
                this.updateLocationFromEntity();
                V3 temp=employedAt.clone();
                temp.x+=5;
                gotoXYZ(temp,GotoMethod.SHIFT);
                gotoXYZ(employedAt, null);
                return;
            }

            if (this.action == FolkAction.ONWAYTOWORK)
            {
                this.statusText = "Going to work";
                this.stayPut = false;

                if (this.destination == null)
                {
                    gotoXYZ(employedAt, null);
                }
            }

            if (this.action == FolkAction.STAYINGHOME && this.hangingWith == null)
            {
                this.statusText = "Staying at home";
                this.stayPut = true;
            }

            if (SimukraftReloaded.isDayTime() && this.statusText.contains("for a baby"))
            {
                this.statusText = "Wandering";
                action = FolkAction.WANDER;
            }
            
            if (this.action==FolkAction.HAVINGBABY) {
            	if (this.pregnancyStage<1.0f) {
            		this.statusText="Just had a baby";
            	} else {
            		this.statusText="Having a baby!";
            	}
            }

            /////// UNEMPLOYED SO STAY AT HOME OR WANDER
            if (SimukraftReloaded.isDayTime() && this.employedAt == null && action == FolkAction.ATHOME)
            {
                isWorking = false;

                if (new Random().nextInt(4) == 1)
                {
                    this.statusText = "Staying Home";
                    action = FolkAction.STAYINGHOME;
                }
                else
                {
                    this.statusText = "Wandering";
                    action = FolkAction.WANDER;
                }
            }

            if (action == FolkAction.STAYINGHOME && this.employedAt != null)
            {
                action = FolkAction.WANDER; //if they are staying at home, but then get a job
            }

            /////////// AT NIGHT WANDER OR GO HOME
            boolean isSoldier = false;

            if (this.vocation != null)
            {
                if (this.vocation == Vocation.SOLDIER)
                {
                    isSoldier = true;
                }
            }

            if (!SimukraftReloaded.isDayTime() && !isSoldier)
            {
                this.action = FolkAction.WANDER;
                this.isWorking=false;

                if (this.getHome() == null)
                {
                    this.statusText = "Wandering";
                    this.stayPut = false;
                }
                else
                {
                    if (this.gotoMethod == GotoMethod.WALK)
                    {
                        this.updateLocationFromEntity();
                    }

                    V3 liveAt=null;

                    try
                    {
                        liveAt = this.getHome().livingXYZ.clone();

                        if (liveAt == null)
                        {
                            liveAt = this.getHome().primaryXYZ.clone();
                        }
                    }
                    catch (Exception e)
                    {
                        SimukraftReloaded.log.warning(this.name+" has no liveAt");
                    }

                    if (liveAt !=null) {
                    int dist = location.getDistanceTo(liveAt);

                    if (dist > 1 && this.destination == null)
                    {
                        this.stayPut = false;
                        gotoXYZ(liveAt, null);
                        this.action = FolkAction.GOINGHOME;
                        this.statusText = "Going Home";
                        isWorking = false;
                    }

                    if (dist <= 1 && !this.statusText.contains("baby"))
                    {
                        this.stayPut = true;
                        this.action = FolkAction.ATHOME;
                        this.statusText = "Relaxing at home";
                        isWorking = false;
                    }
                    }
                }
            }
            else
            {
                this.stayPut = false;
            }

            if (action == FolkAction.WANDER)
            {
                stayPut = false;
            }

            ////// SAVE THIS FOLK EVERY 15 SECONDS OR SO (10 to 20)
            int about10 = rand.nextInt(10000) + 10000;

            if (System.currentTimeMillis() - timeSinceLastSave > about10)
            {
            	Side side = cpw.mods.fml.common.FMLCommonHandler.instance().getEffectiveSide();
            	if (side==Side.SERVER) {
            		//PacketDispatcher.sendPacketToAllPlayers(PacketHandler.makePacket(this.name, "updateFolkPosition", this.location.toString()));
            		//SimukraftPacket.cmd = "updateFolkPosition";
            		//SimukraftPacket.folkName = this.name;
            		//SimukraftPacket.par1 = this.location.toString();
            		//INSTANCE.registerMessage(PacketHandler.class, SimukraftPacket.class, 0, Side.CLIENT);
            		//INSTANCE.sendToAll(new SimukraftPacket());

            		PacketHandler.net.sendToServer(new UpdateFolkPositionPacket(this.location.toString() + ";" + name));//(new UpdateFolkPositionMessage(this.location.toString() + ";" + name),location.theDimension);
            		//BOOKMARK
            		this.saveThisFolk();
            	}

                if(this.statusText.contains("Hanging")&&this.levelSocial < 10)
                {
                	levelSocial += 1;
                }
                
                if(this.statusText.contains("Visiting") || this.statusText.contains("Hanging") || this.statusText.contains("Staying")|| this.statusText.contains("Relaxing") || this.statusText.contains("Shopping") &&this.levelFun < 10)
                {
                	levelFun += 1;
                }
            	
                timeSinceLastSave = System.currentTimeMillis();
            }

            if ((this.statusText.startsWith("Hanging out ") || this.statusText.startsWith("Shopping at the "))
                    && this.destination == null && this.theEntity != null)
            {
                talkCounter++;

                if (talkCounter == 12)
                {
                    if (SimukraftReloadedConfig.configFolkTalking)
                    {
                        int ch = rand.nextInt(26) + 97;
                        String letter = "ashjacksimukraftreloaded:blarg" + Character.toString((char) ch);
                        ModSimukraft.proxy.getClientWorld().playSound(location.x, location.y, location.z, letter, 1.0f, 1.0f, false);
                        //SimukraftReloaded.log(this.name + " Spoke: " + letter);
                    }

                    talkCounter = 0;

                    if (this.hangingWith != null)
                    {
                        Relationship.meddleWithRelationship(this, this.hangingWith);
                    }
                }
            }

            //making a baby!
            if (matingStage >= 0.0f && matingStage < 1.0f && this.gender == 1 && pregnancyStage == 0.0f)
            {
                if (SimukraftReloaded.isDayTime())
                {
                    matingStage = -1.0f;
                }
                else
                {
                    FolkData male = Relationship.isFolkLivingWithSomeone(this, true);

                    if (male != null)
                    {
                        matingStage += 0.02f;

                        if (isSpawned())
                        {
                        	World theWorld = null;
                        	if(!MinecraftServer.getServer().isDedicatedServer())
                        	{
                            	theWorld = Minecraft.getMinecraft().theWorld;
                        	}
                        	else
                        	{
                        		theWorld = MinecraftServer.getServer().getEntityWorld();
                        	}
                            double d0 = rand.nextDouble() * 0.5D;
                            double d1 = rand.nextDouble() * 0.5D;
                            double d2 = rand.nextDouble() * 0.5D;
                            theWorld.spawnParticle("heart", this.theEntity.posX,
                                                   this.theEntity.posY + 2.1,
                                                   this.theEntity.posZ, d0, d1, d2);
                            male.updateLocationFromEntity();

                            if (matingStage < 0.15)
                            {
                                this.gotoXYZ(male.location, GotoMethod.SHIFT); //sometime they wander off during mating LOL :-)
                            }

                            theWorld.spawnParticle("heart", male.location.x,
                                                   male.location.y + 2.1,
                                                   male.location.z, d0, d1, d2);
                            this.statusText = "Trying for a baby";
                            male.statusText = "Trying for a baby";
                            male.stayPut = true;
                        }
                    }
                }
            }
            else if (matingStage >= 1.0f && matingStage < 1.1f)   //finished
            {
                matingStage = 1.1f;
                int chance = rand.nextInt(7); 
                SimukraftReloaded.log.info("FolkData: Finished Trying for baby - chance=" + chance);
                FolkData male = Relationship.isFolkLivingWithSomeone(this, true);
                this.statusText = "Relaxing at home";
                male.statusText = "Relaxing at home";

                if (chance == 1 && this.age < 45)   // 1 in 7 chance of pregnancy, also female needs be be less than 45 yo
                {
                    pregnancyStage = 0.1f;
                    SimukraftReloaded.sendChat("Good news! " + this.name + " and " + male.name + " are expecting a baby!");

                    if (this.isSpawned())
                    {
                        this.theEntity.setJumping(true);
                    }

                    if (male.isSpawned())
                    {
                        male.theEntity.setJumping(true);
                    }

                    World world = ModSimukraft.proxy.getClientWorld();

                    if (world != null)
                    {
                        EntityPlayer p = Minecraft.getMinecraft().thePlayer;

                        if (p != null)
                        {
                            ModSimukraft.proxy.getClientWorld().playSound(p.posX, p.posY, p.posZ, "ashjacksimukraftreloaded:pregnant", 1.0f, 1.0f, false);
                        }
                    }
                }
            }

            timeSinceLastStatusUpdate = now;
        }

        ////// THE REST IS RAN EVERY UPDATE/TICK

        ///////////// DO BEAMING PROGRESS IF THEY ARE BEAMING
        if (this.beamingTo != null)
        {
            doBeaming();
        }

        ////////// FIRE OFF THE JOB'S ONUPDATE() all day and night
        if (this.theirJob != null)
        {
            theirJob.onUpdate();
        }
    }

    /** this is called on the 'once a minute' but is only called once a night and
     * only at night and they have a partner */
    private void tryForBaby()
    {
        if (this.gender == 1 && this.pregnancyStage == 0.0f) //only need to do this for non-preg females
        {
            FolkData malePartner = Relationship.isFolkLivingWithSomeone(this, true);

            if (malePartner != null && this.action == FolkAction.ATHOME && malePartner.action == FolkAction.ATHOME)
            {
                matingStage = 0.0f; //having  - one second tasks handles the rest of this

                if (malePartner.isSpawned())
                {
                    this.gotoXYZ(new V3(malePartner.theEntity.posX, malePartner.theEntity.posY,
                                        malePartner.theEntity.posZ, malePartner.theEntity.dimension), GotoMethod.WALK);
                }

                //SimukraftReloaded.log("tryForBaby() called");
            }
        }
        else
        {
            matingStage = -1.0f;
        }
    }

    /** runs this once a second ONLY if they are homeless */
    private void getHomeForHomeless()
    {
        if (this.action == FolkAction.WANDER)
        {
        	Building.loadAllBuildings();
        	
            for (int b = 0; b < SimukraftReloaded.theBuildings.size(); b++)
            {
                Building building = (Building) SimukraftReloaded.theBuildings.get(b);

                if (building.tennants.size() == 0 && building.buildingComplete == true
                        && building.type.contentEquals("residential"))
                {
                    building.tennants.add(this.name);
                    this.action = FolkAction.GOINGHOME;
                    this.actionArrival = FolkAction.STAYINGHOME;

                    if (building.livingXYZ != null)
                    {
                        gotoXYZ(building.livingXYZ, null);
                    }
                    else
                    {
                        gotoXYZ(building.primaryXYZ, null);
                    }

                   //SimukraftReloaded.states.population++;
                    SimukraftReloaded.states.saveStates();
                    SimukraftReloaded.sendChat(this.name + " is moving into their " + building.displayNameWithoutPK);
                    statusText = "Moved into my " + building.displayNameWithoutPK;
                    Building.saveAllBuildings();
                    break;
                }
            }
        }
    }

    private void updateStatusLines()
    {
    	
    	
        //// UPDATE THEIR STATUS LINES
        if (vocation == null)
        {
            status1 = "Unemployed";
        }
        else
        {
            try
            {
                status1 = vocation.toString();
            }
            catch (Exception e)
            {
                status1 = "";
            }
        }
        Random rand = new Random();
        

        if (this.getHome() != null)
        {
            status2 = "Home owner";
        }
        else
        {
            status2 = "Homeless";
        }

        if (!Relationship.isFolkLivingWithSomeone(this))
        {
            status3 = "Single";
        }
        else
        {
            status3 = "Living with someone";
        }

        if (this.levelFood == 10)
        {
            status4 = "Well fed";
        }
        else if (levelFood > 5)
        {
            status4 = "A little hungry";
        }
        else if (levelFood > 1)
        {
            status4 = "Quite hungry";
        }
        else
        {
            status4 = "VERY hungry!";
        }
        
        if (this.levelFun == 10)
        {
            funStatus = "Having a blast!";
        }
        else if (levelFun > 7)
        {
        	funStatus = "Enjoying themself";
        }
        else if (levelFun > 4)
        {
        	funStatus = "Bored";
        }
        else
        {
        	funStatus = "Stressed";
        }
        
        if (this.levelSocial == 10)
        {
            socialStatus = "Great Banter!";
        }
        else if (levelSocial > 7)
        {
        	socialStatus = "Socially Fulfilled";
        }
        else if (levelSocial > 4)
        {
        	socialStatus = "Lonely";
        }
        else if (levelSocial > 2)
        {
        	socialStatus = "Very Lonely";
        }
        else
        {
        	socialStatus = "Going Insane";
        }
        if (this.levelEnvironment == 10)
        {
            environmentStatus = "Beautiful Surroundings";
        }
        else if (levelEnvironment > 7)
        {
        	environmentStatus = "Nice Surroundings";
        }
        else if (levelEnvironment > 4)
        {
        	environmentStatus = "Poor Surroundings";
        }
        else
        {
        	environmentStatus = "Horrific Surroundings";
        }
    }

    /** returns if the entity is currently spawned (using either the entity==null or entity.isDead being true)*/
    public boolean isSpawned()
    {
        if (this.theEntity == null)
        {
            try
            {
                this.theEntity = FolkData.getFolkByName(this.name).theEntity;
            }
            catch (Exception e) {}  //NPE's at start up
        }

        if (this.theEntity == null)
        {
            return false;
        }
        else
        {
            return !this.theEntity.isDead;
        }
    }

    /** calculates the current distance between this folk and the player */
    public int getDistanceToPlayer()
    {
        EntityPlayer p = FolkData.getClosestPlayer(this.location);

        if (p == null)
        {
            return 9999;
        }

        V3 pv = new V3(p.posX, p.posY, p.posZ, this.location.theDimension);
        return this.location.getDistanceTo(pv);
    }

    /** finds a nice spot close to the player (about 30 blocks away) that is safe to place a folk down*/
    public V3 getLocationCloseToPlayer()
    {
        EntityPlayer p = Minecraft.getMinecraft().thePlayer;
        V3 ret;

        try
        {
            ret = new V3(p.posX, 5d, p.posZ, p.dimension);
        }
        catch (Exception e)
        {
            SimukraftReloaded.log.warning("getLocationCloseToPlayer: player was null, returned null V3");
            return new V3(0d, 5d, 0d, 0);
        }

        boolean found = false;
        Block bid = null;

        try
        {
            for (int go = 30; go > 1; go--)
            {
                ret = new V3(p.posX, 5d, p.posZ + go, p.dimension);

                while (!found)
                {
                    bid = p.worldObj.getBlock(ret.x.intValue(), ret.y.intValue(), ret.z.intValue()); // this can NPE

                    if ((p.worldObj.canBlockSeeTheSky(ret.x.intValue(), ret.y.intValue(), ret.z.intValue()) ||
                            p.dimension != 0) &&
                            bid != Blocks.leaves &&
                            bid == null)
                    {
                        found = true;
                    }

                    ret.y++;

                    if (ret.y > 200)
                    {
                        break;
                    }
                }

                if (found)
                {
                    break;
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        if (!found)
        {
            return new V3(0d, 5d, 0d, 0);
        }

        return ret;
    }

    /** returns the closest player to a location - make sure you set theDimension too */
    public static EntityPlayer getClosestPlayer(V3 location)
    {
        try
        {
            World world = MinecraftServer.getServer().worldServerForDimension(location.theDimension);
            EntityPlayer ret = world.getClosestPlayer(location.x, location.y, location.z, 60);
            return ret;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    /** random name generator for folks - ensures name doesn't exist in this world */
    public static String generateName(int gender, boolean firstNameOnly, String lastNameOptional)
    {
        Random randomGenerator = new Random();
        String firstName = "", lastName = "";
        int i;
        FolkData test = null;

        for (int go = 0; go < 200; go++)
        {
            if (gender == 0)
            {
                i = randomGenerator.nextInt(SimukraftReloadedConfig.configMaleNames.length);
                firstName = SimukraftReloadedConfig.configMaleNames[i].trim();
            }
            else
            {
                i = randomGenerator.nextInt(SimukraftReloadedConfig.configFemaleNames.length);
                firstName = SimukraftReloadedConfig.configFemaleNames[i].trim();
            }

            i = randomGenerator.nextInt(SimukraftReloadedConfig.configSurnames.length);

            if (lastName.contentEquals(""))
            {
                lastName = SimukraftReloadedConfig.configSurnames[i].trim();
            }
            else
            {
                lastName = lastNameOptional;
            }

            test = FolkData.getFolkByName(firstName + " " + lastName);

            if (test == null)
            {
                break;
            }
        } //next go

        if (test != null)  //after 50 go's it still not unique
        {
            lastName += " II";
        }

        if (!firstNameOnly)
        {
            return firstName + " " + lastName;
        }
        else
        {
            return firstName;
        }
    }

    /** fire this folk, resets lots of values */
    public void selfFire()
    {
        SimukraftReloaded.log.info("FolkData: selfFire() " + this.name);
        isWorking = false;

        if (this.inventory.size() > 0)
        {
            int count = 0;

            for (int inv = 0; inv < inventory.size(); inv++)
            {
                ItemStack is = inventory.get(inv);

                if (is != null)
                {
                    if (theEntity != null)
                    {
                        try
                        {
                            theEntity.entityDropItem(is, is.stackSize);
                        }
                        catch (Exception e) {}
                    }
                    else
                    {
                        try
                        {
                            FolkData.getClosestPlayer(this.location).entityDropItem(is, is.stackSize);
                        }
                        catch (Exception e) {}
                    }

                    count += is.stackSize;
                }
            }

            if (count > 0)
            {
                SimukraftReloaded.sendChat(this.name + " has dropped " + count + " items from their inventory");
            }
        }

        this.inventory.clear();

        if (this.theEntity != null)
        {
            theEntity.swingProgress = 0.0f;
            theEntity.getNavigator().clearPathEntity();
        }

        this.employedAt = null;

        if (this.vocation == Vocation.BUILDER)
        {
            theBuilding = null;
        }

        this.vocation = null;
        this.theirJob = null;
        this.action = FolkAction.WANDER;
        this.statusText = "Wandering";
        this.stayPut = false;
        this.saveThisFolk();
    }

    /** tell the folk to goto a location, method will decide how to get them there if you pass NULL for method,
     *  arrival can be NULL */
    public void gotoXYZ(V3 whereTo, GotoMethod methodOfTravel)
    {
    	
    	/*if(theEntity.worldObj.isRemote == true);
    	{
    		SimukraftReloaded.log.info("Is Remote");
    	}
    	if(theEntity.worldObj.isRemote == false)
    	{
    		SimukraftReloaded.log.info("Is NOT Remote");
    	}*/
    	    	
        if (whereTo == null)
        {
            return;
        }

        this.stayPut = false;
        this.destination = whereTo.clone();

        if (this.destination == null)
        {
            return;
        }

        this.destination.doNotTimeout = false;
        int dist = this.location.getDistanceTo(whereTo);

        if (!this.isSpawned())
        {
            methodOfTravel = null;
        }

        if (methodOfTravel == null)
        {
            //decide method of travel
            EntityPlayer pl;
            V3 playpos = null;

            try
            {
                pl = FolkData.getClosestPlayer(this.location);

                if (pl == null || (this.location.theDimension != this.destination.theDimension))
                {
                    dist = 999;
                }
                else
                {
                    playpos = new V3(pl.posX, pl.posY, pl.posZ, pl.dimension);
                }
            }
            catch (Exception e)
            {
                dist = 999;
            }

            if (dist < 40)
            {
                this.gotoMethod = GotoMethod.WALK;
            }

            if (!this.isSpawned() || dist >= 40)
            {
                this.gotoMethod = GotoMethod.BEAM;
            }

            if (playpos != null)  //will be null if player in different dimension or WAY out of range
            {
                if (this.location.getDistanceTo(playpos) >= 40 && whereTo.getDistanceTo(playpos) >= 40)
                {
                    this.gotoMethod = GotoMethod.SHIFT;
                }

                try
                {
                    if (location.theDimension != Minecraft.getMinecraft().thePlayer.dimension &&
                            this.destination.theDimension != Minecraft.getMinecraft().thePlayer.dimension)
                    {
                        this.gotoMethod = GotoMethod.SHIFT;
                    }
                }
                catch (Exception e)
                {
                    this.gotoMethod = GotoMethod.SHIFT;
                }
            }

            //catch all
            if (methodOfTravel == null)
            {
                methodOfTravel = GotoMethod.SHIFT;
            }
        }
        else
        {
            this.gotoMethod = methodOfTravel;
        }

        try
        {
            SimukraftReloaded.log.info("FolkData: GOTOXYZ() for " + this.name + " to " + whereTo.toString() + " - Method:" + gotoMethod.toString()
                             + " DIM:" + whereTo.theDimension);
        }
        catch (Exception e)
        {
            SimukraftReloaded.log.info("FolkData: GOTOXYZ() for " + this.name + " - NULL whereTo");
            return;
        }

        //// start them going
        if (this.destination == null)
        {
            return;
        }

        if (gotoMethod == GotoMethod.SHIFT)
        {
            int xxx = destination.x.intValue();
            int zzz = destination.z.intValue();
            destination.x = xxx + 0.5d;
            destination.z = zzz + 0.5d;

            if (this.theEntity != null)
            {
                //this.theEntity.setPosition(destination.x, destination.y, destination.z);
                //this.theEntity.setPositionAndUpdate(destination.x, destination.y+1, destination.z);
               
                this.theEntity.posX = destination.x;
            	this.theEntity.posY = destination.y;
            	this.theEntity.posZ = destination.z;

                try {
                if (location.theDimension != destination.theDimension)
                {
                	
                    this.theEntity.travelToDimension(destination.theDimension);
                    this.theEntity.dimension = destination.theDimension;
                    this.location.theDimension = destination.theDimension;
                	
                }
                } catch(Exception e) {} //NPE destination or .theDimension?
            }

            try {
            	this.location = destination.clone();
            } catch(Exception e) {} // NPEs when above NPEs
        	this.destination = null;
        }
        else if (gotoMethod == GotoMethod.BEAM)
        {
            this.timeStartedGotoing = System.currentTimeMillis();
            beamMeTo(whereTo);
        }
        else if (gotoMethod == GotoMethod.WALK)
        {
            this.stayPut = false;
            this.timeStartedGotoing = System.currentTimeMillis();
            if (this.theEntity !=null) {
            	this.theEntity.gotPath=false;
            }
            //already set their destination, so this is all it needs
            //It will only get here if they are spawned AND within walking distance
            //so the entity's MoveEntity() method takes over now.
        }
    }

    /** beams the folk to the specified location */
    public void beamMeTo(V3 whereToIn)
    {
        this.stayPut = true;
        this.updateLocationFromEntity(); //only does this if they are currently spawned

        if (this.beamingTo != null)
        {
            SimukraftReloaded.log.warning("FolkData:beamMeTo() already beaming " + this.name);
            return;
        }

        if (whereToIn == null)
        {
            SimukraftReloaded.log.warning("FolkData: beamMeTo() whereTo was NULL, cancelled beaming");
            return;
        }

        timeStartedGotoing = System.currentTimeMillis();
        V3 whereTo = whereToIn.clone();
        World destWorld = MinecraftServer.getServer().worldServerForDimension(whereTo.theDimension);

        for (int y = 0; y < 200; y++)
        {
            Block id1 = destWorld.getBlock(whereTo.x.intValue(), whereTo.y.intValue(), whereTo.z.intValue());
            Block id2 = destWorld.getBlock(whereTo.x.intValue(), whereTo.y.intValue() + 1, whereTo.z.intValue());

            if (id1 == null && id2 == null)
            {
                break;
            }

            whereTo.y++;
        }

        try
        {
            int xxx = whereTo.x.intValue();
            whereTo.x = xxx + 0.5d;
            xxx = whereTo.z.intValue();
            whereTo.z = xxx + 0.5d;
            whereTo.y -= 199d;
        }
        catch (Exception e)
        {
            return;
        }

        this.destination = whereTo.clone();
        SimukraftReloaded.log.info("FolkData: BeamMeTo() for " + this.name + " to " + whereTo.toString() + " Dim:" + whereTo.theDimension);
        this.stayPut = true;

        if (isSpawned())
        {
            this.theEntity.getNavigator().clearPathEntity();
        }

        try {
        if (ModSimukraft.proxy.getClientWorld() != null)
        {
            //ModSimukraft.proxy.getClientWorld().playSound(location.x, location.y, location.z, "ashjacksimukraftreloaded:beamdown", 1.0f, 1.0f, false);
            //ModSimukraft.proxy.getClientWorld().playSound(whereTo.x, whereTo.y, whereTo.z, "ashjacksimukraftreloaded:beamdown", 1f, 1f, false);
        }

        this.beamingTo = whereTo.clone(); //setting this will trigger the beaming progress in the tick/game loop
        } catch(Exception e) {}
    }

    /** called repeatedly during the beaming progress */
    private void doBeaming()
    {
        try
        {
            if (System.currentTimeMillis() - timeStartedGotoing > 4000 || beamingTo == null)
            {
                // arrived via beaming
                if (this.theEntity != null)
                {
                    //this.theEntity.setPosition(beamingTo.x, beamingTo.y, beamingTo.z);
                	this.theEntity.setPositionAndUpdate(beamingTo.x, beamingTo.y+1, beamingTo.z);
                	
                	//this.theEntity.serverPosX = Integer.parseInt(beamingTo.x.toString());
                	//this.theEntity.serverPosY = Integer.parseInt(beamingTo.y.toString());
                	//this.theEntity.serverPosZ = Integer.parseInt(beamingTo.z.toString());
                	
                	//this.theEntity.posX = beamingTo.x;
                	//this.theEntity.posY = beamingTo.y;
                	//this.theEntity.posZ = beamingTo.z;
                	
                    if (theEntity.dimension != beamingTo.theDimension)
                    {
                        this.theEntity.travelToDimension(beamingTo.theDimension);
                        this.theEntity.dimension = beamingTo.theDimension;
                        this.location.theDimension = beamingTo.theDimension;
                    }
                }

                SimukraftReloaded.log.info("FolkData: doBeaming() complete for " + this.name + " to " + beamingTo.toString() + " (dim " + beamingTo.theDimension + ")");
                this.location = beamingTo.clone();
                this.destination = null;
                beamingTo = null;
                respawnEntity(MinecraftServer.getServer().worldServerForDimension(location.theDimension));
                return;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            this.destination = null;
            beamingTo = null;
            return;
        }

        Random random = new Random();
        Double d4 = ((double) random.nextFloat() - 2D) * 2D;
        this.stayPut = true;
        if(!MinecraftServer.getServer().isDedicatedServer())
        {
        	World theWorld = Minecraft.getMinecraft().theWorld; //only need the client world for particles
        

        for (int p = 0; p < 10; p++)
        {
            try
            {
                if (!SimukraftReloadedConfig.configDisableBeamEffect)
                {
                    theWorld.spawnParticle("portal", location.x + (random.nextDouble()) - 0.5,
                                           location.y - 1, location.z + (random.nextDouble()) - 0.5, 0, -d4, 0);
                }
            }
            catch (Exception e) {}

            try
            {
                if (!SimukraftReloadedConfig.configDisableBeamEffect)
                {
                    theWorld.spawnParticle("portal", beamingTo.x + (random.nextDouble()) - 0.5,
                                           beamingTo.y - 1, beamingTo.z + (random.nextDouble()) - 0.5, 0, -d4, 0);
                }
            }
            catch (Exception e)
            {
            }
        }
        }
    }

    /** method that gotoXYZ has decided to use */
    public enum GotoMethod
    {
        WALK, BEAM, SHIFT;

        public String toString()
        {
            if (this == GotoMethod.BEAM)
            {
                return "Beaming";
            }
            else if (this == GotoMethod.SHIFT)
            {
                return "Shifting";
            }
            else if (this == GotoMethod.WALK)
            {
                return "Walking";
            }
            else
            {
                return "";
            }
        }
    }



    /** loads in all the pre-existing folks data, FolkData class will decide if it should spawn them into world */
    public static void loadAndSpawnFolks()
    {
    	SimukraftReloaded.theFolks.clear();
    	
    	File folksFolder = new File(SimukraftReloaded.getSavesDataFolder() + "folks" + File.separator);

        if (!folksFolder.exists())
        {
            folksFolder.mkdirs();
        }

        boolean useNewFormat=false;
        //check for new file format
        for (File f : folksFolder.listFiles())
        {
            if (f.getName().endsWith(".sk2")){
            	useNewFormat=true;
            	break;
            }
        }

        if (useNewFormat) {
        	for (File f : folksFolder.listFiles())
        {
            if (f.getName().endsWith(".sk2"))
            {
            	ArrayList<String> strings=SimukraftReloaded.loadSK2(f.getAbsoluteFile().toString());
            	FolkData folkd = new FolkData();
            	
            	for(String line:strings) {
            		if (line.contains("|")) {
            			int m1=line.indexOf("|");
        				String name=line.substring(0,m1);
        				String value=line.substring(m1+1);
        				
        				
            			try {
        	    			if (name.contentEquals("employedat")) {
        	    				if (!value.contentEquals("null")) {
        	    					folkd.employedAt=new V3(value);
        	    				}
        	    				
        	    			}else if (name.contentEquals("vocation")) {
        	    				if (!value.contentEquals("null")) {
        	    					folkd.vocation=Vocation.valueOf(value);
        	    				}
        	    			}
        	    			else if (name.contentEquals("name")) 
        	    			{
        	    				folkd.name=value;
        	    			}
        	    			else if (name.contentEquals("age")) {
        	    				folkd.age=Integer.parseInt(value);
        	    			}
        	    			else if (name.contentEquals("gender")) {
        	    				folkd.gender=Integer.parseInt(value);
        	    			}
        	    			else if (name.contentEquals("race")) {
        	    				folkd.folkRaceName=value;
        	    			}
        	    			else if (name.contentEquals("skin")) {
        	    				folkd.skinnumber=Integer.parseInt(value);
        	    			}
        	    			else if (name.contentEquals("levelfood")) {
        	    				folkd.levelFood=Integer.parseInt(value);
        	    			}
        	    			else if (name.contentEquals("trait1")) {
        	    				folkd.trait1=value;
        	    			}
        	    			else if (name.contentEquals("trait2")) {
        	    				folkd.trait2=value;
        	    			}
        	    			else if (name.contentEquals("trait3")) {
        	    				folkd.trait3=value;
        	    			}
        	    			else if (name.contentEquals("trait4")) {
        	    				folkd.trait4=value;
        	    			}
        	    			else if (name.contentEquals("levelbuilder")) {
        	    				folkd.levelBuilder=Float.parseFloat(value);
        	    			}
        	    			else if (name.contentEquals("levelminer")) {
        	    				folkd.levelMiner=Float.parseFloat(value);
        	    			}
        	    			else if (name.contentEquals("levelsoldier")) {
        	    				folkd.levelSoldier=Float.parseFloat(value);
        	    			}
        	    			else if (name.contentEquals("stayput")) {
        	    				folkd.stayPut=Boolean.parseBoolean(value);
        	    			}
        	    			else if (name.contentEquals("location")) {
        	    				folkd.location=new V3(value);
        	    			}
        	    			else if (name.contentEquals("pregnancy")) {
        	    				folkd.pregnancyStage= Float.parseFloat(value);
        	    			}
        	    			else if (name.contentEquals("building")) {
        	    				if (!value.contentEquals("null")) {
        	    					int m2=value.indexOf("|");
        	    					int m3=value.indexOf("||");
        	        				String fn=value.substring(0,m2);
        	        				String type=value.substring(m2+1,m3);
        	        				String dir=value.substring(m3+2);  
        	    					folkd.theBuilding=Building.getBuildingForFolk(fn, type);
        	    					folkd.theBuilding.buildDirection=dir;
        	    				}
        	    			}else if (name.contentEquals("terraformtype")) {
        	    				if (!value.contentEquals("null")) {
        	    					folkd.terraformerType=TerraformerType.valueOf(value);
        	    				}
        	    			}else if (name.contentEquals("terraformradius")) {
        	    				folkd.terraformerRadius=Integer.parseInt(value);
        	    			}
        	    			
        	    			
            			} catch(Exception e) {e.printStackTrace(); }
            		}
            	}
            	if (folkd !=null) {
            		SimukraftReloaded.log.info("FolkData: loadAndSpawnFolks() Loaded "+folkd.name+" using new file system");
            		folkd.hasLoaded();
            	}
            }
        }
        	
        } else {   // use the old format (first time only)

        for (File f : folksFolder.listFiles())
        {
            if (f.getName().endsWith(".suk"))
            {
                FolkData folkd = (FolkData) ModSimukraft.proxy.loadObject(f.getAbsoluteFile().toString());

                if (folkd != null)
                {

                    folkd.hasLoaded();
                }
                else
                {
                    f.delete();
                }
            }
        }
        }
    }
    
    /** saves this Folk only (folkData) so they can be loaded in next session */
    public void saveThisFolk()
    {
        String folder = SimukraftReloaded.getSavesDataFolder() + "folks" + File.separator;
        File f = new File(folder);

        if (!f.exists())
        {
            f.mkdirs();
        }

        Side side = cpw.mods.fml.common.FMLCommonHandler.instance().getEffectiveSide();
    	if (side==Side.SERVER) { 
    		ArrayList<String> strings=new ArrayList<String>();
    		if (employedAt ==null) {
    			strings.add("employedat|null");
    		} else {
    			strings.add("employedat|"+this.employedAt.toString());
    		}
        if (vocation==null) {
        	strings.add("vocation|null");
        } else {
        	strings.add("vocation|"+this.vocation.name());
        }
    		strings.add("name|"+this.name);
    		strings.add("age|"+this.age);
    		strings.add("gender|"+this.gender);
    		strings.add("skin|"+ this.skinnumber);
    		strings.add("race|"+this.folkRaceName);
    		strings.add("trait1|"+this.trait1);
    		strings.add("trait2|"+this.trait2);
    		strings.add("trait3|"+this.trait3);
    		strings.add("trait4|"+this.trait4);
    		strings.add("levelfood|"+this.levelFood);
    		strings.add("levelbuilder|"+this.levelBuilder);
    		strings.add("levelminer|"+this.levelMiner);
    		strings.add("levelsoldier|"+this.levelSoldier);
    		strings.add("stayput|"+this.stayPut.toString());
    		strings.add("location|"+this.location.toString());
    		strings.add("pregnancy|"+this.pregnancyStage);
    		if (this.theBuilding==null) {
    			strings.add("building|null");
    		} else {
    			strings.add("building|"+theBuilding.displayName+".txt|"+theBuilding.type+"||"+theBuilding.buildDirection);
    		}
    		if (this.terraformerType==null) {
    			strings.add("terraformtype|null");
    		} else {
    			strings.add("terraformtype|"+this.terraformerType.name());
    		}
    		strings.add("terraformradius|"+this.terraformerRadius);
    		
    		if (!this.name.contentEquals("")) {
    			SimukraftReloaded.saveSK2(folder+this.name+".sk2", strings);
    		}
    	}
        

        //ModSimukraft.proxy.saveObject(folder + this.name + ".suk", this);
    }

    /** get the building/home that this folk lives in, null if homeless */
    public Building getHome()
    {
        for (int b = 0; b < SimukraftReloaded.theBuildings.size(); b++)
        {
            Building home = SimukraftReloaded.theBuildings.get(b);

            for (int t = 0; t < home.tennants.size(); t++)
            {
                String tennant = home.tennants.get(t);

                if (tennant.contentEquals(this.name))
                {
                    return home;
                }
            }
        }

        return null;
    }



    /** creates and optionally spawns in a brand-new folk - gets called every minute, but may not spawn every minute */
    public static void generateNewFolk(World world)
    {
        ArrayList<FolkData> fds = FolkData.getFolkHomeless();

        if (fds.size() == 0 && SimukraftReloaded.theFolks.size() < SimukraftReloadedConfig.configPopulationLimit)
        {
            new FolkData(world);
        }
    }
    
    public static void forceGenerateNewFolk(World world)
    {
        FolkData folk = new FolkData(world);
    }
    
    public static void forceGenerateNewFolk(World world, String nme)
    {
        FolkData folk = new FolkData(world, nme);
    }

    /** return a folk based on their name */
    public static FolkData getFolkByName(String name)
    {
        FolkData f = null;

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            f = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (f.name.contentEquals(name))
            {
                return f;
            }
        }

        return null;
    }

    /** return a folkData based on their position */
    public static FolkData getFolkByLocation(V3 loc)
    {
        FolkData f = null;

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            f = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (f.location.isSameCoordsAs(loc, true, false))
            {
                return f;
            }
        }

        return null;
    }

    /** find a folk who is employed at a particular xyz */
    public static FolkData getFolkByEmployedAt(V3 employedAt)
    {
        FolkData f = null;

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            f = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (f.employedAt != null)
            {
                if (f.employedAt.isSameCoordsAs(employedAt, true, false))
                {
                    return f;
                }
            }
        }

        return null;
    }

    /** PLURAL of getFolkByEmployedAt (which returns the first one it finds) */
    public static ArrayList<FolkData> getFolksByEmployedAt(V3 v)
    {
        ArrayList<FolkData> ret = new ArrayList<FolkData>();

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            FolkData f = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (f.employedAt != null)
            {
                if (f.employedAt.isSameCoordsAs(v, true, false))
                {
                    ret.add(f);
                }
            }
        }

        return ret;
    }

    /** if showEmployed==true it shows all employed folks    false will return unemployed folks */
    public static ArrayList getFolkUnemployed(boolean showEmployed)
    {
        ArrayList f = new ArrayList();

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            FolkData folk = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (showEmployed)
            {
                if (folk.employedAt != null)
                {
                    f.add(folk);
                }
            }
            else
            {
                if (folk.employedAt == null && folk.age > 17 && folk.pregnancyStage == 0.0f)
                {
                    f.add(folk);
                }
            }
        }

        return f;
    }

    /** returns an arraylist of folks that are homeless */
    public static ArrayList getFolkHomeless()
    {
        ArrayList f = new ArrayList();

        for (int x = 0; x < SimukraftReloaded.theFolks.size(); x++)
        {
            FolkData folk = (FolkData) SimukraftReloaded.theFolks.get(x);

            if (folk.getHome() == null)
            {
                f.add(folk);
            }
        }

        return f;
    }

    /** used for spawning so entity can get a reference to the data, returns null if it can't find it */
    public static FolkData getFolkDataByEntityId(int id)
    {
        for (int i = 0; i < SimukraftReloaded.theFolks.size(); i++)
        {
            FolkData fd = SimukraftReloaded.theFolks.get(i);

            if (fd.theEntity != null)
            {
                if (fd.theEntity.getEntityId() == id)
                {
                    return fd;
                }
            }
        }

        return null;
    }

    /** what each folk is doing */
    public enum FolkAction
    {
        ONWAYTOWORK, ATWORK, WANDER, ATHOME, GOINGHOME, STAYINGHOME, HAVINGBABY;

        @Override
        public String toString()
        {
            String ret = "doing nothing";

            if (this == FolkAction.WANDER)
            {
                ret = "just wandering";
            }
            else if (this == FolkAction.ATWORK)
            {
                ret = "at work";
            }
            else if (this == FolkAction.ONWAYTOWORK)
            {
                ret = "on my way to work";
            }
            else if (this == FolkAction.ATHOME)
            {
                ret = "relaxing at home";
            }
            else if (this == FolkAction.GOINGHOME)
            {
                ret = "going home";
            }
            else if (this == FolkAction.STAYINGHOME)
            {
                ret = "staying at home";
            } else if (this==FolkAction.HAVINGBABY) {
            	ret= "having a baby";
            }

            return ret;
        }
    }

    /** called from the entity when the folk has died of something */
    public void eventDied(DamageSource d)
    {
    	Side side = cpw.mods.fml.common.FMLCommonHandler.instance().getEffectiveSide();
    	SimukraftReloaded.log.info("eventDied in FolkData fired on "+side.toString()+" side");
    	
    	String oldJob = "";

        if (this.vocation != null)
        {
            oldJob = " (" + this.vocation.toString() + ")";
        }

        this.employedAt = null;
        this.vocation = null;
        String deathBy = "";

        if (d == DamageSource.cactus)
        {
            deathBy = "(death by cactus... the worst kind.) ";
        }

        if (d == DamageSource.drown)
        {
            deathBy = "(drowned) ";
        }

        if (d == DamageSource.generic)
        {
            deathBy = "(Natural causes/old age) ";
        }

        if (d == DamageSource.inFire)
        {
            deathBy = "(Spontanious combustion) ";
        }

        if (d == DamageSource.lava)
        {
            deathBy = "(while walking on lava) ";
        }

        if (d == DamageSource.onFire)
        {
            deathBy = "(Burned alive!) ";
        }

        if (d == DamageSource.outOfWorld)
        {
            deathBy = "(Fell out of the world!) ";
        }

        if (d == DamageSource.starve)
        {
            deathBy = "(starvation, Build farms, bakeries and grocery stores!) ";
        }

        if (d == DamageSource.fall)
        {
            deathBy = "(Fell off a cliff, or were they pushed?!)";
        }

        if (d == DamageSource.inWall)
        {
            deathBy = "(Buried alive under gravel/sand)";
        }

        if (deathBy.contentEquals(""))
        {
            Random r = new Random();
            int ded = r.nextInt(6);

            if (ded == 0)
            {
                deathBy = "(Electrocuted while in bath) ";
            }
            else if (ded == 1)
            {
                deathBy = "(Tripped on roller-skate on stairs) ";
            }
            else if (ded == 2)
            {
                deathBy = "(Trampled by cows) ";
            }
            else if (ded == 3)
            {
                deathBy = "(Ran over by minecart) ";
            }
            else if (ded == 4)
            {
                deathBy = "(Slipped on banana skin) ";
            }
            else if (ded == 5)
            {
                deathBy = "(killed by Notch) ";
            }
        }

        String only = "";

        if (this.age < 80)
        {
            only = "They were only " + this.age + " years old.";
        }
        else
        {
            only = "They were " + this.age + " years old, oh well, they had a good long life!";
        }

        SimukraftReloaded.sendChat(this.name
                              + oldJob + " has just died! " + deathBy + only);
        this.action = FolkAction.WANDER;
        int i = 0;

        //find the folk in the array
        for (int fn = 0; fn < SimukraftReloaded.theFolks.size(); fn++)
        {
            FolkData fo = SimukraftReloaded.theFolks.get(fn);

            if (fo.name.contentEquals(this.name))
            {
                i = fn;
                break;
            }
        }

        evictThem();

        //if partnered, un-partner them
        try
        {
            //remove all their relationships
            for (int q = 0; q < SimukraftReloaded.theRelationships.size(); q++)
            {
                try
                {
                    Relationship rel = SimukraftReloaded.theRelationships.get(q);

                    if (rel.folk1.name.contentEquals(this.name) || rel.folk2.name.contentEquals(this.name))
                    {
                        String fn = rel.folk1.name.replaceAll(" ", "") + rel.folk2.name.replaceAll(" ", "");
                        File f = new File(SimukraftReloaded.getSavesDataFolder() + "Relationships" + File.separator
                                          + fn + ".sk2");
                        f.delete();
                        SimukraftReloaded.theRelationships.remove(q);
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

            File f = new File(SimukraftReloaded.getSavesDataFolder() + "folks" + File.separator + this.name + ".sk2");
            f.delete();

            if (i >= 0)
            {
                if (i < SimukraftReloaded.theFolks.size())
                {
                	SimukraftReloaded.theFolks.remove(i);
                }
            }
        }
        catch (Exception e)
        {
            SimukraftReloaded.log.warning("FolkData: eventDied() "+e.toString());

        }
    }

    /** called when they die, also when they turn 18 and get evicted from their parents house */
    public void evictThem()
    {
        //evict them from their home :-)
        if (this.getHome() != null)
        {
            //SimukraftReloaded.states.population--;

            for (int b = 0; b < SimukraftReloaded.theBuildings.size(); b++)
            {
                Building building = (Building) SimukraftReloaded.theBuildings.get(b);

                if (building != null && this.getHome() != null)
                {
                    if (building.primaryXYZ.isSameCoordsAs(this.getHome().primaryXYZ, true, false))
                    {
                        building.removeTennant(this.name);
                    }
                }
            }
        }
    }

    /** this is called when loading them in, as well as hiring them via GuiEmployFolks()
     * a null will be passed in if they have no job */
    public void setTheirJob(Vocation vocation)
    {
        if (vocation == null)
        {
            return;
        }

        this.vocation = vocation;

        if (this.vocation == Vocation.BUILDER)
        {
            this.theirJob = new JobBuilder(this);
        }
        else if (this.vocation == Vocation.BAKER)
        {
            this.theirJob = new JobBaker(this);
        }
        else if (this.vocation == Vocation.BUTCHER)
        {
            this.theirJob = new JobButcher(this);
        }
        else if (this.vocation == Vocation.CATTLEFARMER)
        {
            this.theirJob = new JobLivestockFarmer(this);
        }
        else if (this.vocation == Vocation.CHICKENFARMER)
        {
            this.theirJob = new JobLivestockFarmer(this);
        }
        else if (this.vocation == Vocation.COURIER)
        {
            this.theirJob = new JobCourier(this);
        }
        else if (this.vocation == Vocation.CROPFARMER)
        {
            this.theirJob = new JobCropFarmer(this);
        }
        else if (this.vocation == Vocation.GLASSMAKER)
        {
            this.theirJob = new JobGlassMaker(this);
        }
        else if (this.vocation == Vocation.BRICKMAKER)
        {
            this.theirJob = new JobBrickMaker(this);
        }
        else if (this.vocation == Vocation.GROCER)
        {
            this.theirJob = new JobGrocer(this);
        }
        else if (this.vocation == Vocation.LUMBERJACK)
        {
            this.theirJob = new JobLumberjack(this);
        }
        else if (this.vocation == Vocation.MERCHANT)
        {
            this.theirJob = new JobBuildersMerchant(this);
        }
        else if (this.vocation == Vocation.MINER)
        {
            this.theirJob = new JobMiner(this);
        }
        else if (this.vocation == Vocation.PIGFARMER)
        {
            this.theirJob = new JobLivestockFarmer(this);
        }
        else if (this.vocation == Vocation.SHEPHERD)
        {
            this.theirJob = new JobShepherd(this);
        }
        else if (this.vocation == Vocation.SOLDIER)
        {
            this.theirJob = new JobSoldier(this);
        }
        else if (this.vocation == Vocation.TERRAFORMER)
        {
            this.theirJob = new JobTerraformer(this);
        }
        else if (this.vocation == Vocation.FISHERMAN)
        {
            this.theirJob = new JobFisherman(this);
        }
        else if (this.vocation == Vocation.PATHBUILDER)
        {
            //this.theirJob=new JobPathBuilder(this);
        }
        else if (this.vocation == Vocation.DAIRYFARMER)
        {
            this.theirJob = new JobDairyFarmer(this);
        }
        else if (this.vocation == Vocation.CHEESEMAKER)
        {
            this.theirJob = new JobCheesemaker(this);
        }
        else if (this.vocation == Vocation.BURGERSMANAGER)
        {
            this.theirJob = new JobBurgersManager(this);
        }
        else if (this.vocation == Vocation.BURGERSFRYCOOK)
        {
            this.theirJob = new JobBurgersFryCook(this);
        }
        else if (this.vocation == Vocation.BURGERSWAITER)
        {
            this.theirJob = new JobBurgersWaiter(this);
        }
        else if (this.vocation == Vocation.EGGFARMER)
        {
            this.theirJob = new JobEggFarmer(this);
        }

        this.theirJob.resetJob();
        this.theirJob.step = 1;
    }
    
    public void generateTraits()
    {
    	Random rand = new Random();
    	//Trait 1
        this.trait1 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
        
        
        //Trait 2
    	this.trait2 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	
    	while(this.trait2 == this.trait1 || this.traitHasOpposite(trait2))
    	{
    		this.trait2 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	}
    	
    	
    	//Trait 3
    	this.trait3 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	
    	while(this.trait3 == this.trait2 || this.trait3 == this.trait1 || this.traitHasOpposite(trait3))
    	{
    		this.trait3 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	}
    	
    	
    	//Trait 4
    	this.trait4 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	
    	while(this.trait4 == this.trait1 || this.trait4 == this.trait2 || this.trait4 == this.trait3 || this.traitHasOpposite(trait4))
    	{
    		this.trait4 = Traits.traitList[rand.nextInt(Traits.traitList.length-1)].traitName;
    	}
    }
    
    public boolean traitHasOpposite(String trait)
    {
    	if(Trait.getTraitFromName(trait).traitOpposite != null)
    	{
    		if(trait.contains(Trait.getTraitFromName(trait).traitOpposite.traitName))
    		{
    			return true;
    		}
    	}
    	return false;
    }
      
      public boolean hasTrait(Trait trait)
      {
    	  if(this.trait1.contentEquals(trait.traitName) || this.trait2.contentEquals(trait.traitName) || this.trait3.contentEquals(trait.traitName) || this.trait4.contentEquals(trait.traitName))
    	  {
    		  return true;
    	  }
    	  else
    	  {
    		  return false;
    	  }
      }
      
      
      
      
      
      
      
      
      
}

Posted

I'm finally figuring out how to use GitHub too.

 

Pfft.

Until you can figure out how to manage branches and pull requests, I'd say you've gotten up to "what does GitHub do?"

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Sorry, I'm just trying to let the people that are trying to help me know that I have all the source of a github repo.

 

I know.  I'm just saying that you started with GitHub today and I've been using it for months and I still don't understand most of it.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I know.  I'm just saying that you started with GitHub today and I've been using it for months and I still don't understand most of it.

 

How? It's really not that complicated.

 

P.S. You should join the cool people in IRC, then we can explain how to use GitHub :P

Don't make mods if you don't know Java.

Check out my website: http://shadowfacts.net

Developer of many mods

Posted

How? It's really not that complicated.

 

P.S. You should join the cool people in IRC, then we can explain how to use GitHub :P

 

It's more of a workflow problem.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Create a new world, and when it prompts you to choose a gamemode, pick either creative or normal. Normal makes the issue happen instantly, however, it actually makes Minecraft stop responding. Creative takes a few minutes to generate an NPC, and when it does, the world kinda freezes in place. If you want to, you can also use '/generatefolk' to make an NPC spawn instantly. This also makes the world, but not Minecraft itself freeze. If the mod bugs you about a missing 'Simukraft' folder, you may need to download the actual mod and use put the 'Simukraft' folder into the mods folder.

Posted

I'm sorry, the code was in a similar state to this when I took over development of the mod. Eclipse shows none of those warnings. I guess it's time for me to switch to IDEA. I will look into the loops it uses. Thank you.

Posted

Don't worry, I've switched to IDEA. It is a lot better than Eclipse already. I will work on fixing these errors and optimizing the code, and then maybe people will be able to help me when I run into issues.

Posted

I have found the cause of the problem, but have no idea how or why it is the cause.

 

public FolkData(World theWorld)
    {
        Random rand = new Random();
        this.gender = rand.nextInt(2);
        this.name = generateName(gender, false, "");
        this.age = 18;

        if (gender == 0)
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(63) + 1; //1 to 63    male;
        }
        else
        {
        	//this.folkRace = Races.raceList.get(rand.nextInt(Races.raceList.size()));
        	//this.folkRaceName = folkRace.getRaceName();
            this.skinnumber = rand.nextInt(58) + 1; //1 to 58    female;
        }
        
        //this.folkRaceName = Races.raceList.get(rand.nextInt(Races.raceList.size())).getRaceName();
        

        location = getLocationCloseToPlayer();

        if (location == null)
        {
            return;
        }
        
        //generateTraits();

        respawnEntity(theWorld);
        SimukraftReloaded.theFolks.add(this);
        SimukraftReloaded.sendChat(this.name + " has just wandered into the area.");
    }

 

In this constructor, the line

SimukraftReloaded.theFolks.add(this);

causes Minecraft to freeze.

 

This arraylist is defined in another file(that inherits from no other classes, so it's neither client or server sided, just a bunch of variables and functions that are stored in one place):

public static ArrayList<FolkData> theFolks = new ArrayList<FolkData>();

 

It is only referred to in the static context, except in the constructor above, which is not static. Is that what is causing the issue? Because if it is, it was working before, and I have made no changes to it.

Posted

I commented out the last three lines in the constructor, and gradually added them back in. I was able to walk around and exit the game fine until I uncommented out the arraylist adding one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.