} //returns building ID public int buildGranary(int buildTime) { int buildingID = -1; if (Treasury.haveEnoughToWithdraw(Consts.granary_costtobuild)) { Job granaryKeeperJob; int[] granaryJobs = new int[Consts.numberOfGranaryKeepersPerGranary]; LinkedList <InventoryItem> granaryInventory = new LinkedList <InventoryItem>(); buildingID = Program._aStronghold._buildingsList.Count + 1; for (int i = 0; i < Consts.numberOfGranaryKeepersPerGranary; i++) { granaryKeeperJob = Job_creater.createGranaryKeeper(buildingID); granaryJobs[i] = granaryKeeperJob.JobID; _allJobs.AddLast(granaryKeeperJob); } //creates jobs for the Granary Keeper BuildingWithJobsAndInventory granary = new BuildingWithJobsAndInventory(buildingID, //building ID _leader._id, //owner ID Consts.granary, //type Consts.granary_name, //name Consts.granary_hp, //hp Consts.granary_costtobuild, //cost to build new Status(1, Consts.granary_maxlevel), //level Program._gametime, //start build time buildTime, //build time granaryJobs, //jobs granaryInventory, //inventory BuildingState.Planned, new Status(0, Consts.granaryMaxInventory)); Program._aStronghold._buildingsList.AddLast(granary); Treasury.withdrawGold(Consts.granary_costtobuild); } //have enough money to build farm return(buildingID); } //returns building ID
public int buildEmploymentOffice(int buildTime) { int buildingID = -1; Job builderJob; int[] builderJobs = new int[Consts.numberOfInitialBuilders]; buildingID = Program._aStronghold._buildingsList.Count + 1; if (Treasury.haveEnoughToWithdraw(Consts.employmentoffice_costtobuild)) { for (int i = 0; i < Consts.numberOfInitialBuilders; i++) { builderJob = Job_creater.createBuilderJob(buildingID); builderJobs[i] = builderJob.JobID; _allJobs.AddLast(builderJob); } //creates jobs for builders BuildingWithJobsAndInventory employmentoffice = new BuildingWithJobsAndInventory(buildingID, _leader._id, Consts.employmentoffice, Consts.employmentoffice_name, Consts.employmentoffice_hp, Consts.employmentoffice_costtobuild, new Status(1, Consts.employmentoffice_maxlevel), Program._gametime, buildTime, builderJobs, null, BuildingState.Planned, new Status(0, 0)); Program._aStronghold._buildingsList.AddFirst(employmentoffice); Treasury.withdrawGold(Consts.employmentoffice_costtobuild); } //have enough money to build employment office return(buildingID); }
} //returns the building id public int buildFarm(int buildTime) { int buildingID = -1; if (Treasury.haveEnoughToWithdraw(Consts.farm_costtobuild)) { Job farmerJob; int[] farmJobs = new int[Consts.numberOfFarmersPerFarm]; buildingID = Program._aStronghold._buildingsList.Count + 1; for (int i = 0; i < Consts.numberOfFarmersPerFarm; i++) { farmerJob = Job_creater.createFarmerJob(buildingID); farmJobs[i] = farmerJob.JobID; _allJobs.AddLast(farmerJob); } //creates jobs for the farmer BuildingWithJobsAndInventory farm = new BuildingWithJobsAndInventory(buildingID, //building ID _leader._id, //owner ID Consts.farm, //type Consts.farm_name, //name Consts.farm_hp, //hp Consts.farm_costtobuild, //cost to build new Status(1, Consts.farm_maxlevel), //level Program._gametime, //start build time buildTime, //build time farmJobs, //jobs null, //inventory BuildingState.Planned, new Status(0, 0)); Program._aStronghold._buildingsList.AddLast(farm); Treasury.withdrawGold(Consts.farm_costtobuild); } //have enough money to build farm return(buildingID); } //returns building ID
public void OnGameTickPassedHandler(object sender, EventArgs e) { LinkedList <int> numberLinkList = new LinkedList <int>(); int[] commonerUpdateOrder = new int[Program._aStronghold._commoners.Count]; int index, buildingID; InventoryItem item; Job job; Character person; #region updateStrongholdLeaderDecisionMaker if (Program._aStronghold._leader._decisionmaker.listOfActionsToDo.Count != 0) { bool notEnoughFunds = false; int buildResults = -1; foreach (ActionsToDo todo in Program._aStronghold._leader._decisionmaker.listOfActionsToDo) { #region build to do action if (todo._action == action.Build) { #region build hut todo if (todo._objectTypeID == Consts.hut) { if (todo._parameters == parameters.None) { buildResults = Program._aStronghold.buildHut(Consts.hut_buildtime); } else if (todo._parameters == parameters.BuildImmediate) { buildResults = Program._aStronghold.buildHut(Consts.immediatebuildtime); } } #endregion #region build granary todo else if (todo._objectTypeID == Consts.granary) { if (todo._parameters == parameters.None) { buildResults = Program._aStronghold.buildGranary(Consts.granary_buildtime); } else if (todo._parameters == parameters.BuildImmediate) { buildResults = Program._aStronghold.buildGranary(Consts.immediatebuildtime); } } #endregion #region build farm todo else if (todo._objectTypeID == Consts.farm) { if (todo._parameters == parameters.None) { buildResults = Program._aStronghold.buildFarm(Consts.farm_buildtime); } else if (todo._parameters == parameters.BuildImmediate) { buildResults = Program._aStronghold.buildFarm(Consts.immediatebuildtime); } } #endregion #region build employmentoffice todo else if (todo._objectTypeID == Consts.employmentoffice) { if (todo._parameters == parameters.None) { buildResults = Program._aStronghold.buildEmploymentOffice(Consts.employmentoffice_buildtime); } else if (todo._parameters == parameters.BuildImmediate) { buildResults = Program._aStronghold.buildEmploymentOffice(Consts.immediatebuildtime); } } #endregion if (buildResults == -1) { notEnoughFunds = true; } } #endregion } Program._aStronghold._leader._decisionmaker.listOfActionsToDo.Clear(); Program._aStronghold._leader._decisionmaker.listOfPhenomenons.Clear(); if (notEnoughFunds) { Program._aStronghold._leader._decisionmaker.insertPhenomenon(Consts.stronghold, Consts.stronghold_treasury, subobject.Capacity, behaviour.Empty, parameters.None); } } //there are some actions to do #endregion #region randomize update order for characters //create commonerUpdateOrderArray for (int x = 1; x <= Program._aStronghold._commoners.Count; x++) { numberLinkList.AddLast(x); } //build the link list so we can randomize off it. for (int x = 0; x < Program._aStronghold._commoners.Count; x++) { index = Consts.rand.Next(0, numberLinkList.Count); commonerUpdateOrder[x] = numberLinkList.ElementAt(index); numberLinkList.Remove(commonerUpdateOrder[x]); } //picking randomly from numberlist and populating the order in the array //- #endregion #region update character actions for (int x = 0; x < Program._aStronghold._commoners.Count; x++) { person = ((Character)Program._aStronghold._commoners[commonerUpdateOrder[x]]); //goes through commoner order list if (person._health.hp.HealthState == HealthState.Alive) { job = Program._aStronghold.searchJobByID(person._jobID); if (person._characterActions.Count > 0) { person._currentActionFinishTime = person._characterActions.Peek().FinishTime; } if (person._currentActionFinishTime > Program._gametime) { //wait } //person is doing something - wait until action is over else //person is finished doing action, do results { switch (person._characterActions.Peek().Action) { #region buyingfood case CharacterState.BuyingFood: if (person._characterPreviousActions.Last()._action == CharacterState.BuyingFood) { } //if person has been trying to buy food twice in a row then have the else { LinkedList <Building> granaries = Program._aStronghold.searchBuildingsByType(Consts.granary); InventoryItem food; int totalFood = 0; int granaryIDToBuy = -1; if (granaries.Count != 0) { foreach (BuildingWithJobsAndInventory granary in granaries) { if (granary.BuildingState == BuildingState.Built) { food = granary.searchInventoryByID(Consts.FOOD_ID); if (food != null) { totalFood += food.Quantity; if (granary.InventoryCapacity.Current != 0) { granaryIDToBuy = granary.BuildingID; } } } } if (person._characterinventory.searchForItemByName(Consts.GOLD_NAME).Quantity == 0) { person._characterActions.Dequeue(); } else if (totalFood == 0) { person._characterActions.Dequeue(); } else { if (granaryIDToBuy != -1) { person.buyFood(granaryIDToBuy); person._characterActions.Dequeue(); } //else no granaries were found } //else buy food from granaryIDTobuy } else { person._characterActions.Dequeue(); } person.addNewPreviousAction(CharacterState.BuyingFood); } break; #endregion #region eating case CharacterState.Eating: person._bodyneeds.HungerState = HungerState.JustAte; person._bodyneeds.LastAteTime.CopyGameTime(Program._gametime); person._characterActions.Dequeue(); //action is finished person.addNewPreviousAction(CharacterState.Eating); break; #endregion #region lookingforplacetolive case CharacterState.LookingForPlaceToLive: if (person._homeID == Consts.stronghold_yard) { buildingID = person.findPlaceToLive(); person._homeID = buildingID; person._locationID = buildingID; } //person is looking for place to live, returns STRONGHOLD_YARD if does not find any if (person._homeID != Consts.stronghold_yard) { person._characterActions.Dequeue(); } //person found place to live person.addNewPreviousAction(CharacterState.LookingForPlaceToLive); break; #endregion #region sleeping case CharacterState.Sleeping: person._bodyneeds.SleepState = SleepState.Awake; person._bodyneeds.LastSleptTime.CopyGameTime(Program._gametime); person._characterActions.Dequeue(); person.addNewPreviousAction(CharacterState.Sleeping); break; #endregion #region working case CharacterState.Working: person._characterActions.Dequeue(); item = person._characterinventory.retrieveItemInInventory(null, Consts.GOLD_ID); if (item != null) { item.Quantity += job.Payroll; person._characterinventory.putInInventory(item); } //person has gold else { person._characterinventory.putInInventory(new InventoryItem(Consts.GOLD_NAME, Consts.GOLD_ID, Consts.GOLD_WEIGHT, job.Payroll)); } //person doesn't have gold, put gold into inventory if (String.Compare(job.JobName, Consts.builderName) == 0) { Building building; Program._aStronghold.searchBuildingByID(job.BuildingID, out building); if (building != null) { building.NumberOfCurrentBuilders--; job.BuildingID = Consts.stronghold_yard; } } //builder stops working , need to take builder off building person.addNewPreviousAction(CharacterState.Working); break; #endregion } } #region person current action if (person._characterActions.Count > 0) { if (person._characterActions.Peek().Action == CharacterState.Idle) { Gametime finishTime; #region Hunger check //Check if hungry if (person._bodyneeds.HungerState == HungerState.JustAte) { person._bodyneeds.HungerState = HungerState.Full; person._health.hp.Regeneration = 1; } //just ate last round, this round character is full else if (person._bodyneeds.HungerState == HungerState.Full && Program._gametime >= person._bodyneeds.LastAteTime + (int)Consts.hungerTimer.Normal) { person._bodyneeds.HungerState = HungerState.Normal; person._health.hp.Regeneration = 0; } //pass normal hunger time and loses hp regeneration else if (person._bodyneeds.HungerState == HungerState.Normal && Program._gametime > person._bodyneeds.LastAteTime + (int)Consts.hungerTimer.Full) { person._bodyneeds.HungerState = HungerState.Hungry; } //pass hungry hunger time else if (person._bodyneeds.HungerState == HungerState.Hungry) { person._bodyneeds.HungerState = HungerState.Hungry; person._health.hp.Regeneration = -1; } //if hungry and then remains hungry and loses hp every game tick #endregion #region Sleep check if (Program._gametime > person._bodyneeds.LastSleptTime + (int)Consts.sleepTimer.Awake) { person._bodyneeds.SleepState = SleepState.MustSleep; finishTime = Program._gametime + Consts.actionsData[(int)CharacterState.Sleeping]._actionDuration; person._characterActions.insertItemIntoQueue(new CharacterAction(CharacterState.Sleeping, Consts.actionsData[(int)CharacterState.Sleeping]._actionPriority, finishTime)); } #endregion #region Employment check if (person._jobID == -1) //&& person wants to look for job) { LinkedList <Job> listOfAvailableJobs = Program._aStronghold.getAllAvailableJobs(); if (listOfAvailableJobs.Count > 0) { Job availableJob = new Job(); if (Program._aStronghold.hasAtLeastOneBuilderEmployed()) { //randomly picks an available job availableJob = listOfAvailableJobs.ElementAt(Consts.rand.Next(0, listOfAvailableJobs.Count - 1)); } //if there is at least one builder in stronghold else { availableJob = Program._aStronghold.searchFirstAvailableJobByName(Consts.builderName); } //choose builder job for applying Building building = new Building(); Program._aStronghold.searchBuildingByID(availableJob.BuildingID, out building); if (building.BuildingState == BuildingState.Built) { person.applyForJob(availableJob.JobID); } //building that is providing with the job must be built first } //there are jobs in stronghold else { if (!Program._aStronghold.farmsHasAvailableJobs() && !Program._aStronghold.hasEnoughPlannedOrConstruction(Consts.farm)) { Program._aStronghold._leader._decisionmaker.insertPhenomenon(Consts.stronghold, Consts.stronghold_jobs, subobject.Capacity, behaviour.Empty, parameters.None); //no jobs } //if there are no available jobs in the farms and no farms are currently planned or under construction } //no available jobs in stronghold } //person applies for first job in the list else { if (job != null) { if (Program._gametime >= job.StartDate && Program._gametime < job.EndDate) { if (Program._gametime.compareTimeOnly(job.StartTime) <= 0 && //gametime >= job start time Program._gametime.compareTimeOnly(job.EndTime) > 0) //gametime <= job end time { bool needToWork = true; if (String.Compare(job.JobName, Consts.builderName) == 0) { LinkedList <Building> allPlannedBuildings = Program._aStronghold.searchBuildingsByBuildingState(BuildingState.UnderConstruction); if (allPlannedBuildings.Count == 0) { person._currentActionFinishTime.CopyGameTime(Program._gametime); needToWork = false; } //no buildings to build so finish working else if (job.BuildingID != allPlannedBuildings.First.Value.BuildingID) { allPlannedBuildings.First.Value.NumberOfCurrentBuilders++; job.BuildingID = allPlannedBuildings.First.Value.BuildingID; } //assign builder to building only if the builder is not already assigned } //if person is a builder if (needToWork) { Gametime workTimeRelative = new Gametime(Program._gametime.Day, job.EndTime.Hour, job.EndTime.Minute); if (job.EndDate >= workTimeRelative) { finishTime = workTimeRelative; } else { finishTime = job.EndDate; } person._characterActions.insertItemIntoQueue(new CharacterAction(CharacterState.Working, Consts.actionsData[(int)CharacterState.Working]._actionPriority, finishTime)); } } //gametime is between job start time and end time } //job position is open else { Program._aStronghold._allJobs.Find(job).Value.JobStatus = JobStatus.Closed; person._jobID = -1; } //job is no longer available - taken off the market } //person is already employed } //person already employed or doesn't want to work #endregion #region Accomondation check if (person._locationID == Consts.stronghold_yard && person._homeID == Consts.stronghold_yard) { finishTime = Program._gametime; person._characterActions.insertItemIntoQueue(new CharacterAction(CharacterState.LookingForPlaceToLive, Consts.actionsData[(int)CharacterState.LookingForPlaceToLive]._actionPriority, finishTime)); } #endregion } else if (person._characterActions.Peek().Action == CharacterState.Eating) { person._health.staminaUsedThisTick = 3; } else if (person._characterActions.Peek().Action == CharacterState.LookingForPlaceToLive) { person._health.staminaUsedThisTick = 5; } else if (person._characterActions.Peek().Action == CharacterState.Sleeping) { person._locationID = person._homeID; //sleeping } else if (person._characterActions.Peek().Action == CharacterState.Working) { person._health.staminaUsedThisTick = 10; person._locationID = job.BuildingID; if (String.Compare(job.JobName, Consts.builderName) == 0) { LinkedList <Building> allPlannedBuildings = Program._aStronghold.searchBuildingsByBuildingState(BuildingState.UnderConstruction); if (allPlannedBuildings.Count == 0) { person._currentActionFinishTime.CopyGameTime(Program._gametime); } //no buildings to build so finish working } } } #endregion #region person health update //person health is updated at the end of each tick person._health.hp.Current += person._health.hp.Regeneration; person._health.mp.Current += person._health.mp.Regeneration; person._health.stamina.Current = person._health.stamina.Current + person._health.stamina.Regeneration - person._health.staminaUsedThisTick; person._health.staminaUsedThisTick = 0; //reset the stamina usage at the end of gametick #endregion } //if person is alive then update actions } #endregion #region update building actions int totalFoodProduced = 0; foreach (Building building in Program._aStronghold._buildingsList) { #region building construction phases if (building.BuildingState != BuildingState.Built) { //update man working hours building.NumberOfManBuildingHoursLeft -= building.NumberOfCurrentBuilders; //update building constructor status if ((building.NumberOfManBuildingHoursLeft < 0 && building.BuildingState != BuildingState.Built)) { building.BuildingState = BuildingState.Built; } //building is finished else if (Program._gametime >= building.StartBuildTime && building.NumberOfManBuildingHoursLeft >= 0) //&& building.BuildingState != BuildingState.UnderConstruction) { building.BuildingState = BuildingState.UnderConstruction; } //building is underconstruction } //update building phases only if the building is not built #endregion if (Program._gametime.isMidnight()) { if (building.Type == Consts.farm && building.BuildingState == BuildingState.Built) { int[] jobList = ((BuildingWithJobsAndInventory)building).Jobs; for (int i = 0; i < jobList.Length; i++) { if (null != jobList && jobList[i] > 0) { if (Program._aStronghold.searchJobByID(jobList[i]).JobStatus == JobStatus.Taken) { totalFoodProduced += Consts.numberOfFoodProducedPerFarmer; } //job is taken and hence producing food } //job list has jobs } } //transfer farm foods to granary at end of the day } //occurs at the end of each day } bool notthrown = false; InventoryItem foodTransferredToGranary = new InventoryItem(Consts.FOOD_NAME, Consts.FOOD_ID, Consts.FOOD_WEIGHT, totalFoodProduced); int foodLeftAfterTransfer = totalFoodProduced; if (totalFoodProduced > 0) { foreach (Building building in Program._aStronghold._buildingsList) { if (building.Type == Consts.granary && !notthrown && building.BuildingState == BuildingState.Built) { BuildingWithJobsAndInventory granary = building as BuildingWithJobsAndInventory; if (granary.hasEnoughStorageSpace()) { //Building result; //Program._aStronghold.searchBuildingByID(granary.BuildingID, out result); if (granary.InventoryCapacity.Max - granary.InventoryCapacity.Current >= foodTransferredToGranary.Quantity) { foodLeftAfterTransfer = 0; notthrown = true; } //no surplus of food left after transfer else { foodLeftAfterTransfer = foodTransferredToGranary.Quantity - (granary.InventoryCapacity.Max - granary.InventoryCapacity.Current); } //surplus of food , need to throw some out granary.addToInventory(foodTransferredToGranary); } //granary has enough room to store } } if (!notthrown) { //food wasted if (!Program._aStronghold.hasEnoughPlannedOrConstruction(Consts.granary)) { Program._aStronghold._leader._decisionmaker.insertPhenomenon(Consts.stronghold, Consts.granary, subobject.Existence, behaviour.Empty, parameters.None); } } } //transfer food only if food produced is > 0 #endregion } //actions to do in every game tick