public static void UpdateNPCAndBankData() { foreach (NPC npc in mListNPC) { if (npc.status == NPC.Status.dead) { continue; } // Spend money npc.current_money -= npc.consume_rate; if (npc.current_money <= 0) { npc.status = NPC.Status.dead; npc.die_round = SimulationManager.SimulationRound; continue; } // Prepare to look for money npc.mDecisionList.Clear(); int max_money = 0; // Find max view area to check if there is money, go to the location that has max money for (int m = GF.CheckBoundary(npc.current_loc.X - (int)npc.view_size, GF.Axis.x); m < GF.CheckBoundary(npc.current_loc.X + (int)npc.view_size, GF.Axis.y); m++) { for (int n = GF.CheckBoundary(npc.current_loc.Y - (int)npc.view_size, GF.Axis.y); n < GF.CheckBoundary(npc.current_loc.Y + (int)npc.view_size, GF.Axis.y); n++) { if (MapManager.Money_abs_data_arr[m, n] > max_money) { max_money = MapManager.Money_abs_data_arr[m, n]; npc.mDecisionList.Add(new NPC.Decision(m, n, max_money)); } } } // if he/she found some money... if (max_money > 0) { npc.status = NPC.Status.working; //After search for max value, the last value in mDecisionList is the max value int max_x = npc.mDecisionList[npc.mDecisionList.Count() - 1].X; int max_y = npc.mDecisionList[npc.mDecisionList.Count() - 1].Y; // NPC move there npc.current_loc = new NPC.Location(max_x, max_y); // Consume bank MapManager.Money_abs_data_arr[max_x, max_y] -= npc.earn_rate; // If this money stack is empty if (MapManager.Money_abs_data_arr[max_x, max_y] < 0) { MapManager.Money_abs_data_arr[max_x, max_y] = 0; MapManager.Money_stack_data_arr[max_x, max_y] = 0; } // If after giving money to npc, it has 1 less stack, update stack data else if (MapManager.Money_abs_data_arr[max_x, max_y] / MapManager.MONEY_PER_STACK < MapManager.Money_stack_data_arr[max_x, max_y] - 1) { MapManager.Money_stack_data_arr[max_x, max_y]--; } // NPC get money npc.current_money += npc.earn_rate; // In next round npc.earn_rate = (int)(npc.earn_rate + npc.skill_improve_rate); npc.consume_rate = (int)(npc.consume_rate + npc.lust_rate); } // Move to a random location within his/her view field else { // consume rate drop because of idle npc.consume_rate = (npc.consume_rate - 10 > 0 ? npc.consume_rate - 1 : (10 + npc.lust_rate)); npc.status = NPC.Status.moving; // Randomly go to 1 location Random rand = new Random(); int new_x = (int)npc.current_loc.X, new_y = (int)npc.current_loc.Y; switch (rand.Next(1, 5)) { // go to left column case 1: new_x = GF.CheckBoundary(npc.current_loc.X - (int)npc.view_size, GF.Axis.x); new_y = rand.Next(GF.CheckBoundary(npc.current_loc.Y - (int)npc.view_size, GF.Axis.y), GF.CheckBoundary(npc.current_loc.Y + (int)npc.view_size, GF.Axis.y)); break; // go to right column case 2: new_x = GF.CheckBoundary(npc.current_loc.X + (int)npc.view_size, GF.Axis.x); new_y = rand.Next(GF.CheckBoundary(npc.current_loc.Y - (int)npc.view_size, GF.Axis.y), GF.CheckBoundary(npc.current_loc.Y + (int)npc.view_size, GF.Axis.y)); break; // go to top row case 3: new_x = rand.Next(GF.CheckBoundary(npc.current_loc.X - (int)npc.view_size, GF.Axis.x), GF.CheckBoundary(npc.current_loc.X + (int)npc.view_size, GF.Axis.x)); new_y = GF.CheckBoundary(npc.current_loc.Y - (int)npc.view_size, GF.Axis.y); break; // go to bottom row case 4: new_x = rand.Next(GF.CheckBoundary(npc.current_loc.X - (int)npc.view_size, GF.Axis.x), GF.CheckBoundary(npc.current_loc.X + (int)npc.view_size, GF.Axis.x)); new_y = GF.CheckBoundary(npc.current_loc.Y + (int)npc.view_size, GF.Axis.y); break; } npc.current_loc = new NPC.Location(new_x, new_y); } // Locate 1 npc //if (npc.current_loc.X == i && npc.current_loc.Y == j) //{ //} //for (int i = 0; i < MapManager.MAP_SIZE.width; i++) //{ // for (int j = 0; j < MapManager.MAP_SIZE.height; j++) // { // } //} } }