Example #1
0
string cRivalManager::rivals_plunder_pc_gold(cRival* rival)
{
	if (g_Gold.ival() <= 0) return "";						// no gold to sieze? nothing to do.
	long pc_gold = g_Gold.ival();							// work out how much they take. make a note of how much we have

	long gold = g_Dice.random(min((long)2000, pc_gold));
	if (gold < 45) gold = 45;								// make sure there's at least 45 gold taken
	if (pc_gold < gold) gold = pc_gold;						// unless the pc has less than that, in which case take the lot
	g_Gold.rival_raids(gold);								// deduct the losses against rival raid losses
	rival->m_Gold += gold;									// add the aount to rival coffers

	stringstream ss;
	ss << gettext("\nThey get away with ") << gold << gettext(" gold.");	// format a message and store it in the string that was passed to us
	return ss.str();
}
void cScreenGirlDetails::take_gold(sGirl *girl)
{
	string message;
	bool girl_win = do_take_gold(girl, message);
	/*
	*	if the girl won, then we're pretty much sorted
	*	display the message and return
	*/
	if (girl_win)
	{
		g_MessageQue.AddToQue(message, 0);
		g_InitWin = true;
		return;
	}
	/*
	*	so the girl lost: take away her money now
	*/
	g_Gold.misc_credit(girl->m_Money);
	girl->m_Money = 0;
	/*
	*	she isn't going to like this much
	*	but it's not so bad for slaves
	*/
	if (girl->m_States&(1 << STATUS_SLAVE))
	{
		g_Girls.UpdateStat(girl, STAT_CONFIDENCE, -1);
		g_Girls.UpdateStat(girl, STAT_OBEDIENCE, 5);
		g_Girls.UpdateStat(girl, STAT_SPIRIT, -2);
		g_Girls.UpdateStat(girl, STAT_PCHATE, 5);
		g_Girls.UpdateStat(girl, STAT_PCLOVE, -5);
		g_Girls.UpdateStat(girl, STAT_PCFEAR, 5);
		g_Girls.UpdateStat(girl, STAT_HAPPINESS, -20);
	}
	else
	{
		g_Girls.UpdateStat(girl, STAT_CONFIDENCE, -5);
		g_Girls.UpdateStat(girl, STAT_OBEDIENCE, 5);
		g_Girls.UpdateStat(girl, STAT_SPIRIT, -10);
		g_Girls.UpdateStat(girl, STAT_PCHATE, 30);
		g_Girls.UpdateStat(girl, STAT_PCLOVE, -30);
		g_Girls.UpdateStat(girl, STAT_PCFEAR, 10);
		g_Girls.UpdateStat(girl, STAT_HAPPINESS, -50);
	}
	/*
	*	and queue the message again
	*/
	g_MessageQue.AddToQue(message, 0);
	g_InitWin = true;
	return;
}
Example #3
0
void cScreenTown::check_farm(int FarmNum)
{	// player clicked on one of the brothels
	if (g_Farm.GetNumBrothels() == FarmNum)
	{	// player doesn't own this Studio... can he buy it? 
		static_brothel_data *bck = farm_data + FarmNum;
		locale syslocale("");
		stringstream ss;
		ss.imbue(syslocale);

		if (!g_Gold.afford(bck->price) || g_Gangs.GetNumBusinessExtorted() < bck->business)
		{	// can't buy it
			ss << gettext("This building costs ") << bck->price << gettext(" gold and you need to control at least ") << bck->business << gettext(" businesses.");
			if (!g_Gold.afford(bck->price))
				ss << "\n" << gettext("You need ") << (bck->price - g_Gold.ival()) << gettext(" more gold to afford it.");
			if (g_Gangs.GetNumBusinessExtorted() < bck->business)
				ss << "\n" << gettext("You need to control ") << (bck->business - g_Gangs.GetNumBusinessExtorted()) << gettext(" more businesses.");
			g_MessageQue.AddToQue(ss.str(), 0);
		}
		else
		{	// can buy it
			ss << gettext("Do you wish to purchase this building for ") << bck->price << gettext(" gold? It has ") << bck->rooms << gettext(" rooms.");
			g_MessageQue.AddToQue(ss.str(), 2);
			g_ChoiceManager.CreateChoiceBox(224, 112, 352, 384, 0, 2, 32, 8);
			g_ChoiceManager.AddChoice(0, gettext("Buy It"), 0);
			g_ChoiceManager.AddChoice(0, gettext("Don't Buy It"), 1);
			g_ChoiceManager.SetActive(0);
			BuyFarm = FarmNum;
		}
	}
	else
	{	// player owns this brothel... go to it
		g_Building = BUILDING_FARM;
		g_CurrFarm = FarmNum;
		g_WinManager.push("Farm Screen");
	}
}
Example #4
0
// Run the shifts
void cCentreManager::UpdateGirls(sBrothel* brothel, bool Day0Night1)	// Start_Building_Process_B
{
	
	stringstream ss;
	string summary, girlName;

	u_int restjob = JOB_CENTREREST;
	u_int matronjob = JOB_CENTREMANAGER;
	u_int firstjob = JOB_CENTREREST;
	u_int lastjob = JOB_THERAPY;
	u_int sw = 0, psw = 0;

	int totalPay = 0, totalTips = 0, totalGold = 0;
	int sum = EVENT_SUMMARY;
	int numgirls = GetNumGirls(brothel->m_id);

	bool matron = false, matrondone = false;
	bool counselor = false;

	bool refused = false;

	m_Processing_Shift = Day0Night1;		// WD:	Set processing flag to shift type

	//////////////////////////////////////////////////////
	//  Handle the start of shift stuff for all girls.  //
	//////////////////////////////////////////////////////
	sGirl* current = brothel->m_Girls;
	while (current)
	{
		if (current->health() <= 0)		// skip dead girls
		{
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		else
		{
			g_Girls.UseItems(current);				// Girl uses items she has
			g_Girls.CalculateGirlType(current);		// update the fetish traits
			g_Girls.CalculateAskPrice(current, true);	// Calculate the girls asking price

			current = current->m_Next; // Next Girl
		}
	}


	////////////////////////////////////////////////////////
	//  Process Matron first incase she refuses to work.  //
	////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && !matrondone)
	{
		if (current->health() <= 0 ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) > 0 && (current->m_DayJob != matronjob || current->m_NightJob != matronjob)) ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1 && (current->m_PrevDayJob != matronjob || current->m_PrevNightJob != matronjob)))
		{	// Sanity check! Don't process dead girls and only process those with matron jobs
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` so someone is or was a matron

		girlName = current->m_Realname;
		// if there is no matron on duty, we see who was on duty previously
		if (GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1)
		{
			// if a matron was found and she is healthy, not tired and not on maternity leave... send her back to work
			if ((current->m_PrevDayJob == matronjob || current->m_PrevNightJob == matronjob) &&
				(g_Girls.GetStat(current, STAT_HEALTH) >= 50 && g_Girls.GetStat(current, STAT_TIREDNESS) <= 50) &&
				current->m_PregCooldown < cfg.pregnancy.cool_down())
				// Matron job is more important so she will go back to work at 50% instead of regular 80% health and 20% tired
			{
				current->m_DayJob = current->m_NightJob = matronjob;
				current->m_PrevDayJob = current->m_PrevNightJob = 255;
				current->m_Events.AddMessage("The Centre Manager puts herself back to work.", IMGTYPE_PROFILE, EVENT_BACKTOWORK);
			}
			else if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` Now we have a matron so lets see if she will work

		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// `J` she can refuse the first shift then decide to work the second shift 
		if (!current->m_Refused_To_Work_Day && Day0Night1 == SHIFT_NIGHT)	// but if she worked the first shift she continues the rest of the night
		{
			matron = true;
			ss << girlName << " continued to help the other girls throughout the night.";
		}
		else if (g_Girls.DisobeyCheck(current, ACTION_WORKMATRON, brothel))
		{
			(Day0Night1 ? current->m_Refused_To_Work_Night = true : current->m_Refused_To_Work_Day = true);
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work as the Centre Manager.";
			sum = EVENT_NOWORK;
		}
		else	// so there is less chance of a matron refusing the entire turn
		{
			matron = true;
			totalPay = totalTips = totalGold = 0;
			m_JobManager.JobFunc[matronjob](current, brothel, Day0Night1, summary);
			totalGold += current->m_Pay + current->m_Tips;

			// She does not get paid for the first shift and gets docked some pay from the second shift if she refused once
			if (Day0Night1 == SHIFT_NIGHT) totalGold /= 3;

			current->m_Pay += max(0, totalGold);
			current->m_Pay = current->m_Tips = 0;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
			/* */if (totalGold > 0)		{ ss << girlName << " earned a total of " << totalGold << " gold directly from you. She gets to keep it all."; }
			else if (totalGold == 0)	{ ss << girlName << " made no money."; }
			else if (totalGold < 0)		{ sum = EVENT_DEBUG; ss << "ERROR: She has a loss of " << totalGold << " gold\n\n Please report this to the Pink Petal Devloment Team at http://pinkpetal.org"; }
		}
		current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;	// Next Girl
		matrondone = true;			// there can be only one matron so this ends the while loop
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  Now If there is a matron and she is not refusing to work, then she can delegate the girls in this building.  //
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw != restjob)
		{	// skip dead girls and anyone not resting
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->m_PregCooldown == cfg.pregnancy.cool_down())
		{
			ss << girlName << " is on maternity leave.";
		}
		else if (current->health() < 80 || current->tiredness() > 20)
		{
			m_JobManager.JobFunc[restjob](current, brothel, Day0Night1, summary);
		}
		else
		{	// if she is healthy enough to go back to work... 
			if (matron)	// and there is a marton working...
			{
				psw = (Day0Night1 ? current->m_PrevNightJob : current->m_PrevDayJob);
				if (psw == JOB_COUNSELOR && current->is_free())
				{
					current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
					ss << "The Centre Manager puts " << girlName << " back to work.\n";
				}
				else if (psw == JOB_REHAB)
				{
					current->m_DayJob = current->m_NightJob = psw;
					ss << "The Centre Manager puts " << girlName << " back into Rehab.\n";
				}
				else if (psw == JOB_ANGER || psw == JOB_EXTHERAPY || psw == JOB_THERAPY)
				{
					current->m_DayJob = current->m_NightJob = psw;
					ss << "The Centre Manager puts " << girlName << " back into Therapy.\n";
				}
				else if (psw != restjob && psw != 255 && psw != JOB_COUNSELOR)
				{	// if she had a previous job, put her back to work.
					if (Day0Night1 == SHIFT_DAY)
					{
						current->m_DayJob = current->m_PrevDayJob;
						if (current->m_NightJob == restjob && current->m_PrevNightJob != restjob && current->m_PrevNightJob != 255)
							current->m_NightJob = current->m_PrevNightJob;
					}
					else
					{
						if (current->m_DayJob == restjob && current->m_PrevDayJob != restjob && current->m_PrevDayJob != 255)
							current->m_DayJob = current->m_PrevDayJob;
						current->m_NightJob = current->m_PrevNightJob;
					}
					ss << "The Centre Manager puts " << girlName << " back to work.\n";
				}
				else if (current->m_DayJob == restjob && current->m_NightJob == restjob)
				{	// if they have no job at all, assign them a job
					ss << "The Centre Manager assigns " << girlName << " to ";
					// first send any addicts to rehab
					if (current->is_addict())
					{
						current->m_DayJob = current->m_NightJob = JOB_REHAB;
						ss << "go to Rehab.";
					}
					// Make sure there is at least 1 counselor on duty
					else if (current->is_free() && GetNumGirlsOnJob(0, JOB_COUNSELOR, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
						ss << "work as a Counselor.";
					}
					// assign 1 cleaner per 20 girls
					else if (GetNumGirlsOnJob(0, JOB_CLEANCENTRE, Day0Night1) < max(1,numgirls/20))
					{
						current->m_DayJob = current->m_NightJob = JOB_CLEANCENTRE;
						ss << "clean the Centre.";
					}
					// assign 1 counselor per 20 girls
					else if (current->is_free() && GetNumGirlsOnJob(0, JOB_COUNSELOR, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
						ss << "work as a Counselor.";
					}
					// split all the rest between JOB_COMUNITYSERVICE and JOB_FEEDPOOR
					else if (GetNumGirlsOnJob(0, JOB_COMUNITYSERVICE, Day0Night1) < GetNumGirlsOnJob(0, JOB_FEEDPOOR, Day0Night1))
					{
						current->m_DayJob = current->m_NightJob = JOB_COMUNITYSERVICE;
						ss << "work doing comunity service.";
					}
					else
					{
						current->m_DayJob = current->m_NightJob = JOB_FEEDPOOR;
						ss << "work feeding the poor.";
					}
				}
				current->m_PrevDayJob = current->m_PrevNightJob = 255;
				sum = EVENT_BACKTOWORK;
			}
			else	// no one to send her back to work
			{
				ss << "WARNING " << girlName << " is doing nothing!\n";
				sum = EVENT_WARNING;
			}
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;
	}

	//////////////////////////////////////////////////////////
	//  JOB_COUNSELOR needs to be checked before all others //
	//////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw != JOB_COUNSELOR)
		{	// skip dead girls and anyone who is not a counselor
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;
		
		if (g_Girls.DisobeyCheck(current, ACTION_WORKCOUNSELOR, brothel))
		{
			(Day0Night1 ? current->m_Refused_To_Work_Night = true : current->m_Refused_To_Work_Day = true);
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work so made no money.";
		}
		else
		{
			counselor = true;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}

	/////////////////////////////////////////////////////////////////////////////////
	//  Anyone not in the Therapy Cantre can be assigned to counselor if need be.  //
	/////////////////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && matron && !counselor && GetNumberPatients(Day0Night1) > 0)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || (sw != JOB_FEEDPOOR && sw != JOB_COMUNITYSERVICE && sw != JOB_CLEANCENTRE))
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKCOUNSELOR, brothel))
		{
			counselor = true;
			ss << "There was no Counselor available to work so " << girlName << " was assigned to do it.";
			current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}

	/////////////////////////////////////////////////////////////////////////////
	//  Anyone in the Therapy Cantre can be assigned to counselor if need be.  //
	//  Try them in order of who can better go without their therapy.          //
	/////////////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && matron && !counselor && GetNumberPatients(Day0Night1) > 0)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw != JOB_THERAPY)
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKCOUNSELOR, brothel))
		{
			counselor = true;
			ss << "There was no Counselor available to work so " << girlName << " was assigned to do it.";
			current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}
	current = brothel->m_Girls;
	while (current && matron && !counselor && GetNumberPatients(Day0Night1) > 0)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || (sw != JOB_ANGER && sw != JOB_EXTHERAPY))
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKCOUNSELOR, brothel))
		{
			counselor = true;
			ss << "There was no Counselor available to work so " << girlName << " was assigned to do it.";
			current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}
	current = brothel->m_Girls;
	while (current && matron && !counselor && GetNumberPatients(Day0Night1) > 0)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw != JOB_REHAB)
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKCOUNSELOR, brothel))
		{
			counselor = true;
			ss << "There was no Counselor available to work so " << girlName << " was assigned to do it.";
			current->m_DayJob = current->m_NightJob = JOB_COUNSELOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}
	
	/////////////////////////////////////
	//  Do all the Centre staff jobs.  //
	/////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || (sw != JOB_FEEDPOOR && sw != JOB_COMUNITYSERVICE && sw != JOB_CLEANCENTRE && sw != JOB_COUNSELOR) ||
			// skip dead girls and anyone who is not staff
			(sw == JOB_COUNSELOR && ((Day0Night1 == SHIFT_DAY && current->m_Refused_To_Work_Day) || (Day0Night1 == SHIFT_NIGHT && current->m_Refused_To_Work_Night))))
		{	// and skip counselors who refused to work in the first check
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->m_NightJob == JOB_COUNSELOR) summary = "SkipDisobey";
		// do their job
		refused = m_JobManager.JobFunc[sw](current, brothel, Day0Night1, summary);

		totalPay += current->m_Pay;
		totalTips += current->m_Tips;
		totalGold += current->m_Pay + current->m_Tips;
		g_Brothels.CalculatePay(brothel, current, sw);

		//		Summary Messages
		if (refused)
		{
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work so made no money.";
		}
		else
		{
			ss << m_JobManager.GirlPaymentText(brothel, current, totalTips, totalPay, totalGold, Day0Night1);
			if (totalGold < 0) sum = EVENT_DEBUG;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}


	////////////////////////////////////////////////////////////////////
	//  Do Rehab and therapy last if there is a counselor available.  //
	////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || (sw != JOB_REHAB && sw != JOB_ANGER && sw != JOB_EXTHERAPY && sw != JOB_THERAPY))
		{	// skip dead girls, resting girls and the matron
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		summary = "";
		m_JobManager.JobFunc[sw](current, brothel, Day0Night1, summary);

		current = current->m_Next; // Next Girl
	}

	///////////////////////////////////
	//  Finaly do end of day stuff.  //
	///////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		if (current->health() <= 0)
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		girlName = current->m_Realname;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// update for girls items that are not used up
		do_daily_items(brothel, current);					// `J` added

		// Level the girl up if nessessary
		g_Girls.LevelUp(current);
		// Natural healing, 2% health and 2% tiredness per day
		g_Girls.UpdateStat(current, STAT_HEALTH, 2, false);
		g_Girls.UpdateStat(current, STAT_TIREDNESS, -2, false);


		if (g_Girls.GetStat(current, STAT_HAPPINESS) < 40)
		{
			if (current->m_NightJob != matronjob && matron && brothel->m_NumGirls > 1 && g_Dice.percent(70))
			{
				ss << "The Centre Manager helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 5);
			}
			else if (brothel->m_NumGirls > 10 && g_Dice.percent(50))
			{
				ss << "Some of the other girls help cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 8 + 3);
			}
			else if (brothel->m_NumGirls > 1 && g_Dice.percent(max(brothel->m_NumGirls, 50)))
			{
				ss << "One of the other girls helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 6 + 2);
			}
			else if (brothel->m_NumGirls == 1 && g_Dice.percent(70))
			{
				ss << girlName << " plays around in the empty building until she feels better.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 10);
			}
			else if (g_Girls.GetStat(current, STAT_HAPPINESS) < 20) // no one helps her and she is really unhappy
			{
				ss << girlName << " is looking very depressed. You may want to do something about that before she does something drastic.\n";
				sum = EVENT_WARNING;
			}
		}

		if (g_Girls.GetStat(current, STAT_TIREDNESS) > 80 || g_Girls.GetStat(current, STAT_HEALTH) < 40)
		{
			int t = g_Girls.GetStat(current, STAT_TIREDNESS);
			int h = g_Girls.GetStat(current, STAT_HEALTH);

			if (current->m_WorkingDay > 0)
			{
				ss << girlName << " is not faring well in rehab.\n";
			}
			else if (!matron)	// do no matron first as it is the easiest
			{
				ss << "WARNING! " << girlName;
				if (t > 80 && h < 20)		ss << " is in real bad shape, she is tired and injured.\nShe should go to the Clinic.\n";
				else if (t > 80 && h < 40)	ss << " is in bad shape, she is tired and injured.\nShe should rest or she may die!\n";
				else if (t > 80)			ss << " is desparatly in need of rest.\nGive her some free time\n";
				else if (h < 20)			ss << " is badly injured.\nShe should rest or go to the Clinic.\n";
				else if (h < 40)			ss << " is hurt.\nShe should rest and recuperate.\n";
			}
			else if (current->m_NightJob == matronjob && matron)	// do matron	
			{
				if (t > 90 && h < 10)	// The matron may take herself off work if she is really bad off
				{
					current->m_PrevDayJob = current->m_DayJob;
					current->m_PrevNightJob = current->m_NightJob;
					current->m_DayJob = current->m_NightJob = restjob;
					ss << "The Centre Manager takes herself off duty because she is just too damn sore.\n";
					g_Girls.UpdateEnjoyment(current, ACTION_WORKMATRON, -10);
				}
				else
				{
					ss << "As Centre Manager, " << girlName << " has the keys to the store room.\nShe used them to 'borrow' ";
					if (t > 80 && h < 40)
					{
						ss << "some potions";
						g_Gold.consumable_cost(20, true);
						current->m_Stats[STAT_HEALTH] = min(current->m_Stats[STAT_HEALTH] + 20, 100);
						current->m_Stats[STAT_TIREDNESS] = max(current->m_Stats[STAT_TIREDNESS] - 20, 0);
					}
					else if (t > 80)
					{
						ss << "a resting potion";
						g_Gold.consumable_cost(10, true);
						current->m_Stats[STAT_TIREDNESS] = max(current->m_Stats[STAT_TIREDNESS] - 20, 0);
					}
					else if (h < 40)
					{
						ss << "a healing potion";
						g_Gold.consumable_cost(10, true);
						current->m_Stats[STAT_HEALTH] = min(current->m_Stats[STAT_HEALTH] + 20, 100);
					}
					ss << " for herself.\n";
				}
			}
			else	// do all other girls with a matron working
			{
				if (current->m_PrevNightJob == 255 && current->m_PrevDayJob == 255) // the girl has been working
				{
					current->m_PrevDayJob = current->m_DayJob;
					current->m_PrevNightJob = current->m_NightJob;
					current->m_DayJob = current->m_NightJob = restjob;
					ss << "The Centre Manager takes " << girlName << " off duty to rest due to her ";
					if (t > 80 && h < 40)	ss << "exhaustion.\n";
					else if (t > 80)		ss << "tiredness.\n";
					else if (h < 40)		ss << "low health.\n";
					else /*       */		ss << "current state.\n";
				}
				else	// the girl has already been taken off duty by the matron
				{
					if (g_Dice.percent(70))
					{
						ss << "The Centre Manager helps ";
						if (t > 80 && h < 40)
						{
							ss << girlName << " recuperate.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 4 + 2));
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 4 + 2));
						}
						else if (t > 80)
						{
							ss << girlName << " to relax.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 5 + 5));
						}
						else if (h < 40)
						{
							ss << "heal " << girlName << ".\n";
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 5 + 5));
						}
					}
				}
			}
		}

		if (ss.str().length() > 0)	current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;		// Process next girl
	}

	m_Processing_Shift = -1;	// WD: Finished Processing Shift set flag
}
Example #5
0
// ----- Update & end of turn
void cCentreManager::UpdateCentre()	// Start_Building_Process_A
{
	cTariff tariff;
	stringstream ss;
	string girlName;

	sBrothel* current = (sBrothel*)m_Parent;
	u_int restjob = JOB_CENTREREST;
	u_int matronjob = JOB_CENTREMANAGER;
	u_int firstjob = JOB_CENTREREST;
	u_int lastjob = JOB_THERAPY;

	current->m_Finance.zero();
	current->m_AntiPregUsed = 0;
	m_Rehab_Patient_Time = 0;

	sGirl* cgirl = current->m_Girls;
	while (cgirl)
	{
		current->m_Filthiness++;
		if (cgirl->health() <= 0)			// Remove any dead bodies from last week
		{
			current->m_Filthiness++; // `J` Death is messy
			sGirl* DeadGirl = 0;
			girlName = cgirl->m_Realname;
			DeadGirl = cgirl;
			// If there are more girls to process
			cgirl = (cgirl->m_Next) ? cgirl->m_Next : 0;
			// increase all the girls fear and hate of the player for letting her die (weather his fault or not)
			UpdateAllGirlsStat(current, STAT_PCFEAR, 2);
			UpdateAllGirlsStat(current, STAT_PCHATE, 1);

			ss.str(""); ss << girlName << " has died from her injuries, the other girls all fear and hate you a little more.";
			DeadGirl->m_Events.AddMessage(ss.str(), IMGTYPE_DEATH, EVENT_DANGER);
			g_MessageQue.AddToQue(ss.str(), COLOR_RED);
			ss.str(""); ss << girlName << " has died from her injuries.  Her body will be removed by the end of the week.";
			DeadGirl->m_Events.AddMessage(ss.str(), IMGTYPE_DEATH, EVENT_SUMMARY);

			RemoveGirl(0, DeadGirl); DeadGirl = 0;	// cleanup
		}
		else
		{
			cgirl->m_Events.Clear();			// Clear the girls' events from the last turn
			cgirl->where_is_she = 0;
			cgirl->m_InStudio = false;
			cgirl->m_InArena = false;
			cgirl->m_InCentre = true;
			cgirl->m_InClinic = false;
			cgirl->m_InFarm = false;
			cgirl->m_InHouse = false;

			cgirl->m_Pay = cgirl->m_Tips = 0;

			// `J` Check for out of building jobs and set yesterday jobs for everyone first
			if (cgirl->m_DayJob	  < firstjob || cgirl->m_DayJob   > lastjob)	cgirl->m_DayJob = restjob;
			if (cgirl->m_NightJob < firstjob || cgirl->m_NightJob > lastjob)	cgirl->m_NightJob = restjob;
			if (cgirl->m_PrevDayJob != 255 && (cgirl->m_PrevDayJob	 < firstjob || cgirl->m_PrevDayJob   > lastjob))	cgirl->m_PrevDayJob = 255;
			if (cgirl->m_PrevNightJob != 255 && (cgirl->m_PrevNightJob < firstjob || cgirl->m_PrevNightJob > lastjob))	cgirl->m_PrevNightJob = 255;
			cgirl->m_YesterDayJob = cgirl->m_DayJob;		// `J` set what she did yesterday
			cgirl->m_YesterNightJob = cgirl->m_NightJob;	// `J` set what she did yesternight
			cgirl->m_Refused_To_Work_Day = cgirl->m_Refused_To_Work_Night = false;
			string summary = "";

			g_Girls.AddTiredness(cgirl);			// `J` moved all girls add tiredness to one place
			do_food_and_digs(current, cgirl);		// Brothel only update for girls accommodation level
			g_Girls.updateGirlAge(cgirl, true);		// update birthday counter and age the girl
			g_Girls.HandleChildren(cgirl, summary);	// handle pregnancy and children growing up
			g_Girls.updateSTD(cgirl);				// health loss to STD's				NOTE: Girl can die
			g_Girls.updateHappyTraits(cgirl);		// Update happiness due to Traits	NOTE: Girl can die
			updateGirlTurnBrothelStats(cgirl);		// Update daily stats				Now only runs once per day
			g_Girls.updateGirlTurnStats(cgirl);		// Stat Code common to Dugeon and Brothel

			if (cgirl->m_JustGaveBirth)				// if she gave birth, let her rest this week
			{
				if (cgirl->m_DayJob != restjob)		cgirl->m_PrevDayJob = cgirl->m_DayJob;
				if (cgirl->m_NightJob != restjob)	cgirl->m_PrevNightJob = cgirl->m_NightJob;
				cgirl->m_DayJob = cgirl->m_NightJob = restjob;
			}

			cgirl = cgirl->m_Next;
		}
	}

	UpdateGirls(current, 0);	// Run the Day Shift

	UpdateGirls(current, 1);	// Run the Nighty Shift

	if (current->m_Filthiness < 0)		current->m_Filthiness = 0;
	if (current->m_SecurityLevel < 0)	current->m_SecurityLevel = 0;

	g_Gold.brothel_accounts(current->m_Finance, current->m_id);

	cgirl = current->m_Girls;
	while (cgirl)
	{
		g_Girls.updateTemp(cgirl);			// update temp stuff
		g_Girls.EndDayGirls(current, cgirl);
		cgirl = cgirl->m_Next;
	}
}
Example #6
0
// Run the shifts
void cArenaManager::UpdateGirls(sBrothel* brothel, bool Day0Night1)	// Start_Building_Process_B
{
	stringstream ss;
	string summary, girlName;

	u_int sw = 0, psw = 0;

	int totalPay = 0, totalTips = 0, totalGold = 0;
	int sum = EVENT_SUMMARY;
	int numgirls = GetNumGirls(brothel->m_id);

	bool matron = false, matrondone = false;
	
	
	bool refused = false;

	m_Processing_Shift = Day0Night1;		// WD:	Set processing flag to shift type

	//////////////////////////////////////////////////////
	//  Handle the start of shift stuff for all girls.  //
	//////////////////////////////////////////////////////
	sGirl* current = brothel->m_Girls;
	while (current)
	{
		if (current->health() <= 0)		// skip dead girls
		{
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		else
		{
			g_Girls.UseItems(current);					// Girl uses items she has
			g_Girls.CalculateGirlType(current);			// update the fetish traits
			g_Girls.CalculateAskPrice(current, true);	// Calculate the girls asking price

			current = current->m_Next; // Next Girl
		}
	}


	////////////////////////////////////////////////////////
	//  Process Matron first incase she refuses to work.  //
	////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && !matrondone)
	{
		if (current->health() <= 0 ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) > 0 && (current->m_DayJob != matronjob || current->m_NightJob != matronjob)) ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1 && (current->m_PrevDayJob != matronjob || current->m_PrevNightJob != matronjob)))
		{	// Sanity check! Don't process dead girls and only process those with matron jobs
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` so someone is or was a matron

		girlName = current->m_Realname;
		// if there is no matron on duty, we see who was on duty previously
		if (GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1)
		{
			// if a matron was found and she is healthy, not tired and not on maternity leave... send her back to work
			if ((current->m_PrevDayJob == matronjob || current->m_PrevNightJob == matronjob) &&
				(g_Girls.GetStat(current, STAT_HEALTH) >= 50 && g_Girls.GetStat(current, STAT_TIREDNESS) <= 50) &&
				current->m_PregCooldown < cfg.pregnancy.cool_down())
				// Matron job is more important so she will go back to work at 50% instead of regular 80% health and 20% tired
			{
				current->m_DayJob = current->m_NightJob = matronjob;
				current->m_PrevDayJob = current->m_PrevNightJob = 255;
				current->m_Events.AddMessage("The Doctore puts herself back to work.", IMGTYPE_PROFILE, EVENT_BACKTOWORK);
			}
			else if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` Now we have a matron so lets see if she will work

		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// `J` she can refuse the first shift then decide to work the second shift 
		if (!current->m_Refused_To_Work_Day && Day0Night1 == SHIFT_NIGHT)	// but if she worked the first shift she continues the rest of the night
		{
			matron = true;
			ss << girlName << " continued to help the other girls throughout the night.";
		}
		else if (g_Girls.DisobeyCheck(current, ACTION_WORKMATRON, brothel))
		{
			(Day0Night1 ? current->m_Refused_To_Work_Night = true : current->m_Refused_To_Work_Day = true);
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work as the Doctore.";
			sum = EVENT_NOWORK;
		}
		else	// so there is less chance of a matron refusing the entire turn
		{
			matron = true;
			totalPay = totalTips = totalGold = 0;
			m_JobManager.JobFunc[matronjob](current, brothel, Day0Night1, summary);
			totalGold += current->m_Pay + current->m_Tips;

			// She does not get paid for the first shift and gets docked some pay from the second shift if she refused once
			if (Day0Night1 == SHIFT_NIGHT) totalGold /= 3;

			current->m_Pay += max(0, totalGold);
			current->m_Pay = current->m_Tips = 0;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
			/* */if (totalGold > 0)		{ ss << girlName << " earned a total of " << totalGold << " gold directly from you. She gets to keep it all."; }
			else if (totalGold == 0)	{ ss << girlName << " made no money."; }
			else if (totalGold < 0)		{ sum = EVENT_DEBUG; ss << "ERROR: She has a loss of " << totalGold << " gold\n\n Please report this to the Pink Petal Devloment Team at http://pinkpetal.org"; }
		}
		current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;	// Next Girl
		matrondone = true;			// there can be only one matron so this ends the while loop
	}

	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  Now If there is a matron and she is not refusing to work, then she can delegate the girls in this building.  //
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw != restjob)
		{	// skip dead girls and anyone not resting
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->m_PregCooldown == cfg.pregnancy.cool_down())
		{
			ss << girlName << " is on maternity leave.";
		}
		else if (current->health() < 80 || current->tiredness() > 20)
		{
			m_JobManager.JobFunc[restjob](current, brothel, Day0Night1, summary);
		}
		else
		{	// if she is healthy enough to go back to work... 
			if (matron)	// and there is a marton working...
			{
				psw = (Day0Night1 ? current->m_PrevNightJob : current->m_PrevDayJob);
				if (psw != restjob && psw != 255)
				{	// if she had a previous job, put her back to work.
					if (Day0Night1 == SHIFT_DAY)
					{
						current->m_DayJob = current->m_PrevDayJob;
						if (current->m_NightJob == restjob && current->m_PrevNightJob != restjob && current->m_PrevNightJob != 255)
							current->m_NightJob = current->m_PrevNightJob;
					}
					else
					{
						if (current->m_DayJob == restjob && current->m_PrevDayJob != restjob && current->m_PrevDayJob != 255)
							current->m_DayJob = current->m_PrevDayJob;
						current->m_NightJob = current->m_PrevNightJob;
					}
					ss << "The Doctore puts " << girlName << " back to work.\n";
				}
				else if (current->m_DayJob == restjob && current->m_NightJob == restjob)
				{	// if they have no job at all, assign them a job
					ss << "The Doctore assigns " << girlName << " to ";

					// need at least 1 guard and 1 cleaner (because guards must be free, they get assigned first)
					if (current->is_free() && GetNumGirlsOnJob(0, JOB_CITYGUARD, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_CITYGUARD;
						ss << "work helping the city guard.";
					}
					else if (GetNumGirlsOnJob(0, JOB_CLEANARENA, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_CLEANARENA;
						ss << "work cleaning the arena.";
					}
					else if (GetNumGirlsOnJob(0, JOB_BLACKSMITH, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_BLACKSMITH;
						ss << "work making weapons and armor.";
					}
					else if (GetNumGirlsOnJob(0, JOB_COBBLER, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_COBBLER;
						ss << "work making shoes and leather items.";
					}
					else if (GetNumGirlsOnJob(0, JOB_JEWELER, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_JEWELER;
						ss << "work making jewelery.";
					}

					// next assign more guards and cleaners if there are a lot of girls to choose from
					else if (current->is_free() && GetNumGirlsOnJob(0, JOB_CITYGUARD, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_CITYGUARD;
						ss << "work helping the city guard.";
					}
					else if (GetNumGirlsOnJob(0, JOB_CLEANARENA, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_CLEANARENA;
						ss << "work cleaning the arena.";
					}
					else if (GetNumGirlsOnJob(0, JOB_BLACKSMITH, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_BLACKSMITH;
						ss << "work making weapons and armor.";
					}
					else if (GetNumGirlsOnJob(0, JOB_COBBLER, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_COBBLER;
						ss << "work making shoes and leather items.";
					}
					else if (GetNumGirlsOnJob(0, JOB_JEWELER, Day0Night1) < numgirls / 20)
					{
						current->m_DayJob = current->m_NightJob = JOB_JEWELER;
						ss << "work making jewelery.";
					}

					// Assign fighters - 50+ combat

					/*	Only fight beasts if there are 10 or more available
					*		and 1 girl per 10 beasts so they don't get depleted too fast.
					*	You can manually assign more if you want but I prefer to save beasts for the brothel
					*		until each building has their own beast supply.
					*	The farm will supply them when more work gets done to it
					*/
					else if (current->combat() > 60 && g_Brothels.GetNumBeasts() >= 10 &&
						GetNumGirlsOnJob(0, JOB_FIGHTBEASTS, Day0Night1) < g_Brothels.GetNumBeasts() / 10)
					{
						current->m_DayJob = current->m_NightJob = JOB_FIGHTBEASTS;
						ss << "work fighting beast in the arena.";
					}
					// if there are not enough beasts, have the girls fight other girls
					else if (current->combat() > 60 && GetNumGirlsOnJob(0, JOB_FIGHTARENAGIRLS, Day0Night1) < 1)
					{
						current->m_DayJob = current->m_NightJob = JOB_FIGHTARENAGIRLS;
						ss << "work fighting other girls in the arena.";
					}

					else	// assign anyone else to Traning
					{
						current->m_DayJob = current->m_NightJob = JOB_FIGHTTRAIN;
						ss << "train for the arena.";
					}
				}
				current->m_PrevDayJob = current->m_PrevNightJob = 255;
				sum = EVENT_BACKTOWORK;
			}
			else	// no one to send her back to work
			{
				ss << "WARNING " << girlName << " is doing nothing!\n";
				sum = EVENT_WARNING;
			}
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;
	}

	///////////////////////////////////////////////////////////
	//  All Jobs in the Arena can be done at the same time.  //
	///////////////////////////////////////////////////////////
	/* `J` zzzzzz - Need to split up the jobs
	Done - JOB_ARENAREST, JOB_DOCTORE

	JOB_CLEANARENA

	JOB_FIGHTBEASTS
	JOB_FIGHTARENAGIRLS
	JOB_FIGHTTRAIN
	JOB_CITYGUARD


	//*/
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->health() <= 0 || sw == restjob || sw == matronjob)
		{	// skip dead girls, resting girls and the matron
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		// fight beasts so if there is no beasts dont want them doing nothing
		if (sw == JOB_FIGHTBEASTS && g_Brothels.GetNumBeasts() < 1)
		{
			stringstream ssc;
			ssc << "There are no beasts to fight so " << girlName << " was sent to ";

			if (current->health() < 50)
			{
				ssc << "rest and heal";
				sw = restjob;
			}
			else if (current->combat() > 90 && current->magic() > 90 && current->agility() > 90 && current->constitution() > 90 && current->health() > 90)
			{
				ssc << "fight other girls";
				sw = JOB_FIGHTARENAGIRLS;
			}
			else
			{
				ssc << "train for combat";
				sw = JOB_FIGHTTRAIN;
			}
			ssc << " instead.\n\n";
			current->m_Events.AddMessage(ssc.str(), IMGTYPE_PROFILE, Day0Night1);

		}

		// do their job
		refused = m_JobManager.JobFunc[sw](current, brothel, Day0Night1, summary);

		totalPay += current->m_Pay;
		totalTips += current->m_Tips;
		totalGold += current->m_Pay + current->m_Tips;
		g_Brothels.CalculatePay(brothel, current, sw);

		//		Summary Messages
		if (refused)
		{
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work so made no money.";
		}
		else
		{
			ss << m_JobManager.GirlPaymentText(brothel, current, totalTips, totalPay, totalGold, Day0Night1);
			if (totalGold < 0) sum = EVENT_DEBUG;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}

	///////////////////////////////////
	//  Finaly do end of day stuff.  //
	///////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		if (current->health() <= 0)
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		girlName = current->m_Realname;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// update for girls items that are not used up
		do_daily_items(brothel, current);					// `J` added

		// Level the girl up if nessessary
		g_Girls.LevelUp(current);
		// Natural healing, 2% health and 2% tiredness per day
		g_Girls.UpdateStat(current, STAT_HEALTH, 2, false);
		g_Girls.UpdateStat(current, STAT_TIREDNESS, -2, false);


		if (g_Girls.GetStat(current, STAT_HAPPINESS) < 40)
		{
			if (current->m_NightJob != matronjob && matron && brothel->m_NumGirls > 1 && g_Dice.percent(70))
			{
				ss << "The Doctore helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 5);
			}
			else if (brothel->m_NumGirls > 10 && g_Dice.percent(50))
			{
				ss << "Some of the other girls help cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 8 + 3);
			}
			else if (brothel->m_NumGirls > 1 && g_Dice.percent(max(brothel->m_NumGirls, 50)))
			{
				ss << "One of the other girls helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 6 + 2);
			}
			else if (brothel->m_NumGirls == 1 && g_Dice.percent(70))
			{
				ss << girlName << " plays around in the empty building until she feels better.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 10);
			}
			else if (g_Girls.GetStat(current, STAT_HAPPINESS) < 20) // no one helps her and she is really unhappy
			{
				ss << girlName << " is looking very depressed. You may want to do something about that before she does something drastic.\n";
				sum = EVENT_WARNING;
			}
		}

		if (g_Girls.GetStat(current, STAT_TIREDNESS) > 80 || g_Girls.GetStat(current, STAT_HEALTH) < 40)
		{
			int t = g_Girls.GetStat(current, STAT_TIREDNESS);
			int h = g_Girls.GetStat(current, STAT_HEALTH);

			if (!matron)	// do no matron first as it is the easiest
			{
				ss << "WARNING! " << girlName;
				if (t > 80 && h < 20)		ss << " is in real bad shape, she is tired and injured.\nShe should go to the Clinic.\n";
				else if (t > 80 && h < 40)	ss << " is in bad shape, she is tired and injured.\nShe should rest or she may die!\n";
				else if (t > 80)			ss << " is desparatly in need of rest.\nGive her some free time\n";
				else if (h < 20)			ss << " is badly injured.\nShe should rest or go to the Clinic.\n";
				else if (h < 40)			ss << " is hurt.\nShe should rest and recuperate.\n";
			}
			else if (current->m_NightJob == matronjob && matron)	// do matron	
			{
				if (t > 90 && h < 10)	// The matron may take herself off work if she is really bad off
				{
					current->m_PrevDayJob = current->m_DayJob;
					current->m_PrevNightJob = current->m_NightJob;
					current->m_DayJob = current->m_NightJob = restjob;
					ss << "The Doctore takes herself off duty because she is just too damn sore.\n";
					g_Girls.UpdateEnjoyment(current, ACTION_WORKMATRON, -10);
				}
				else
				{
					ss << "As Doctore, " << girlName << " has the keys to the store room.\nShe used them to 'borrow' ";
					if (t > 80 && h < 40)
					{
						ss << "some potions";
						g_Gold.consumable_cost(20);
						current->m_Stats[STAT_HEALTH] = min(current->m_Stats[STAT_HEALTH] + 20, 100);
						current->m_Stats[STAT_TIREDNESS] = max(current->m_Stats[STAT_TIREDNESS] - 20, 0);
					}
					else if (t > 80)
					{
						ss << "a resting potion";
						g_Gold.consumable_cost(10, true);
						current->m_Stats[STAT_TIREDNESS] = max(current->m_Stats[STAT_TIREDNESS] - 20, 0);
					}
					else if (h < 40)
					{
						ss << "a healing potion";
						g_Gold.consumable_cost(10, true);
						current->m_Stats[STAT_HEALTH] = min(current->m_Stats[STAT_HEALTH] + 20, 100);
					}
					ss << " for herself.\n";
				}
			}
			else	// do all other girls with a matron working
			{
				if (current->m_PrevNightJob == 255 && current->m_PrevDayJob == 255) // the girl has been working
				{
					current->m_PrevDayJob = current->m_DayJob;
					current->m_PrevNightJob = current->m_NightJob;
					current->m_DayJob = current->m_NightJob = restjob;
					ss << "The Doctore takes " << girlName << " off duty to rest due to her ";
					if (t > 80 && h < 40)	ss << "exhaustion.\n";
					else if (t > 80)		ss << "tiredness.\n";
					else if (h < 40)		ss << "low health.\n";
					else /*       */		ss << "current state.\n";
				}
				else	// the girl has already been taken off duty by the matron
				{
					if (g_Dice.percent(70))
					{
						ss << "The Doctore helps ";
						if (t > 80 && h < 40)
						{
							ss << girlName << " recuperate.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 4 + 2));
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 4 + 2));
						}
						else if (t > 80)
						{
							ss << girlName << " to relax.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 5 + 5));
						}
						else if (h < 40)
						{
							ss << " heal " << girlName << ".\n";
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 5 + 5));
						}
					}
				}
			}
		}

		if (ss.str().length() > 0)	current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;		// Process next girl
	}

	m_Processing_Shift = -1;	// WD: Finished Processing Shift set flag
}
void cScreenGangs::check_events()
{
	if (g_InterfaceEvents.GetNumEvents() == 0) return;	// no events means we can go home
	if (g_InterfaceEvents.CheckButton(back_id))			// if it's the back button, pop the window off the stack and we're done
	{
		g_InitWin = true;
		g_WinManager.Pop();
		return;
	}
	if (g_InterfaceEvents.CheckButton(ganghire_id))
	{
		hire_recruitable();
		return;
	}
	if (g_InterfaceEvents.CheckButton(weaponup_id))
	{
		int cost = 0;
		int *wlev = g_Gangs.GetWeaponLevel();
		cost = tariff.goon_weapon_upgrade(*wlev);
		if (g_Gold.item_cost(cost) == true)
		{
			*wlev += 1;
			g_InitWin = true;
		}
		wlev = 0;
		return;
	}

	int buynets = 0;
	if (g_InterfaceEvents.CheckButton(netbuy_id))	buynets = 1;
	if (g_InterfaceEvents.CheckButton(netbuy10_id))	buynets = 10;
	if (g_InterfaceEvents.CheckButton(netbuy20_id))	buynets = 20;
	if (buynets > 0)
	{
		int cost = 0;
		int amount = buynets;
		int *nets = g_Gangs.GetNets();
		if (((*nets) + buynets) > 60) amount = 60 - (*nets);
		cost = tariff.nets_price(amount);
		if (g_Gold.item_cost(cost) == true)
		{
			*nets += amount;
			if (IsCheckboxOn(netautobuy_id)) g_Gangs.KeepNetStocked(*nets);
			g_InitWin = true;
		}
		nets = 0;
		buynets = 0;
		return;
	}

	int buypots = 0;
	if (g_InterfaceEvents.CheckButton(healbuy_id))		buypots = 1;
	if (g_InterfaceEvents.CheckButton(healbuy10_id))	buypots = 10;
	if (g_InterfaceEvents.CheckButton(healbuy20_id))	buypots = 20;
	if (buypots > 0)
	{
		int cost = 0;
		int amount = buypots;
		int *potions = g_Gangs.GetHealingPotions();
		if (((*potions) + buypots) > 200)	amount = 200 - (*potions);
		cost = tariff.healing_price(amount);
		if (g_Gold.item_cost(cost) == true)
		{
			*potions += amount;
			if (IsCheckboxOn(healautobuy_id)) g_Gangs.KeepHealStocked(*potions);
			g_InitWin = true;
		}
		potions = 0;
		buypots = 0;
		return;
	}
	if (g_InterfaceEvents.CheckCheckbox(netautobuy_id))
	{
		int *nets = g_Gangs.GetNets();
		g_Gangs.KeepNetStocked(IsCheckboxOn(netautobuy_id) ? *nets : 0);
	}
	if (g_InterfaceEvents.CheckCheckbox(healautobuy_id))
	{
		int *potions = g_Gangs.GetHealingPotions();
		g_Gangs.KeepHealStocked(IsCheckboxOn(healautobuy_id) ? *potions : 0);
	}
	if (g_InterfaceEvents.CheckButton(gangfire_id))
	{
		selection = GetLastSelectedItemFromList(ganglist_id);
		if (selection != -1)
		{
			g_Gangs.FireGang(selection);
			g_InitWin = true;
		}
		return;
	}
	if (g_InterfaceEvents.CheckListbox(recruitlist_id))
	{
		string ClickedHeader = HeaderClicked(recruitlist_id);
		if (ClickedHeader != "")
		{
			g_LogFile.ss() << "User clicked \"" << ClickedHeader << "\" column header on Recruit listbox" << endl; g_LogFile.ssend();
			return;
		}

		g_LogFile.ss() << "selected recruitable gang changed" << endl; g_LogFile.ssend();
		sel_recruit = GetLastSelectedItemFromList(recruitlist_id);

		if (ListDoubleClicked(recruitlist_id))
		{
			g_LogFile.ss() << "User double-clicked recruitable gang! Hiring if possible." << endl; g_LogFile.ssend();
			hire_recruitable();
			return;
		}
		//		g_InitWin = true;
	}

	// this is what gets called it you change the selected gang
	if (g_InterfaceEvents.CheckListbox(ganglist_id))
	{
		string ClickedHeader = HeaderClicked(ganglist_id);
		if (ClickedHeader != "")
		{
			g_LogFile.ss() << "User clicked \"" << ClickedHeader << "\" column header on Gangs listbox" << endl; g_LogFile.ssend();
			return;
		}

		g_LogFile.write("selected gang changed");
		selection = GetLastSelectedItemFromList(ganglist_id);
		if (selection != -1)
		{
			sGang* gang = g_Gangs.GetGang(selection);
			ss.str(""); ss << "Name: " << gang->m_Name << "\n" << "Number: " << gang->m_Num << "\n" << "Combat: " << gang->m_Skills[SKILL_COMBAT] << "%\n" << "Magic: " << gang->m_Skills[SKILL_MAGIC] << "%\n" << "Intelligence: " << gang->m_Stats[STAT_INTELLIGENCE] << "%\n";
			EditTextItem(ss.str(), gangdesc_id);
			SetSelectedItemInList(missionlist_id, gang->m_MissionID, false);
			set_mission_desc(gang->m_MissionID);		// set the long description for the mission
		}
	}
	if (g_InterfaceEvents.CheckListbox(missionlist_id))
	{
		// get the index into the missions list
		int mission_id = GetLastSelectedItemFromList(missionlist_id);
		g_LogFile.ss() << "selchange: mid = " << mission_id << endl; g_LogFile.ssend();
		set_mission_desc(mission_id);		// set the textfield with the long description and price for this mission
		g_LogFile.ss() << "selection change: rebuilding gang list box" << endl; g_LogFile.ssend();
		for (int selection = multi_first(); selection != -1; selection = multi_next())
		{
			sGang* gang = g_Gangs.GetGang(selection);
			/*
			*				make sure we found the gang - pretty catastrophic
			*				if not, so log it if we do
			*/
			if (gang == 0)
			{
				g_LogFile.ss() << "Error: No gang for index " << selection; g_LogFile.ssend();
				continue;
			}
			/*
			*				if the mission id is -1, nothing else to do
			*				(moving this to before the recruitment check
			*				since -1 most likely means nothing selected in
			*				the missions list)
			*/
			if (mission_id == -1) { continue; }
			/*
			*				if the gang is already doing <whatever>
			*				then let them get on with it
			*/
			if (gang->m_MissionID == u_int(mission_id)) { continue; }
			/*
			*				if they were recruiting, turn off the
			*				auto-recruit flag
			*/
			if (gang->m_MissionID == MISS_RECRUIT && gang->m_AutoRecruit)
			{
				gang->m_AutoRecruit = false;
				gang->m_LastMissID = -1;
			}
			gang->m_MissionID = mission_id;
			/*
			*				format the display line
			*/
			g_InitWin = true;
		}

		int cost = 0;
		if (g_Gangs.GetNumGangs() > 0)
		{
			for (int i = 0; i < g_Gangs.GetNumGangs(); i++)
			{
				sGang* g = g_Gangs.GetGang(i);
				cost += tariff.goon_mission_cost(g->m_MissionID);
			}
		}
		ss.str(""); ss << "Weekly Cost: " << cost;
		EditTextItem(ss.str(), totalcost_id);
		if (gold_id >= 0)
		{
			ss.str(""); ss << "Gold: " << g_Gold.ival();
			EditTextItem(ss.str(), gold_id);
		}

	}

	if (g_InterfaceEvents.CheckCheckbox(controlcatacombs_id))
	{
		g_Gangs.Control_Gangs(IsCheckboxOn(controlcatacombs_id));
	}
	bool dosliders = false;
	if (g_InterfaceEvents.CheckSlider(girlspercslider_id))
	{
		int s1 = SliderValue(girlspercslider_id);
		int s2 = SliderValue(itemspercslider_id);
		if (s2 < s1)
		{
			s2 = s1;
			SliderRange(itemspercslider_id, 0, 100, s2, 1);
		}
		dosliders = true;
	}
	if (g_InterfaceEvents.CheckSlider(itemspercslider_id))
	{
		int s1 = SliderValue(itemspercslider_id);
		int s2 = SliderValue(girlspercslider_id);
		if (s1 < s2)
		{
			s2 = s1;
			SliderRange(girlspercslider_id, 0, 100, s2, 1);
		}
		dosliders = true;
	}
	if (dosliders)
	{
		int s1 = SliderValue(girlspercslider_id);
		int s2 = SliderValue(itemspercslider_id);
		g_Gangs.Gang_Gets_Girls(s1);
		g_Gangs.Gang_Gets_Items(s2 - s1);
		g_Gangs.Gang_Gets_Beast(100 - s2);
		ss.str("");	ss << "Girls : " << g_Gangs.Gang_Gets_Girls() << "%";	EditTextItem(ss.str(), ganggetsgirls_id);
		ss.str("");	ss << "Items : " << g_Gangs.Gang_Gets_Items() << "%";	EditTextItem(ss.str(), ganggetsitems_id);
		ss.str("");	ss << "Beasts : " << g_Gangs.Gang_Gets_Beast() << "%";	EditTextItem(ss.str(), ganggetsbeast_id);
		return;
	}
}
void cScreenGangs::init()
{
	g_CurrentScreen = SCREEN_GANGMANAGEMENT;
	if (!g_InitWin) return;
	Focused();
	g_InitWin = false;

	selection = GetLastSelectedItemFromList(ganglist_id);
	sel_recruit = GetLastSelectedItemFromList(recruitlist_id);

	ClearListBox(missionlist_id);
	AddToListBox(missionlist_id, 0, "GUARDING");
	AddToListBox(missionlist_id, 1, "SABOTAGE");
	AddToListBox(missionlist_id, 2, "SPY ON GIRLS");
	AddToListBox(missionlist_id, 3, "RECAPTURE");
	AddToListBox(missionlist_id, 4, "ACQUIRE TERRITORY");
	AddToListBox(missionlist_id, 5, "PETTY THEFT");
	AddToListBox(missionlist_id, 6, "GRAND THEFT");
	AddToListBox(missionlist_id, 7, "KIDNAPPING");
	AddToListBox(missionlist_id, 8, "CATACOMBS");
	AddToListBox(missionlist_id, 9, "TRAINING");
	AddToListBox(missionlist_id, 10, "RECRUITING");
	AddToListBox(missionlist_id, 11, "SERVICE");

	SetCheckBox(controlcatacombs_id, (g_Gangs.Control_Gangs()));
	SliderRange(girlspercslider_id, 0, 100, g_Gangs.Gang_Gets_Girls(), 1);
	SliderRange(itemspercslider_id, 0, 100, g_Gangs.Gang_Gets_Girls() + g_Gangs.Gang_Gets_Items(), 1);
	ss.str("");	ss << "Girls : " << g_Gangs.Gang_Gets_Girls() << "%";	EditTextItem(ss.str(), ganggetsgirls_id);
	ss.str("");	ss << "Items : " << g_Gangs.Gang_Gets_Items() << "%";	EditTextItem(ss.str(), ganggetsitems_id);
	ss.str("");	ss << "Beasts : " << g_Gangs.Gang_Gets_Beast() << "%";	EditTextItem(ss.str(), ganggetsbeast_id);

	SetCheckBox(netautobuy_id, (g_Gangs.GetNetRestock() > 0));
	SetCheckBox(healautobuy_id, (g_Gangs.GetHealingRestock() > 0));

	// weapon upgrades
	int *wlev = g_Gangs.GetWeaponLevel();
	ss.str("");	ss << "Weapon Level: " << *wlev;
	if ((*wlev) < 4)
	{
		EnableButton(weaponup_id);
		ss << " Next: " << tariff.goon_weapon_upgrade(*wlev) << "g";
	}
	else DisableButton(weaponup_id);
	g_LogFile.ss() << "weapon text = '" << ss.str() << "'" << endl; g_LogFile.ssend();
	EditTextItem(ss.str(), weaponlevel_id);

	int *nets = g_Gangs.GetNets();
	ss.str(""); ss << "Nets (" << tariff.nets_price(1) << "g each): " << *nets;
	EditTextItem(ss.str(), netdesc_id);
	DisableButton(netbuy_id, *nets >= 60);
	DisableButton(netbuy10_id, *nets >= 60);
	DisableButton(netbuy20_id, *nets >= 60);
	DisableCheckBox(netautobuy_id, *nets < 1);

	int *potions = g_Gangs.GetHealingPotions();
	ss.str(""); ss << "Heal Potions (" << tariff.healing_price(1) << "g each): " << *potions;
	EditTextItem(ss.str(), healdesc_id);
	DisableButton(healbuy_id, *potions >= 200);
	DisableButton(healbuy10_id, *potions >= 200);
	DisableButton(healbuy20_id, *potions >= 200);
	DisableCheckBox(healautobuy_id, *potions < 1);

	int cost = 0;
	if (g_Gangs.GetNumGangs() > 0)
	{
		for (int i = 0; i < g_Gangs.GetNumGangs(); i++)
		{
			sGang* g = g_Gangs.GetGang(i);
			if (g == 0) g = g_Gangs.GetGang(i - 1);
			cost += tariff.goon_mission_cost(g->m_MissionID);
		}
	}
	ss.str(""); ss << "Weekly Cost: " << cost;
	EditTextItem(ss.str(), totalcost_id);
	if (gold_id >= 0)
	{
		ss.str(""); ss << "Gold: " << g_Gold.ival();
		EditTextItem(ss.str(), gold_id);
	}

	ClearListBox(ganglist_id);
	int num = 0;
	sGang* current = g_Gangs.GetGang(0);

	// loop through the gangs, populating the list box
	g_LogFile.write("Setting gang mission descriptions\n");
	for (current = g_Gangs.GetGang(0); current; current = current->m_Next)
	{
		// format the string with the gang name, mission and number of men
		string Data[11];
		ss.str("");	ss << current->m_Name;								Data[0] = ss.str();
		ss.str("");	ss << current->m_Num;								Data[1] = ss.str();
		ss.str("");	ss << short_mission_desc(current->m_MissionID);		Data[2] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_COMBAT] << "%";		Data[3] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_MAGIC] << "%";		Data[4] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_INTELLIGENCE] << "%";	Data[5] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_AGILITY] << "%";		Data[6] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_CONSTITUTION] << "%";	Data[7] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_CHARISMA] << "%";		Data[8] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_STRENGTH] << "%";		Data[9] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_SERVICE] << "%";		Data[10] = ss.str();

		//		cerr << "Gang:\t" << Data[0] << "\t" << Data[1] << "\t" << Data[2]
		//			<< "\t" << Data[3] << "\t" << Data[4] << "\t" << Data[5] << "\t" << Data[6] << endl;

		/*
		*			add the box to the list; red highlight gangs that are low on numbers
		*/
		int color = (current->m_Num < 6 ? COLOR_RED : COLOR_BLUE);
		if (current->m_Num < 6 && (current->m_MissionID == MISS_SERVICE || current->m_MissionID == MISS_TRAINING)) color = COLOR_YELLOW;
		AddToListBox(ganglist_id, num++, Data, 11, color);
	}

	ClearListBox(recruitlist_id);
	num = 0;
	current = g_Gangs.GetHireableGang(0);

	// loop through the gangs, populating the list box
	g_LogFile.write("Setting recruitable gang info\n");
	for (current = g_Gangs.GetHireableGang(0); current; current = current->m_Next)
	{
		// format the string with the gang name, mission and number of men
		string Data[10];
		ss.str("");	ss << current->m_Name;								Data[0] = ss.str();
		ss.str("");	ss << current->m_Num;								Data[1] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_COMBAT] << "%";		Data[2] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_MAGIC] << "%";		Data[3] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_INTELLIGENCE] << "%";	Data[4] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_AGILITY] << "%";		Data[5] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_CONSTITUTION] << "%";	Data[6] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_CHARISMA] << "%";		Data[7] = ss.str();
		ss.str("");	ss << current->m_Stats[STAT_STRENGTH] << "%";		Data[8] = ss.str();
		ss.str("");	ss << current->m_Skills[SKILL_SERVICE] << "%";		Data[9] = ss.str();

		//		cerr << "Recruitable\t" << Data[0] << "\t" << Data[1] << "\t" << Data[2]
		//			<< "\t" << Data[3] << "\t" << Data[4] << "\t" << Data[5] << endl;

		/*
		*			add the box to the list
		*/
		int color = (current->m_Num < 6 ? COLOR_RED : COLOR_BLUE);
		AddToListBox(recruitlist_id, num++, Data, 10, color);
	}

	if (selection == -1 && GetListBoxSize(ganglist_id) >= 1) selection = 0;

	if (selection >= 0)
	{
		while (selection > GetListBoxSize(ganglist_id) && selection != -1) selection--;
	}
	if (selection >= 0) SetSelectedItemInList(ganglist_id, selection);
	if (sel_recruit == -1 && GetListBoxSize(recruitlist_id) >= 1) sel_recruit = 0;
	if (sel_recruit >= 0) SetSelectedItemInList(recruitlist_id, sel_recruit);

	DisableButton(ganghire_id, (g_Gangs.GetNumHireableGangs() <= 0) || (g_Gangs.GetNumGangs() >= g_Gangs.GetMaxNumGangs()) || (sel_recruit == -1));
	DisableButton(gangfire_id, (g_Gangs.GetNumGangs() <= 0) || (selection == -1));

	potions = wlev = nets = 0;
}
Example #9
0
// Run the shifts
void cClinicManager::UpdateGirls(sBrothel* brothel, bool Day0Night1)	// Start_Building_Process_B
{
	// `J` When modifying Jobs, search for "J-Change-Jobs"  :  found in >> cClinic.cpp
	u_int restjob = JOB_CLINICREST;
	u_int matronjob = JOB_CHAIRMAN;
	u_int firstjob = JOB_GETHEALING;
	u_int lastjob = JOB_JANITOR;
	stringstream ss;
	string summary, girlName;

	u_int sw = 0, psw = 0;

	int totalPay = 0, totalTips = 0, totalGold = 0;
	int sum = EVENT_SUMMARY;
	int numgirls = GetNumGirls(brothel->m_id);

	bool matron = false, matrondone = false;
	int numDoctors = 0, numNurses = 0;

	bool refused = false;

	m_Processing_Shift = Day0Night1;		// WD:	Set processing flag to shift type

	//////////////////////////////////////////////////////
	//  Handle the start of shift stuff for all girls.  //
	//////////////////////////////////////////////////////
	sGirl* current = brothel->m_Girls;
	while (current)
	{
		if (current->is_dead())		// skip dead girls
		{
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		else
		{
			sum = EVENT_SUMMARY; summary = ""; ss.str("");

			g_Girls.UseItems(current);				// Girl uses items she has
			g_Girls.CalculateGirlType(current);		// update the fetish traits
			g_Girls.CalculateAskPrice(current, true);	// Calculate the girls asking price

			if (g_Girls.HasTrait(current, "AIDS") &&
				(current->m_DayJob == JOB_DOCTOR || current->m_DayJob == JOB_INTERN || current->m_DayJob == JOB_NURSE
				|| current->m_NightJob == JOB_DOCTOR || current->m_NightJob == JOB_INTERN || current->m_NightJob == JOB_NURSE))
			{
				ss << "Health laws prohibit anyone with AIDS from working in the Medical profession so " << girlName << " was sent to the waiting room.";
				current->m_DayJob = current->m_NightJob = JOB_CLINICREST;
				sum = EVENT_WARNING;
			}
			if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);
			current = current->m_Next; // Next Girl
		}

	}


	////////////////////////////////////////////////////////
	//  Process Matron first incase she refuses to work.  //
	////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && !matrondone)
	{
		if (current->is_dead() ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) > 0 && (current->m_DayJob != matronjob || current->m_NightJob != matronjob)) ||
			(GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1 && (current->m_PrevDayJob != matronjob || current->m_PrevNightJob != matronjob)))
		{	// Sanity check! Don't process dead girls and only process those with matron jobs
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` so someone is or was a matron

		girlName = current->m_Realname;
		// if there is no matron on duty, we see who was on duty previously
		if (GetNumGirlsOnJob(0, matronjob, Day0Night1) < 1)
		{
			// if a matron was found and she is healthy, not tired and not on maternity leave... send her back to work
			if ((current->m_PrevDayJob == matronjob || current->m_PrevNightJob == matronjob) &&
				(g_Girls.GetStat(current, STAT_HEALTH) >= 50 && g_Girls.GetStat(current, STAT_TIREDNESS) <= 50) &&
				current->m_PregCooldown < cfg.pregnancy.cool_down())
				// Matron job is more important so she will go back to work at 50% instead of regular 80% health and 20% tired
			{
				current->m_DayJob = current->m_NightJob = matronjob;
				current->m_PrevDayJob = current->m_PrevNightJob = 255;
				current->m_Events.AddMessage("The Chairman puts herself back to work.", IMGTYPE_PROFILE, EVENT_BACKTOWORK);
			}
			else if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		// `J` Now we have a matron so lets see if she will work

		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// `J` she can refuse the first shift then decide to work the second shift 
		if (!current->m_Refused_To_Work_Day && Day0Night1 == SHIFT_NIGHT)	// but if she worked the first shift she continues the rest of the night
		{
			matron = true;
			ss << girlName << " continued to help the other girls throughout the night.";
		}
		else if (g_Girls.DisobeyCheck(current, ACTION_WORKMATRON, brothel))
		{
			(Day0Night1 ? current->m_Refused_To_Work_Night = true : current->m_Refused_To_Work_Day = true);
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work as the Chairman.";
			sum = EVENT_NOWORK;
		}
		else	// so there is less chance of a matron refusing the entire turn
		{
			matron = true;
			totalPay = totalTips = totalGold = 0;
			m_JobManager.JobFunc[matronjob](current, brothel, Day0Night1, summary);
			totalGold += current->m_Pay + current->m_Tips;

			// She does not get paid for the first shift and gets docked some pay from the second shift if she refused once
			if (Day0Night1 == SHIFT_NIGHT) totalGold /= 3;

			current->m_Pay += max(0, totalGold);
			current->m_Pay = current->m_Tips = 0;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
			/* */if (totalGold > 0)		{ ss << girlName << " earned a total of " << totalGold << " gold directly from you. She gets to keep it all."; }
			else if (totalGold == 0)	{ ss << girlName << " made no money."; }
			else if (totalGold < 0)		{ sum = EVENT_DEBUG; ss << "ERROR: She has a loss of " << totalGold << " gold\n\nPlease report this to the Pink Petal Devloment Team at http://pinkpetal.org\n" << "\nGirl Name: " << current->m_Realname << "\nJob: " << m_JobManager.JobName[(Day0Night1 ? current->m_NightJob : current->m_DayJob)] << "\nPay:     " << current->m_Pay << "\nTips:   " << current->m_Tips << "\nTotal: " << totalGold; }
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;	// Next Girl
		matrondone = true;			// there can be only one matron so this ends the while loop
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  Now If there is a matron and she is not refusing to work, then she can delegate the girls in this building.  //
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || sw != restjob)
		{	// skip dead girls and anyone not resting
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->m_PregCooldown == cfg.pregnancy.cool_down())
		{
			ss << girlName << " is on maternity leave.";
		}
		else if (matron && (current->health() < 80 || current->tiredness() > 20))	// if she is not healthy enough to go back to work
		{
			ss << "The Chairman admits " << girlName << " to get ";
			/* */if (g_Girls.HasTrait(current, "Construct"))		{ ss << "repaired";				current->m_DayJob = current->m_NightJob = JOB_GETREPAIRS; }
			else if (g_Girls.HasTrait(current, "Half-Construct"))	{ ss << "healed and repaired";	current->m_DayJob = JOB_GETHEALING;	current->m_NightJob = JOB_GETREPAIRS; }
			else/*                                             */	{ ss << "healed";				current->m_DayJob = current->m_NightJob = JOB_GETHEALING; }
			ss << ".\n";
		}
		else if (current->health() < 40 || current->tiredness() > 60 && g_Dice.percent(current->intelligence()))
		{
			ss << girlName << " checks herself in to get ";
			/* */if (g_Girls.HasTrait(current, "Construct"))		{ ss << "repaired";				current->m_DayJob = current->m_NightJob = JOB_GETREPAIRS; }
			else if (g_Girls.HasTrait(current, "Half-Construct"))	{ ss << "healed and repaired";	current->m_DayJob = JOB_GETHEALING;	current->m_NightJob = JOB_GETREPAIRS; }
			else/*                                             */	{ ss << "healed";				current->m_DayJob = current->m_NightJob = JOB_GETHEALING; }
			ss << ".\n";
		}
		else if (matron)	// send her back to work
		{
			psw = (Day0Night1 ? current->m_PrevNightJob : current->m_PrevDayJob);
			bool backtowork = false;
			if (psw == JOB_DOCTOR || psw == JOB_NURSE || psw == JOB_INTERN || psw == JOB_MECHANIC)
			{
				if (current->has_trait("AIDS"))
				{
					current->m_DayJob = current->m_NightJob = restjob;
					ss << girlName << " could not go back to work as a";
					if (psw == JOB_DOCTOR)	ss << " Doctor";
					if (psw == JOB_NURSE)	ss << " Nurse";
					if (psw == JOB_INTERN)	ss << "n Intern";
					ss << " because she has AIDS. Instead ";
				}
				else if (psw == JOB_DOCTOR && current->is_slave())
				{
					current->m_DayJob = current->m_NightJob = restjob;
					ss << girlName << " could not go back to work as a Doctor because she is a slave. Instead ";
				}
				else if (psw == JOB_INTERN)		// intern is a part time job
				{
					current->m_DayJob = current->m_PrevDayJob;
					current->m_NightJob = current->m_PrevNightJob;
					backtowork = true;
				}
				else							// the others are fulltime
				{
					current->m_DayJob = current->m_NightJob = psw;
					backtowork = true;
				}
			}
			else if (psw != restjob && psw >= firstjob && psw<=lastjob)
			{	// if she had a previous job that shift, put her back to work.
				if (m_JobManager.FullTimeJob(psw))
				{
					current->m_DayJob = current->m_NightJob = psw;
				}
				else if (Day0Night1)	// checking night job
				{
					if (current->m_DayJob == restjob && current->m_PrevDayJob != restjob && current->m_PrevDayJob != 255)
						current->m_DayJob = current->m_PrevDayJob;
					current->m_NightJob = psw;
				}
				else					// checking day job
				{
					current->m_DayJob = psw;
					if (current->m_NightJob == restjob && current->m_PrevNightJob != restjob && current->m_PrevNightJob != 255)
						current->m_NightJob = current->m_PrevNightJob;
				}
				backtowork = true;
			}
			if (backtowork)	ss << "The Chairman puts " << girlName << " back to work.\n";

			if (!backtowork && current->m_DayJob == restjob && current->m_NightJob == restjob)
			{	// if they have no job at all, assign them a job
				ss << "The Chairman assigns " << girlName << " to ";
				if (current->has_trait("AIDS"))										// anyone with AIDS
				{
					current->m_DayJob = current->m_NightJob = JOB_CUREDISEASES;		//  needs to get it treated right away
					ss << "get her AIDS treated right away.";
				}
				else if (current->is_free() &&										// assign any free girl
					(current->intelligence() > 70 && current->medicine() > 70)		// who is well qualified
					|| (GetNumGirlsOnJob(0, JOB_DOCTOR, Day0Night1) < 1 &&			// or if there are no doctors yet
					current->intelligence() >= 50 && current->medicine() >= 50))	// asign anyone who qualifies
				{
					current->m_DayJob = current->m_NightJob = JOB_DOCTOR;			// as a Doctor
					ss << "work as a Doctor.";
				}
				else if (GetNumGirlsOnJob(0, JOB_NURSE, Day0Night1) < 1)			// make sure there is at least 1 Nurse
				{
					current->m_DayJob = current->m_NightJob = JOB_NURSE;
					ss << "work as a Nurse.";
				}
				else if (current->has_disease())									// treat anyone with a disease
				{
					current->m_DayJob = current->m_NightJob = JOB_CUREDISEASES;
					vector<string> diseases;
					if (current->has_trait("Herpes"))		diseases.push_back("Herpes");
					if (current->has_trait("Chlamydia"))	diseases.push_back("Chlamydia");
					if (current->has_trait("Syphilis"))		diseases.push_back("Syphilis");
					if (current->has_trait("AIDS"))			diseases.push_back("AIDS");
					int numdiseases = diseases.size();
					ss << "get her " << (numdiseases > 1 ? "diseases" : diseases[0]) << " treated.";
					diseases.clear();
				}
				// then make sure there is at least 1 Janitor and 1 Mechanic
				else if (GetNumGirlsOnJob(0, JOB_MECHANIC, Day0Night1) < 1)
				{
					current->m_DayJob = current->m_NightJob = JOB_MECHANIC;
					ss << "work as a Mechanic.";
				}
				else if (GetNumGirlsOnJob(0, JOB_JANITOR, Day0Night1) < 1)
				{
					current->m_DayJob = current->m_NightJob = JOB_JANITOR;
					ss << "work as a Janitor.";
				}
				// then add more of each job as numbers permit
				else if (current->medicine() > 30 && GetNumGirlsOnJob(0, JOB_NURSE, Day0Night1) < numgirls / 10)
				{
					current->m_DayJob = current->m_NightJob = JOB_NURSE;
					ss << "work as a Nurse.";
				}
				else if (GetNumGirlsOnJob(0, JOB_MECHANIC, Day0Night1) < numgirls / 20)
				{
					current->m_DayJob = current->m_NightJob = JOB_MECHANIC;
					ss << "work as a Mechanic.";
				}
				else if (GetNumGirlsOnJob(0, JOB_JANITOR, Day0Night1) < numgirls / 20)
				{
					current->m_DayJob = current->m_NightJob = JOB_JANITOR;
					ss << "work as a Janitor.";
				}
				else	// assign anyone else to Internship
				{
					current->m_DayJob = current->m_NightJob = JOB_INTERN;
					ss << "work as an Intern.";
				}
			}
			current->m_PrevDayJob = current->m_PrevNightJob = 255;
			sum = EVENT_BACKTOWORK;

		}
		else if (current->health() < 100 || current->tiredness() > 0)	// should only do rest job in the clinic if there is no matron
		{
			m_JobManager.JobFunc[restjob](current, brothel, Day0Night1, summary);
		}
		else	// she is fully healthy but there is no one to send her back to work
		{
			ss << "WARNING " << girlName << " is doing nothing!\n";
			sum = EVENT_WARNING;
		}
		
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;
	}

	////////////////////////////////////////////////////////
	//  JOB_DOCTOR needs to be checked before all others  //
	////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || sw != JOB_DOCTOR)
		{	// skip dead girls and anyone who is not a doctor
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->has_trait("AIDS"))
		{
			ss << girlName << " has AIDS! She has to get it treated before she can go back to work as a Doctor.";
			current->m_DayJob = current->m_NightJob = JOB_CUREDISEASES;
		}
		else if (current->is_slave())
		{
			ss << "Doctors can not be slaves so " << girlName << " was demoted to Nurse.";
			current->m_DayJob = current->m_NightJob = JOB_NURSE;
		}
		else if (current->intelligence() < 50 || current->medicine() < 50)
		{
			ss << girlName << " is not qualified to be a Doctor so she was sent back to being an Intern.";
			current->m_DayJob = current->m_NightJob = JOB_NURSE;
		}
		else if (g_Girls.DisobeyCheck(current, ACTION_WORKDOCTOR, brothel))
		{
			(Day0Night1 ? current->m_Refused_To_Work_Night = true : current->m_Refused_To_Work_Day = true);
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work as a Doctor so made no money.";
			sum = EVENT_NOWORK;
		}
		else
		{
			numDoctors++;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}

	////////////////////////////////////////////////////////////////
	//  Interns and Nurses can be promoted to doctor if need be.  //
	////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current && matron && numDoctors < 1)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || sw != JOB_INTERN || current->is_slave() || current->intelligence() < 50 || current->medicine() < 50)
		{	// skip dead girls and anyone who is not an intern and make sure they are qualified to be a doctor
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKDOCTOR, brothel))
		{
			numDoctors++;
			ss << "There was no Doctor available to work so " << girlName << " was promoted to Doctor.";
			current->m_DayJob = current->m_NightJob = JOB_DOCTOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}
	current = brothel->m_Girls;
	while (current && matron && numDoctors < 1)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || sw != JOB_NURSE || current->is_slave() || current->intelligence() < 50 || current->medicine() < 50)
		{	// skip dead girls and anyone who is not a nurse and make sure they are qualified to be a doctor
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (!g_Girls.DisobeyCheck(current, ACTION_WORKDOCTOR, brothel))
		{
			numDoctors++;
			ss << "There was no Doctor available to work so " << girlName << " was promoted to Doctor.";
			current->m_DayJob = current->m_NightJob = JOB_DOCTOR;
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}

	/////////////////////////////////////
	//  Do all the Clinic staff jobs.  //
	/////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || (sw != JOB_INTERN && sw != JOB_NURSE && sw != JOB_JANITOR && sw != JOB_MECHANIC && sw != JOB_DOCTOR) ||
			// skip dead girls and anyone who is not staff
			(sw == JOB_DOCTOR && ((Day0Night1 == SHIFT_DAY && current->m_Refused_To_Work_Day)||(Day0Night1 == SHIFT_NIGHT && current->m_Refused_To_Work_Night))))
		{	// and skip doctors who refused to work in the first check
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		totalPay = totalTips = totalGold = 0;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");
		girlName = current->m_Realname;

		if (current->m_NightJob == JOB_DOCTOR) summary = "SkipDisobey";
		// do their job
		refused = m_JobManager.JobFunc[sw](current, brothel, Day0Night1, summary);

		totalPay += current->m_Pay;
		totalTips += current->m_Tips;
		totalGold += current->m_Pay + current->m_Tips;
		g_Brothels.CalculatePay(brothel, current, sw);

		//		Summary Messages
		if (refused)
		{
			brothel->m_Fame -= g_Girls.GetStat(current, STAT_FAME);
			ss << girlName << " refused to work so made no money.";
		}
		else
		{
			ss << m_JobManager.GirlPaymentText(brothel, current, totalTips, totalPay, totalGold, Day0Night1);
			if (totalGold < 0) sum = EVENT_DEBUG;

			brothel->m_Fame += g_Girls.GetStat(current, STAT_FAME);
		}
		if (ss.str().length() > 0) current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next; // Next Girl
	}


	///////////////////////////////////////////////////////////////////////
	//  Do all the surgery jobs. Not having a doctor is in all of them.  //
	///////////////////////////////////////////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (current->is_dead() || (sw != JOB_GETHEALING && sw != JOB_GETREPAIRS && sw != JOB_GETABORT
			&& sw != JOB_COSMETICSURGERY && sw != JOB_LIPO && sw != JOB_BREASTREDUCTION && sw != JOB_BOOBJOB
			&& sw != JOB_VAGINAREJUV && sw != JOB_FACELIFT && sw != JOB_ASSJOB && sw != JOB_TUBESTIED
			&& sw != JOB_CUREDISEASES && sw != JOB_FERTILITY))
		{	// skip dead girls and anyone not a patient
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		summary = "";

		// do their surgery
		m_JobManager.JobFunc[sw](current, brothel, Day0Night1, summary);

		current = current->m_Next; // Next Girl
	}

	///////////////////////////////////
	//  Finaly do end of day stuff.  //
	///////////////////////////////////
	current = brothel->m_Girls;
	while (current)
	{
		if (current->is_dead())
		{	// skip dead girls
			if (current->m_Next) { current = current->m_Next; continue; }
			else { current = 0; break; }
		}
		girlName = current->m_Realname;
		sum = EVENT_SUMMARY; summary = ""; ss.str("");

		// update for girls items that are not used up
		do_daily_items(brothel, current);					// `J` added

		// Level the girl up if nessessary
		g_Girls.LevelUp(current);
		// Natural healing, 2% health and 2% tiredness per day
		g_Girls.UpdateStat(current, STAT_HEALTH, 2, false);
		g_Girls.UpdateStat(current, STAT_TIREDNESS, -2, false);

		sw = (Day0Night1 ? current->m_NightJob : current->m_DayJob);
		if (g_Girls.GetStat(current, STAT_HAPPINESS) < 40)
		{
			if (sw != matronjob && matron && brothel->m_NumGirls > 1 && g_Dice.percent(70))
			{
				ss << "The Chairman helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 5);
			}
			else if (brothel->m_NumGirls > 10 && g_Dice.percent(50))
			{
				ss << "Some of the other girls help cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 8 + 3);
			}
			else if (brothel->m_NumGirls > 1 && g_Dice.percent(max(brothel->m_NumGirls, 50)))
			{
				ss << "One of the other girls helps cheer up " << girlName << " when she is feeling sad.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 6 + 2);
			}
			else if (brothel->m_NumGirls == 1 && g_Dice.percent(70))
			{
				ss << girlName << " plays around in the empty building until she feels better.\n";
				g_Girls.UpdateStat(current, STAT_HAPPINESS, g_Dice % 10 + 10);
			}
			else if (g_Girls.GetStat(current, STAT_HAPPINESS) < 20) // no one helps her and she is really unhappy
			{
				ss << girlName << " is looking very depressed. You may want to do something about that before she does something drastic.\n";
				sum = EVENT_WARNING;
			}
		}

		// The Clinic Chairman will heal herself if she is injured or tired
		if (sw == matronjob && (current->tiredness() > 60 || current->health() < 40))
		{
			int t = g_Girls.GetStat(current, STAT_TIREDNESS);
			int h = g_Girls.GetStat(current, STAT_HEALTH);
			if (t > 90 || h < 10)	// The matron may take herself off work if she is really bad off
			{
				current->m_PrevDayJob = current->m_DayJob;
				current->m_PrevNightJob = current->m_NightJob;
				current->m_DayJob = current->m_NightJob = JOB_GETHEALING;
				ss << "The Chairman admits herself to get Healing because she is just too damn sore.\n";
				g_Girls.UpdateEnjoyment(current, ACTION_WORKMATRON, -10);
			}
			else
			{
				ss << "As Chairman, " << girlName << " has the keys to the store room.\nShe used them to 'borrow' ";
				if (t > 50 && h < 50)
				{
					ss << "some potions";
					g_Gold.consumable_cost(20, true);
					current->health(min(current->health() + 20, 100));
					current->tiredness(max(current->tiredness() - 20, 0));
				}
				else if (t > 50)
				{
					ss << "a resting potion";
					g_Gold.consumable_cost(10, true);
					current->m_Stats[STAT_TIREDNESS] = max(current->m_Stats[STAT_TIREDNESS] - 20, 0);
				}
				else if (h < 50)
				{
					ss << "a healing potion";
					g_Gold.consumable_cost(10, true);
					current->m_Stats[STAT_HEALTH] = min(current->m_Stats[STAT_HEALTH] + 20, 100);
				}
				ss << " for herself.\n";
			}

		}
		else if (current->tiredness() > 80 || current->health() < 20)
		{
			int t = g_Girls.GetStat(current, STAT_TIREDNESS);
			int h = g_Girls.GetStat(current, STAT_HEALTH);

			if (current->m_WorkingDay > 0)
			{
				ss << girlName << " is not faring well in surgery.\n";
				sum = EVENT_WARNING;
			}
			else if (!matron)	// do no matron first as it is the easiest
			{
				ss << "WARNING! " << girlName;
				if (t > 80 && h < 20)		ss << " is in real bad shape, she is tired and injured.\nShe should go to the Clinic.\n";
				else if (t > 80 && h < 40)	ss << " is in bad shape, she is tired and injured.\nShe should rest or she may die!\n";
				else if (t > 80)			ss << " is desparatly in need of rest.\nGive her some free time\n";
				else if (h < 20)			ss << " is badly injured.\nShe should rest or go to the Clinic.\n";
				else if (h < 40)			ss << " is hurt.\nShe should rest and recuperate.\n";
				sum = EVENT_WARNING;
			}
			else	// do all other girls with a matron working
			{
				if (current->m_PrevNightJob == 255 && current->m_PrevDayJob == 255) // the girl has been working
				{
					current->m_PrevDayJob = current->m_DayJob;
					current->m_PrevNightJob = current->m_NightJob;
					current->m_DayJob = current->m_NightJob = restjob;
					ss << "The Chairman takes " << girlName << " off duty to rest due to her ";
					if (t > 80 && h < 40)	ss << "exhaustion.\n";
					else if (t > 80)		ss << "tiredness.\n";
					else if (h < 40)		ss << "low health.\n";
					else /*       */		ss << "current state.\n";
					sum = EVENT_WARNING;
				}
				else	// the girl has already been taken off duty by the matron
				{
					if (g_Dice.percent(70))
					{
						ss << "The Chairman helps ";
						if (t > 80 && h < 40)
						{
							ss << girlName << " recuperate.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 4 + 2));
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 4 + 2));
						}
						else if (t > 80)
						{
							ss << girlName << " to relax.\n";
							g_Girls.UpdateStat(current, STAT_TIREDNESS, -(g_Dice % 5 + 5));
						}
						else if (h < 40)
						{
							ss << " heal " << girlName << ".\n";
							g_Girls.UpdateStat(current, STAT_HEALTH, (g_Dice % 5 + 5));
						}
					}
				}
			}
		}

		if (ss.str().length() > 0)	current->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, sum);

		current = current->m_Next;		// Process next girl
	}

	m_Processing_Shift = -1;	// WD: Finished Processing Shift set flag
}
Example #10
0
void cRivalManager::Update(int& NumPlayerBussiness)
{
	cRival* curr = m_Rivals;
	cConfig cfg;

	if (g_Year >= 1209 && g_Month > 3) m_PlayerSafe = false;

	while (curr)
	{
		// check if rival is killed
		if (curr->m_Gold <= 0 && curr->m_NumBrothels <= 0 && curr->m_NumGangs <= 0 &&
			curr->m_NumGirls <= 0 && curr->m_NumGamblingHalls <= 0 && curr->m_NumBars <= 0 &&
			curr->m_NumInventory <= 0)
		{
			cRival* tmp = curr->m_Next;
			RemoveRival(curr);
			curr = tmp;
			SetGameFlag(FLAG_RIVALLOSE);
			continue;
		}

		int income = 0; int upkeep = 0; int profit = 0;
		int totalincome = 0; int totalupkeep = 0;
		int startinggold = curr->m_Gold;

		// `J` added - rival power
		// `J` reworked to reduce the rival's power
		curr->m_Power = 
			max(0, curr->m_NumBrothels * 5) +
			max(0, curr->m_NumGamblingHalls * 2) +
			max(0, curr->m_NumBars * 1);
	
		// check if a rival is in danger
		if (curr->m_Gold <= 0 || curr->m_NumBrothels <= 0 || curr->m_NumGirls <= 0 || curr->m_NumGamblingHalls <= 0 || curr->m_NumBars <= 0)
		{
			// The AI is in danger so will stop extra spending
			curr->m_BribeRate = 0;
			curr->m_Influence = 0;

			// first try to sell any items
			if (curr->m_NumInventory > 0)
			{
				for (int i = 0; i < MAXNUM_RIVAL_INVENTORY && curr->m_Gold + income + upkeep < 1000; i++)
				{
					sInventoryItem* temp = curr->m_Inventory[i];
					if (temp)
					{
						income += (temp->m_Cost / 2);
						RemoveRivalInvByNumber(curr, i);
					}
				}
			}

			// try to buy at least one of each to make up for losses
			if (curr->m_NumBrothels <= 0 && curr->m_Gold + income + upkeep - 20000 >= 0)
			{
				upkeep -= 20000;
				curr->m_NumBrothels++;
			}
			if (curr->m_NumGirls <= 0 && curr->m_Gold + income + upkeep - 550 >= 0)
			{
				upkeep -= 550;
				curr->m_NumGirls++;
			}
			if (curr->m_NumGamblingHalls <= 0 && curr->m_Gold + income + upkeep - 10000 >= 0)
			{
				curr->m_NumGamblingHalls++;
				upkeep -= 10000;
			}
			if (curr->m_NumBars <= 0 && curr->m_Gold + income + upkeep - 2500 >= 0)
			{
				curr->m_NumBars++;
				upkeep -= 2500;
			}
			// buy more girls if there is enough money left (save at least 1000 in reserve)
			if (curr->m_Gold + income + upkeep >= 1550 && (curr->m_NumGirls < 5 || curr->m_NumGirls < curr->m_NumBrothels * 20))
			{
				int i = 0;
				while (curr->m_Gold + income + upkeep >= 1550 && i < (g_Dice % 5) + 1)	// buy up to 5 girls if they can afford it.
				{
					upkeep -= 550;
					curr->m_NumGirls++;
					i++;
				}
			}
		}

		// process money
		totalincome += income; totalupkeep += upkeep; curr->m_Gold += income; curr->m_Gold += upkeep; profit = totalincome + totalupkeep; 
		income = upkeep = 0;
		
		for (int i = 0; i < curr->m_NumGirls; i++)	// from girls
		{
			// If a rival has more girls than their brothels can handle, the rest work on the streets
			double rapechance = (i > curr->m_NumBrothels * 20 ? cfg.prostitution.rape_brothel() : cfg.prostitution.rape_streets());
			int Customers = g_Dice % 6;				// 0-5 cust per girl
			for (int i = 0; i < Customers;i++)
			{
				if (g_Dice.percent(rapechance))
				{
					upkeep -= 50;					// pay off the girl and the officials after killing the rapist
				}
				else
				{
					income += g_Dice % 38 + 2;		// 2-40 gold per cust
				}
			}
		}
		// from halls
		for (int i = 0; i < curr->m_NumGamblingHalls; i++)
		{
			int Customers = ((g_Dice%curr->m_NumGirls) + curr->m_NumGirls / 5);
			if (g_Dice.percent(5))
			{
				upkeep -= ((g_Dice % 101) + 200);			// Big Winner
				Customers += g_Dice % 10;					// attracts more customers
			}
			if (g_Dice.percent(5))
			{
				income += ((g_Dice % 601) + 400);			// Big Loser
				Customers -= g_Dice % (Customers / 5);		// scares off some customers
			}
			// they will kick a customer out if they win too much so they can win up to 100 but only lose 50
			for (int j = 0; j < Customers; j++)
			{
				int winloss = (g_Dice % 151 - 50);
				if (winloss > 0) income += winloss;
				else /*       */ upkeep += winloss;
			}
		}
		// from bars
		for (int i = 0; i < curr->m_NumBars; i++)
		{
			int Customers = ((g_Dice%curr->m_NumGirls) + curr->m_NumGirls/5);
			if (g_Dice.percent(5))
			{
				upkeep -= ((g_Dice % 250) + 1);				// bar fight - cost to repair
				Customers -= g_Dice % (Customers / 5);		// scare off some customers
			}
			if (g_Dice.percent(5))
			{
				income += ((g_Dice % 250) + 1);				// Big Spender
				Customers += g_Dice % 5;					// attracts more customers
			}
			for (int j = 0; j < Customers; j++)
			{
				income += (g_Dice % 9) + 1;				// customers spend 1-10 per visit
			}

		}
		// from businesses
		if (curr->m_BusinessesExtort > 0) income += (curr->m_BusinessesExtort * INCOME_BUSINESS);

		// Calc their upkeep
		upkeep -= curr->m_BribeRate;
		upkeep -= curr->m_NumGirls * 5;
		upkeep -= curr->m_NumBars * 20;
		upkeep -= curr->m_NumGamblingHalls * 80;
		upkeep -= (curr->m_NumBars)*((g_Dice % 50) + 30);	// upkeep for buying barrels of booze
		upkeep -= (curr->m_NumGangs * 90);

		float taxRate = 0.06f;	// normal tax rate is 6%
		if (curr->m_Influence > 0)	// can you influence it lower
		{
			int lowerBy = curr->m_Influence / 20;
			float amount = (float)(lowerBy / 100);
			taxRate -= amount;
			if (taxRate <= 0.01f) taxRate = 0.01f;
		}
		if (income > 0)
		{
			int tmp = income - (g_Dice % (int)(income*0.25f));	// launder up to 25% of gold
			int tax = (int)(tmp*taxRate);
			upkeep -= tax;
		}

		// process money
		totalincome += income; totalupkeep += upkeep; curr->m_Gold += income; curr->m_Gold += upkeep; profit = totalincome + totalupkeep; 
		income = upkeep = 0;

		// Work out gang missions
		int cGangs = curr->m_NumGangs;
		for (int i = 0; i < cGangs; i++)
		{
			sGang* cG1 = g_Gangs.GetTempGang(curr->m_Power);	// create a random gang for this rival
			int missionid = -1;
			int tries = 0;
			while (missionid == -1 && tries < 10)	// choose a mission
			{
				switch (g_Dice % 9)	// `J` zzzzzz - need to add checks into this
				{
				case 0:
					missionid = MISS_EXTORTION;		// gain territory
					break;
				case 1:
					missionid = MISS_PETYTHEFT;		// small money but safer
					break;
				case 2:
					missionid = MISS_GRANDTHEFT;	// large money but difficult
					break;
				case 3:
					missionid = MISS_SABOTAGE;		// attack rivals
					break;
				case 4:
					break;	// not ready
					missionid = MISS_CAPTUREGIRL;	// take girls from rivals
					break;
				case 5:
					missionid = MISS_KIDNAPP;		// get new girls
					break;
				case 6:
					missionid = MISS_CATACOMBS;		// random but dangerous
					break;
				default:	
					missionid = MISS_GUARDING;		// don't do anything but guard
					break;
				}
				tries++;
			}


			switch (missionid)
			{
			case MISS_EXTORTION:		// gain territory
			{
				int numB = GetNumBusinesses() + NumPlayerBussiness;
				if (numB < TOWN_NUMBUSINESSES)	// if there are uncontrolled businesses
				{
					int n = g_Dice % 5 - 2;
					if (n > 0)					// try to take some
					{
						if (numB + n > TOWN_NUMBUSINESSES)
							n = TOWN_NUMBUSINESSES - numB;

						curr->m_BusinessesExtort += n;
						income += n * 20;
					}
				}
				else			// if there are no uncontrolled businesses
				{
					stringstream ss;
					int who = (g_Dice % (m_NumRivals + 1));				// who to attack
					if (who == m_NumRivals)								// try to attack you
					{
						if (!player_safe() && NumPlayerBussiness > 0)	// but only if you are a valid target
						{
							sGang* miss1 = g_Gangs.GetGangOnMission(MISS_GUARDING);
							if (miss1)									// if you have a gang guarding
							{
								ss << gettext("Your guards encounter ") << curr->m_Name << gettext(" going after some of your territory.");

								sGang* rGang = g_Gangs.GetTempGang(curr->m_Power);
								if (g_Gangs.GangBrawl(miss1, rGang))	// if you win
								{
									if (rGang->m_Num == 0) curr->m_NumGangs--;
									ss << gettext("\nBut you maintain control of the territory.");
									miss1->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_GANG);
								}
								else									// if you lose
								{
									if (miss1->m_Num == 0) g_Gangs.RemoveGang(miss1);
									ss << gettext("\nYou lose the territory.");
									NumPlayerBussiness--;
									curr->m_BusinessesExtort++;
									g_MessageQue.AddToQue(ss.str(), COLOR_RED);
								}
								delete rGang; rGang = 0;	// cleanup
							}
							else										// if you do not have a gang guarding
							{
								ss << gettext("Your rival ") << curr->m_Name << gettext(" has taken one of the undefended territories you control.");
								g_MessageQue.AddToQue(ss.str(), COLOR_RED);
								NumPlayerBussiness--;
								curr->m_BusinessesExtort++;
							}
						}
					}
					else	// attack another rival
					{
						ss << gettext("The ") << curr->m_Name << gettext(" attacked the territories of ");
						cRival* rival = GetRival(who);
						if (rival != curr && rival->m_BusinessesExtort > 0)
						{
							ss << rival->m_Name;
							if (rival->m_NumGangs > 0)
							{
								sGang* rG1 = g_Gangs.GetTempGang(rival->m_Power);
								if (g_Gangs.GangBrawl(cG1, rG1, true))
								{
									rival->m_NumGangs--;
									rival->m_BusinessesExtort--;
									curr->m_BusinessesExtort++;
									ss << gettext(" and won.");
								}
								else
								{
									curr->m_NumGangs--;
									ss << gettext(" and lost.");
								}
								delete rG1; rG1 = 0;	// cleanup
							}
							else
							{
								ss << " and took an unguarded territory.";
								rival->m_BusinessesExtort--;
								curr->m_BusinessesExtort++;
							}
							g_MessageQue.AddToQue(ss.str(), COLOR_BLUE);
						}
					}
				}
			}break;
			case MISS_PETYTHEFT:		// small money but safer
			{
				if (g_Dice.percent(70))
				{
					income += g_Dice % 400 + 1;
				}
				else if (g_Dice.percent(10))	// they may lose the gang
				{
					curr->m_NumGangs--;
				}
			}break;
			case MISS_GRANDTHEFT:		// large money but difficult
			{
				if (g_Dice.percent(30))
				{
					income += (g_Dice % 20 + 1) * 100;
				}
				else if (g_Dice.percent(30))	// they may lose the gang
				{
					curr->m_NumGangs--;
				}
			}break;
			case MISS_SABOTAGE:			// attack rivals
			{
				if (g_Dice.percent(min(90, cG1->intelligence())))	// chance they find a target
				{
					stringstream ss;
					int who = (g_Dice % (m_NumRivals + 1));
					if (who == m_NumRivals && !player_safe())	// if it is you and you are a valid target
					{
						int num = 0;
						bool damage = false;
						sGang* miss1 = g_Gangs.GetGangOnMission(MISS_GUARDING);
						if (miss1)
						{
							ss << gettext("Your rival the ") << curr->m_Name << gettext(" attack your assets.");

							if (!g_Gangs.GangBrawl(miss1, cG1))
							{
								if (miss1->m_Num == 0) g_Gangs.RemoveGang(miss1);
								ss << gettext("\nYour men are defeated.");
								int num = (g_Dice % 2) + 1;
								damage = true;
							}
							else
							{
								if (cG1->m_Num == 0) curr->m_NumGangs--;
								ss << gettext(" But they fail.");
								miss1->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_GANG);
							}
						}
						else
						{
							ss << gettext("You have no guards so your rival ") << curr->m_Name << gettext(" attacks.");
							if (NumPlayerBussiness > 0 || g_Gold.ival() > 0)
							{
								num = (g_Dice % 3) + 1;
								damage = true;
							}
						}
						if (damage)
						{
							if (NumPlayerBussiness > 0)
							{
								ss << "\nThey destroy ";
								NumPlayerBussiness -= num;
								if (NumPlayerBussiness < 0)
								{
									ss << "all";
									NumPlayerBussiness = 0;
								}
								else if (num == 1)	ss << "one";
								else if (num == 2)	ss << "two";
								else /*         */	ss << num;
								ss << " of your territories.";
							}
							else ss << ".";

							ss << rivals_plunder_pc_gold(curr);
							g_MessageQue.AddToQue(ss.str(), COLOR_RED);
						}
					}
					else
					{
						ss << gettext("The ") << curr->m_Name << gettext(" launched an assault on ");
						cRival* rival = GetRival(who);
						if (rival && rival != curr)
						{
							int num = 0;
							ss << rival->m_Name;
							if (rival->m_NumGangs > 0)
							{
								sGang* rG1 = g_Gangs.GetTempGang(rival->m_Power);
								if (g_Gangs.GangBrawl(cG1, rG1, true))
								{
									rival->m_NumGangs--;
									ss << gettext(" and won.");
									num = (g_Dice % 2) + 1;
								}
								else
								{
									ss << gettext(" and lost.");
									curr->m_NumGangs--;
								}
								delete rG1; rG1 = 0;	// cleanup
							}
							else
							{
								num = (g_Dice % 4) + 1;	// can do more damage if not fighting another gang
							}
							if (num > 0)
							{
								if (rival->m_BusinessesExtort > 0)
								{
									rival->m_BusinessesExtort -= num;
									if (rival->m_BusinessesExtort < 0)
										rival->m_BusinessesExtort = 0;
								}
								if (rival->m_Gold > 0)
								{
									long gold = (g_Dice % 2000) + 45;	// get a random ammount
									if ((rival->m_Gold - gold) > 0)		// and if they have more than that
									{
										rival->m_Gold -= gold;			// take it
									}
									else								// but if not
									{
										gold = rival->m_Gold;			// take all they have
										rival->m_Gold = 0;
									}
									income += gold;
								}
								int buildinghit = g_Dice.d100() - num;
								if (rival->m_NumBrothels > 0 && buildinghit < 10 + (rival->m_NumBrothels * 2))
								{		// 10% base + 2% per brothel
									rival->m_NumBrothels--;
									rival->m_Power--;
									ss << "\nThey destroyed one of their Brothels.";
								}
								else if (rival->m_NumGamblingHalls > 0 && buildinghit < 30 + (rival->m_NumGamblingHalls * 2))
								{		// 20% base + 2% per hall
									rival->m_NumGamblingHalls--;
									ss << "\nThey destroyed one of their Gambling Halls.";
								}
								else if (rival->m_NumBars > 0 && buildinghit < 60 + (rival->m_NumBars * 2))
								{		// 60% base + 2% per bar
									rival->m_NumBars--;
									ss << "\nThey destroyed one of their Bars.";
								}
							}
							g_MessageQue.AddToQue(ss.str(), 0);
						}
					}
				}
			}break;
			case MISS_CAPTUREGIRL:		// take girls from rivals
			{





			}break;
			case MISS_KIDNAPP:			// get new girls
			{
				if (g_Dice.percent(cG1->intelligence()))			// chance to find a girl
				{
					bool addgirl = false;
					sGirl* girl = g_Girls.GetRandomGirl();
					g_Girls.SetStat(girl, STAT_HEALTH, 100);		// make sure she is at full health
					if (girl)
					{
						if (g_Dice.percent(cG1->m_Stats[STAT_CHARISMA]))	// convince her
						{
							addgirl = true;
						}
						else if (g_Brothels.FightsBack(girl))				// try to kidnap her
						{
							if (!g_Gangs.GirlVsEnemyGang(girl, cG1)) addgirl = true;
							else if (cG1->m_Num <= 0) curr->m_NumGangs--;
						}
						else { addgirl = true; }							// she goes willingly
					}
					if (addgirl) curr->m_NumGirls++;
				}
			}break;
			case MISS_CATACOMBS:		// random but dangerous
			{
				int num = cG1->m_Num;
				for (int i = 0; i < num; i++)
				{
					if (!g_Dice.percent(cG1->combat())) cG1->m_Num--;
				}
				if (cG1->m_Num > 0)
				{
					// determine loot
					int gold = cG1->m_Num;
					gold += g_Dice % (cG1->m_Num * 100);
					income += gold;

					int items = 0;
					while (g_Dice.percent(60) && items <= (cG1->m_Num / 3) && curr->m_NumInventory < MAXNUM_RIVAL_INVENTORY)
					{
						bool quit = false; bool add = false;
						sInventoryItem* temp;
						do { temp = g_InvManager.GetRandomItem(); 
						} while (!temp || temp->m_Rarity < RARITYSHOP25 || temp->m_Rarity > RARITYCATACOMB01);

						switch (temp->m_Rarity)
						{
						case RARITYSHOP25:								add = true;		break;
						case RARITYSHOP05:		if (g_Dice.percent(25))	add = true;		break;
						case RARITYCATACOMB15:	if (g_Dice.percent(15))	add = true;		break;
						case RARITYCATACOMB05:	if (g_Dice.percent(5))	add = true;		break;
						case RARITYCATACOMB01:	if (g_Dice.percent(1))	add = true;		break;
							// adding these cases to shut the compiler up
						case RARITYCOMMON:	case RARITYSHOP50:	case RARITYSCRIPTONLY:	case RARITYSCRIPTORREWARD:
						default:
							break;
						}
						if (add)
						{
							AddRivalInv(curr, temp);
						}
					}

					int girls = 0;
					while (g_Dice.percent(40) && girls <= 4)	// up to 4 girls
					{
						girls++;
						curr->m_NumGirls++;
					}
				}
			}break;
			default:	break;			// No mission
			}	// end mission switch
			delete cG1; cG1 = 0;	// cleanup
		}	// end Gang Missions

		// process money
		totalincome += income; totalupkeep += upkeep; curr->m_Gold += income; curr->m_Gold += upkeep; profit = totalincome + totalupkeep; 
		income = upkeep = 0;

		bool danger = false;
		bool sellfail = false;
		// if they are loosing money and they will be bankrupt in 2 turns or less
		if (profit <= 0 && curr->m_Gold - (profit * 2) < 0)		// sell off some stuff
		{
			danger = true;						// this will make sure AI doesn't replace them this turn
			while (curr->m_Gold + income + upkeep - (profit * 2) < 0 && !sellfail)
			{
				// first try to sell any items
				if (curr->m_NumInventory > 0)
				{
					for (int i = 0; i < MAXNUM_RIVAL_INVENTORY && curr->m_Gold + income + upkeep - (profit * 2) < 0; i++)
					{
						sInventoryItem* temp = curr->m_Inventory[i];
						if (temp)
						{
							income += (temp->m_Cost / 2);
							RemoveRivalInvByNumber(curr, i);
						}
					}
				}

				// sell extra stuff - hall or bar
				if (curr->m_NumGamblingHalls > curr->m_NumBrothels)
				{
					curr->m_NumGamblingHalls--;
					income += 5000;
				}
				else if (curr->m_NumBars > curr->m_NumBrothels)
				{
					curr->m_NumBars--;
					income += 1250;
				}
				// if they have an empty brothel, sell it
				else if (curr->m_NumBrothels > 1 && (curr->m_NumBrothels - 1) * 20 > curr->m_NumGirls + 1)
				{
					curr->m_NumBrothels--;
					income += 10000;
				}
				// sell extra girls
				else if (curr->m_NumGirls > curr->m_NumBrothels * 20)
				{
					curr->m_NumGirls--;
					income += g_Dice % 401 + 300;	// variable price 300-700
				}
				// sell a hall or bar keeping at least 1 of each
				else if (curr->m_NumGamblingHalls > 1 && curr->m_NumBars <= curr->m_NumGamblingHalls)
				{
					curr->m_NumGamblingHalls--;
					income += 5000;
				}
				else if (curr->m_NumBars > 1)
				{
					curr->m_NumBars--;
					income += 1250;
				}
				// Finally - sell a girl
				else if (curr->m_NumGirls > 1)
				{
					curr->m_NumGirls--;
					income += g_Dice % 401 + 300;	// variable price 300-700
				}
				else
				{
					sellfail = true;	// could not sell anything so break out of the while loop
				}
			}
		}

		// process money
		totalincome += income; totalupkeep += upkeep; curr->m_Gold += income; curr->m_Gold += upkeep; profit = totalincome + totalupkeep; 
		income = upkeep = 0;

		if (!danger)
		{
			// use or sell items
			if (curr->m_NumInventory > 0)
			{
				for (int i = 0; i < MAXNUM_RIVAL_INVENTORY; i++)
				{
					sInventoryItem* temp = curr->m_Inventory[i];
					if (temp && g_Dice.percent(50))
					{
						if (g_Dice.percent(50)) income += (temp->m_Cost / 2);
						RemoveRivalInvByNumber(curr, i);
					}
				}
			}

			// buy a new brothel if they have enough money
			if (curr->m_Gold + income + upkeep - 20000 > 0 && curr->m_NumGirls + 2 >= curr->m_NumBrothels * 20 && curr->m_NumBrothels < 6)
			{
				curr->m_NumBrothels++;
				upkeep -= 20000;
			}
			// buy new girls
			int girlsavailable = (g_Dice % 6) + 1;
			while (curr->m_Gold + income + upkeep - 550 >= 0 && girlsavailable > 0 && curr->m_NumGirls < curr->m_NumBrothels * 20)
			{
				curr->m_NumGirls++;
				girlsavailable--;
				upkeep -= 550;
			}
			// hire gangs
			int gangsavailable = (max(0, (g_Dice % 5) - 2));
			while (curr->m_Gold + income + upkeep - 90 >= 0 && gangsavailable > 0 && curr->m_NumGangs < 8)
			{
				curr->m_NumGangs++;
				upkeep -= 90;
			}
			// buy a gambling hall 
			if (g_Dice.percent(30) && curr->m_Gold + income + upkeep - 10000 >= 0 && curr->m_NumGamblingHalls < curr->m_NumBrothels)
			{
				curr->m_NumGamblingHalls++;
				upkeep -= 10000;
			}
			// buy a new bar
			if (g_Dice.percent(60) && curr->m_Gold + income + upkeep - 2500 >= 0 && curr->m_NumBars < curr->m_NumBrothels)
			{
				curr->m_NumBars++;
				upkeep -= 2500;
			}

			// buy items
			int rper[7] = { 90, 70, 50, 30, 10, 5, 1 };
			int i = 0;
			while (i < 6)
			{
				sInventoryItem* item = g_InvManager.GetRandomItem();
				if (item && item->m_Rarity <= RARITYCATACOMB01 && g_Dice.percent(rper[item->m_Rarity])
					&& curr->m_Gold + income + upkeep > item->m_Cost)
				{
					if (g_Dice.percent(50))
					{
						AddRivalInv(curr, item);	// buy 50%, use 50%
					}
					upkeep -= item->m_Cost;
				}
				i++;

			}
		}

		// process money
		totalincome += income; totalupkeep += upkeep; curr->m_Gold += income; curr->m_Gold += upkeep; profit = totalincome + totalupkeep; 
		income = upkeep = 0;

		// adjust their bribe rate		
		if (profit > 1000)		curr->m_BribeRate += (long)(50);	// if doing well financially then increase 
		else if (profit < 0)	curr->m_BribeRate -= (long)(50);	// if loosing money decrease
		if (curr->m_BribeRate < 0) curr->m_BribeRate = 0;			// check 0
		g_Brothels.UpdateBribeInfluence();							// update influence


		// `J` bookmark - rival money at the end of their turn
		if (cfg.debug.log_debug())
		g_LogFile.os() << "Processing Rival: " << curr->m_Name
			<< " | Starting Gold: " << startinggold
			<< " | Income: " << totalincome
			<< " | Upkeep: " << totalupkeep
			<< " | Profit: " << totalincome + totalupkeep
			<< " | Ending Gold: " << curr->m_Gold <<"\n";

		curr = curr->m_Next;
	}
}
Example #11
0
void cScreenHouse::init()
{
	g_CurrentScreen = SCREEN_HOUSE;
	if (!g_InitWin) { return; }
	Focused();
	g_InitWin = false;

	locale syslocale("");
	stringstream ss;
	ss.imbue(syslocale);

	ss << gettext("CURRENT OBJECTIVE: ");
	sObjective* obj = g_Brothels.GetObjective();
	if (obj)
	{
		switch (obj->m_Objective)
		{
		case OBJECTIVE_REACHGOLDTARGET:
			ss << gettext("Gather ") << obj->m_Target << gettext(" gold");
			if (obj->m_Limit != -1) {
				ss << gettext(" in ") << obj->m_Limit << gettext(" weeks");
			}
			ss << gettext(", ") << g_Gold.ival() << gettext(" gathered so far.");
			break;
		case OBJECTIVE_GETNEXTBROTHEL:
			fmt_objective(ss, gettext("Purchase the next brothel"), obj->m_Limit);
			break;
			/*----
			case OBJECTIVE_PURCHASENEWGAMBLINGHALL:
			fmt_objective(ss, "Purchase a gambling hall", obj->m_Limit);
			break;
			case OBJECTIVE_PURCHASENEWBAR:
			fmt_objective(ss, "Purchase a bar", obj->m_Limit);
			break;
			----*/
		case OBJECTIVE_LAUNCHSUCCESSFULATTACK:
			fmt_objective(ss, gettext("Launch a successful attack"), obj->m_Limit);
			break;
		case OBJECTIVE_HAVEXGOONS:
			ss << gettext("Have ") << obj->m_Target << gettext(" gangs");
			fmt_objective(ss, "", obj->m_Limit);
			break;
		case OBJECTIVE_STEALXAMOUNTOFGOLD:
			ss << gettext("Steal ") << obj->m_Target << gettext(" gold");
			fmt_objective(ss, "", obj->m_Limit, obj->m_SoFar);
			break;
		case OBJECTIVE_CAPTUREXCATACOMBGIRLS:
			ss << gettext("Capture ") << obj->m_Target << gettext(" girls from the catacombs");
			fmt_objective(ss, "", obj->m_Limit, obj->m_SoFar);
			break;
		case OBJECTIVE_HAVEXMONSTERGIRLS:
			ss << gettext("Have a total of ") << obj->m_Target << gettext(" monster (non-human) girls");
			fmt_objective(ss, "", obj->m_Limit, g_Brothels.GetTotalNumGirls(true));
			break;
		case OBJECTIVE_KIDNAPXGIRLS:
			ss << gettext("Kidnap ") << obj->m_Target << gettext(" girls from the streets");
			fmt_objective(ss, "", obj->m_Limit, obj->m_SoFar);
			break;
		case OBJECTIVE_EXTORTXNEWBUSINESS:
			ss << gettext("Control ") << obj->m_Target << gettext(" city business");
			fmt_objective(ss, "", obj->m_Limit, obj->m_SoFar);
			break;
		case OBJECTIVE_HAVEXAMOUNTOFGIRLS:
			ss << gettext("Have a total of ") << obj->m_Target << gettext(" girls");
			fmt_objective(ss, "", obj->m_Limit, g_Brothels.GetTotalNumGirls(false));
			break;
		}
	}
	else ss << gettext("NONE\n");

	ss << gettext("\n")
		<< gettext("Current gold: ") << g_Gold.ival() << gettext("\n")
		<< gettext("Bank account: ") << g_Brothels.GetBankMoney() << gettext("\n")
		<< gettext("Businesses controlled: ")
		<< g_Gangs.GetNumBusinessExtorted()
		<< gettext("\n")
		;

	ss << gettext("\nCurrent number of runaways: ") << g_Brothels.GetNumRunaways() << gettext("\n");
	//	`J` added while loop to add runaway's names to the list 
	if (g_Brothels.GetNumRunaways() > 0)
	{
		sGirl* rgirl = g_Brothels.m_Runaways;
		while (rgirl)
		{
			ss << rgirl->m_Realname << gettext(" (") << rgirl->m_RunAway << gettext(")");
			rgirl = rgirl->m_Next;
			if (rgirl)	ss << gettext(" ,   ");
		}
	}

	EditTextItem(ss.str(), details_id);
	obj = 0;
}
Example #12
0
// `J` Job Brothel - General
bool cJobManager::WorkTorturer(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKTORTURER;
	if (Day0Night1) return false;		// Do this only once a day
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	if (g_Girls.DisobeyCheck(girl, actiontype, brothel))
	{
		ss << " refused to torture anyone.";
		girl->morality(1);
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " is assigned to torture people in the dungeon.";
	girl->morality(-1);

	g_Girls.EquipCombat(girl);	// ready armor and weapons!

	// Complications
#if 0
	if (g_Dice.percent(10))
	{
		g_Girls.UpdateEnjoyment(girl, actiontype, -3);
		ss << girlName << gettext(" hurt herself while torturing someone.");
		girl->m_Events.AddMessage(message, IMGTYPE_PROFILE, Day0Night1);
	}
	else
	{
		g_Girls.UpdateEnjoyment(girl, actiontype, +3);
		ss << girlName << gettext(" enjoyed her job working in the dungeon.");
		girl->m_Events.AddMessage(message, IMGTYPE_PROFILE, Day0Night1);
	}
#else
	//SIN: bit more variety for the above
	int roll(g_Dice % 5);
	bool forFree = false;
	if (g_Dice.percent(10))
	{
		g_Girls.UpdateEnjoyment(girl, actiontype, -3);
		if (g_Girls.HasTrait(girl, "Sadistic") || g_Girls.HasTrait(girl, "Merciless") || g_Girls.GetStat(girl, STAT_MORALITY) < 30)
			ss << girlName << gettext(" hurt herself while torturing someone.\n");
		else
		{
			switch (roll)
			{
			case 0:		ss << girlName << gettext(" felt bad torturing people as she could easily see herself in the victim.\n"); break;
			case 1:		ss << girlName << gettext(" doesn't like this as she feels it is wrong to torture people.\n"); break;
			case 2:		ss << girlName << gettext(" feels like a bitch after one of her torture victims wept the entire time and kept begging her to stop.\n"); break;
			case 3:		ss << girlName << gettext(" feels awful after accidentally whipping someone in an excruciating place.\n"); break;
			case 4:		ss << girlName << gettext(" didn't enjoy this as she felt sorry for the victim.\n"); break;
			default:	ss << girlName << gettext(" didn't enjoy this for some illogical reason. [error]\n"); break; //shouldn't happen
			}
			//And a little randomness
			if (g_Dice.percent(40))
			{
				roll = g_Dice % 3;
				switch (roll)
				{
				case 0:
					ss << gettext("She hates you for making her do this today.\n");
					g_Girls.UpdateStat(girl, STAT_PCLOVE, -(g_Dice % 2));
					g_Girls.UpdateStat(girl, STAT_PCHATE, g_Dice % 2);
					break;
				case 1:
					ss << girlName << gettext(" is terrified that you treat people like this.\n");
					g_Girls.UpdateStat(girl, STAT_PCFEAR, g_Dice % 6);
					g_Girls.UpdateStat(girl, STAT_OBEDIENCE, g_Dice % 2);
					break;
				case 2:
					ss << gettext("She learned a bit about medicine while trying to stop the pain.\n");
					g_Girls.UpdateSkill(girl, SKILL_MEDICINE, g_Dice % 10);
					break;
				default:
					ss << girlName << gettext(" did something completely unexpected. [error]");
					break;
				}
			}
		}
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
	}
	else
	{
		g_Girls.UpdateEnjoyment(girl, actiontype, +3);
		switch (roll)
		{
		case 0:		ss << girlName << gettext(" enjoyed her job working in the dungeon.\n"); break;
		case 1:		ss << girlName << gettext(" is turned on by the power of torturing people.\n"); break;
		case 2:		ss << girlName << gettext(" enjoyed trying out different torture devices and watching the effects on the victim.\n"); break;
		case 3:		ss << girlName << gettext(" spent her time in the dungeon whipping her victim in time to music to make amusing sound effects.\n"); break;
		case 4:		ss << girlName << gettext(" uses the victim's cries and screams to to figure out the 'best' areas to torture.\n"); break;
		default:	ss << girlName << gettext(" enjoyed this for some illogical reason. [error]\n"); break;
		}

		//And a little randomness
		if ((g_Girls.GetStat(girl, STAT_MORALITY) < 20 || g_Girls.HasTrait(girl, "Sadistic")) && g_Dice.percent(20))
		{
			ss << girlName << gettext(" loved this so much she wouldn't accept any money, as long as you promise she can do it again soon.\n");
			g_Girls.UpdateEnjoyment(girl, actiontype, +3);
			forFree = true;
		}
		if (g_Dice.percent(20))
		{
			roll = g_Dice % 4;
			switch (roll)
			{
			case 0:
				ss << girlName << gettext(" put so much energy into this it seems to have improved her fitness.\n");
				g_Girls.UpdateStat(girl, STAT_CONSTITUTION, g_Dice % 3);
				break;
			case 1:
				ss << girlName << gettext(" went way too far, creating a hell of a mess. Still it looks like she had fun - she hasn't stopped smiling.\n");
				g_Girls.UpdateStat(girl, STAT_HAPPINESS, g_Dice % 5);
				g_Girls.UpdateEnjoyment(girl, actiontype, +1);
				brothel->m_Filthiness += 15;
				break;
			case 2:
				ss << girlName << gettext(" over-exerted herself.");
				g_Girls.UpdateStat(girl, STAT_HEALTH, -(g_Dice % 5));
				g_Girls.UpdateStat(girl, STAT_TIREDNESS, g_Dice % 5);
				break;
			case 3:
				ss << girlName << gettext(" appreciates that you entrust her with this kind of work.");
				g_Girls.UpdateStat(girl, STAT_PCLOVE, g_Dice % 2);
				g_Girls.UpdateStat(girl, STAT_PCHATE, -(g_Dice % 2));
				break;
			default:
				ss << girlName << gettext(" did something completely unexpected. [error]");
				break;
			}
		}
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
	}
#endif

	// Improve girl
	int xp = 15, libido = 5, skill = 1;

	if (g_Girls.HasTrait(girl, "Quick Learner"))		{ skill += 1; xp += 3; }
	else if (g_Girls.HasTrait(girl, "Slow Learner"))	{ skill -= 1; xp -= 3; }
	if (g_Girls.HasTrait(girl, "Nymphomaniac"))			{ libido += 2; }

	if (!forFree)
	{
		girl->m_Pay += 65;
		g_Gold.staff_wages(65);  // wages come from you
	}

	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateStat(girl, STAT_MORALITY, -2);
	g_Girls.UpdateSkill(girl, SKILL_BDSM, skill);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	// WD: Update flag
	g_Brothels.TortureDone(true);

	// Check for new traits
	g_Girls.PossiblyGainNewTrait(girl, "Sadistic", 30, actiontype, girl->m_Realname + gettext(" has come to enjoy her job so much that she has become rather Sadistic."), Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Merciless", 50, actiontype, girl->m_Realname + gettext(" extensive experience with torture has made her absolutely Merciless."), Day0Night1);

	return false;
}
Example #13
0
void cScreenTown::init()
{
	if (BuyClinic != -1)
	{
		(g_ChoiceManager.GetChoice(0) == 0 ? GetClinic = true : BuyClinic = -1);
		g_ChoiceManager.Free();
	}
	if (GetClinic)
	{
		static_brothel_data *bpt = clinic_data + BuyClinic;
		g_Gold.brothel_cost(bpt->price);
		g_Clinic.NewBrothel(bpt->rooms, bpt->maxrooms);
		g_Clinic.SetName(0, gettext("Clinic"));
		GetClinic = false;
		BuyClinic = -1;
	}
	if (BuyCentre != -1)
	{
		(g_ChoiceManager.GetChoice(0) == 0 ? GetCentre = true : BuyCentre = -1);
		g_ChoiceManager.Free();
	}
	if (GetCentre)
	{
		static_brothel_data *bpt = centre_data + BuyCentre;
		g_Gold.brothel_cost(bpt->price);
		g_Centre.NewBrothel(bpt->rooms, bpt->maxrooms);
		g_Centre.SetName(0, gettext("Centre"));
		GetCentre = false;
		BuyCentre = -1;
	}
	if (BuyArena != -1)
	{
		(g_ChoiceManager.GetChoice(0) == 0 ? GetArena = true : BuyArena = -1);
		g_ChoiceManager.Free();
	}
	if (GetArena)
	{
		static_brothel_data *bpt = arena_data + BuyArena;

		g_Gold.brothel_cost(bpt->price);
		g_Arena.NewBrothel(bpt->rooms, bpt->maxrooms);
		g_Arena.SetName(0, gettext("Arena"));

		GetArena = false;
		BuyArena = -1;
	}
	if (BuyStudio != -1)
	{
		(g_ChoiceManager.GetChoice(0) == 0 ? GetStudio = true : BuyStudio = -1);
		g_ChoiceManager.Free();
	}
	if (GetStudio)
	{
		static_brothel_data *bpt = studio_data + BuyStudio;
		g_Gold.brothel_cost(bpt->price);
		g_Studios.NewBrothel(bpt->rooms, bpt->maxrooms);
		g_Studios.SetName(0, gettext("Studio"));
		GetStudio = false;
		BuyStudio = -1;
	}
	if (BuyFarm != -1)
	{
		(g_ChoiceManager.GetChoice(0) == 0 ? GetFarm = true : BuyFarm = -1);
		g_ChoiceManager.Free();
	}
	if (GetFarm)
	{
		static_brothel_data *bpt = farm_data + BuyFarm;
		g_Gold.brothel_cost(bpt->price);
		g_Farm.NewBrothel(bpt->rooms, bpt->maxrooms);
		g_Farm.SetName(0, gettext("Farm"));
		GetFarm = false;
		BuyFarm = -1;
	}
	if (GetName)
	{
		if (g_ReturnText != "")
		{
			if (g_Brothels.GetObjective() && g_Brothels.GetObjective()->m_Objective == OBJECTIVE_GETNEXTBROTHEL) 
				g_Brothels.PassObjective();
			static_brothel_data *bpt = brothel_data + BuyBrothel;
			g_Gold.brothel_cost(bpt->price);
			g_Brothels.NewBrothel(bpt->rooms, bpt->maxrooms);
			g_Brothels.SetName(g_Brothels.GetNumBrothels() - 1, g_ReturnText);
			g_InitWin = true;
		}
		GetName = false;
		BuyBrothel = -1;
	}
	if (BuyBrothel != -1)
	{
		if (g_ChoiceManager.GetChoice(0) == 0)
		{
			g_MessageQue.AddToQue("Enter a name for your new brothel.", 0);
			GetName = true;
			g_InitWin = true;
			g_WinManager.Push(GetString, &g_GetString);
		}
		else BuyBrothel = -1;
		g_ChoiceManager.Free();
		if (!GetName) BuyBrothel = -1;
		return;
	}
	g_CurrentScreen = SCREEN_TOWN;
	if (!g_InitWin) return;

	Focused();
	g_InitWin = false;

	// buttons enable/disable
	DisableButton(walk_id, g_WalkAround);

	HideButton(brothel2_id, (g_Brothels.GetBrothel(1) == 0));
	HideButton(brothel3_id, (g_Brothels.GetBrothel(2) == 0));
	HideButton(brothel4_id, (g_Brothels.GetBrothel(3) == 0));
	HideButton(brothel5_id, (g_Brothels.GetBrothel(4) == 0));
	HideButton(brothel6_id, (g_Brothels.GetBrothel(5) == 0));

	string brothel = "Current Brothel: ";
	brothel += g_Brothels.GetName(g_CurrBrothel);
	EditTextItem(brothel, curbrothel_id);
}
Example #14
0
// `J` Job Centre - General
bool cJobManager::WorkFeedPoor(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKCENTRE;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	int roll_a = g_Dice.d100(), roll_b = g_Dice.d100(), roll_c = g_Dice.d100();
	if (g_Girls.DisobeyCheck(girl, ACTION_WORKCENTRE, brothel))			// they refuse to work 
	{
		ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked feeding the poor.";

	g_Building = BUILDING_CENTRE;
	g_Girls.UnequipCombat(girl);	// put that shit away, you'll scare off the customers!

	bool blow = false, sex = false;
	double wages = 20, tips = 0;
	int enjoy = 0, feed = 0, fame = 0;

	int imagetype = IMGTYPE_PROFILE;
	int msgtype = Day0Night1;

#pragma endregion
#pragma region //	Job Performance			//

	double jobperformance = JP_FeedPoor(girl, false);


	//Adding cust here for use in scripts...
	sCustomer* Cust = new sCustomer;
	GetMiscCustomer(brothel, Cust);


	int dispo; // `J` merged slave/free messages and moved actual dispo change to after
	if (jobperformance >= 245)
	{
		ss << " She must be perfect at this.\n\n";
		dispo = 12;
		if (roll_b <= 20)
		{
			ss << "Today " << girlName << " was managing the kitchen giving orders to other cooks and checking the quality of their work.\n";
		}
		else if (roll_b <= 40)
		{
			ss << girlName << " was helping in the kitchen. Her task was to stir-fry vegetables. One word: Perfection. Food that she prepared was great!\n";
		}
		else if (roll_b <= 60)
		{
			ss << "Being done with the main dish earlier, " << girlName << " decided to bake cookies for desert!\n";
		}
		else if (roll_b <= 80)
		{
			ss << "Excellent dish! Some world class chefs should learn from " << girlName << "!\n";
		}
		else
		{
			ss << girlName << " knife skill is impressive. She's cutting precisely and really fast, almost like a machine.\n";
		}
	}
	else if (jobperformance >= 185)
	{
		ss << " She's unbelievable at this and is always getting praised by people for her work.\n\n";
		dispo = 10;
		if (roll_b <= 20)
		{
			ss << girlName << " is in charge of the cooking for several weeks now. You could swear that the population of rodents and small animals in the area went down.\n";
		}
		else if (roll_b <= 40)
		{
			ss << "While preparing for today's cooking, " << girlName << " noticed that one of the crucial ingredients is missing. She manage to change the menu and fully use available ingredients.\n";
		}
		else if (roll_b <= 60)
		{
			ss << "She speedily served all in line at the food counter. All the portions handed out were equal.\n";
		}
		else if (roll_b <= 80)
		{
			ss << "Preparing something new she mixed up the proportions from the recipe. The outcome tasted great!\n";
		}
		else
		{
			ss << girlName << " was helping in the kitchen. Her task was to prepare the souse for today's meatballs. The texture and flavor was top notch.\n";
		}
	}
	else if (jobperformance >= 145)
	{
		ss << " She's good at this job and gets praised by people often.\n\n";
		dispo = 8;
		if (roll_b <= 20)
		{
			ss << "While cooking she used everything that was in the kitchen. Nothing was wasted.\n";
		}
		else if (roll_b <= 40)
		{
			ss << "While cooking she accidentally sneezed into the pot. Luckily nobody saw that.\n";
		}
		else if (roll_b <= 60)
		{
			ss << girlName << " was helping in the kitchen. Her task was to carve the meat. Smile on her face that appear while doing this, was somehow scary and disturbing.\n";
		}
		else if (roll_b <= 80)
		{
			ss << girlName << " was doing the dishes. Most of them \"survived\" and will be used next time.\n";
		}
		else
		{
			ss << "She spent her shift at the food counter without any trouble.\n";
		}
	}
	else if (jobperformance >= 100)
	{
		ss << " She made a few mistakes but overall she is okay at this.\n\n";
		dispo = 6;
		if (roll_b <= 20)
		{
			ss << "Her cooking isn't very good. But You probably would risk serving the prepared dish to a dog.\n";
		}
		else if (roll_b <= 40)
		{
			ss << "Today she was assign as the cook. Not being able to focus on the task at hand, she overcooked the pasta.\n";
		}
		else if (roll_b <= 60)
		{
			ss << "She served all in line at the food counter. Some portions were smaller than others.\n";
		}
		else if (roll_b <= 80)
		{
			ss << girlName << " was helping in the kitchen. Her task was to make a salad. She manage to do this much.\n";
		}
		else
		{
			ss << "When walking with a pile of clean dished she slipped and fall. All the plates got broken.\n";
		}
	}
	else if (jobperformance >= 70)
	{
		ss << " She was nervous and made a few mistakes. She isn't that good at this.\n\n";
		dispo = 4;
		if (roll_b <= 20)
		{
			ss << "Today she was assign as the cook. Meatballs that she prepared could be used as lethal projectiles.\n";
		}
		else if (roll_b <= 40)
		{
			ss << girlName << " was doing the dishes. Let's say it would be a lot quicker to throw them all right away, then wait for her to brake so many during this simple chore.\n";
		}
		else if (roll_b <= 60)
		{
			ss << "While cooking she burned two, brand new pots!\n";
		}
		else if (roll_b <= 80)
		{
			ss << girlName << " was helping in the kitchen. Her task was to dice the carrots. Surely the carrots were cut, but to called them diced would be an exaggeration.\n";
		}
		else
		{
			ss << "Just wanting to serve the food fast to end her shift. She did a sloppy job at the food counter.\n";
		}
	}
	else
	{
		ss << " She was nervous and constantly making mistakes. She really isn't very good at this job.\n\n";
		dispo = 2;
		if (roll_b <= 20)
		{
			ss << "While preparing ingredients for the soup she almost cut off her hand!\n";
		}
		else if (roll_b <= 40)
		{
			ss << girlName << " was helping in the kitchen. Her task was to peel the potatoes. The peels were thick and had a lot of the vegetable left on them. What a waste!\n";
		}
		else if (roll_b <= 60)
		{
			ss << "Today she was assigned as the cook. The thing that she created hardly could be called food.\n";
		}
		else if (roll_b <= 80)
		{
			ss << "Today she was assigned to work at the food counter. While handing out food she served different portions to people in line.\n";
		}
		else
		{
			ss << "Being assigned to the food counter, she putted a sign \"self serving\" and went out.\n";
		}
	}


	//try and add randomness here
	if (g_Girls.GetStat(girl, STAT_INTELLIGENCE) < 55 && g_Dice.percent(30))//didnt put a check on this one as we could use some randomness and its an intel check... guess we can if people keep bitching
	{
		blow = true;	ss << "An elderly fellow managed to convince " << girlName << " that he was full and didn't need anymore food but that she did. He told her his c**k gave a special treat if she would suck on it long enough. Which she did man she isn't very smart.\n\n";
	}

	if (g_Girls.HasTrait(girl, "Nymphomaniac") && g_Dice.percent(30) && g_Girls.GetStat(girl, STAT_LIBIDO) > 75
		&& !g_Girls.HasTrait(girl, "Lesbian") && !g_Girls.HasTrait(girl, "Virgin")
		&& (!brothel->m_RestrictNormal || !brothel->m_RestrictAnal))
	{
		sex = true;
		ss << "Her Nymphomania got the better of her today and she decided to let them eat her pussy!  After a few minutes they started f*****g her.\n";
	}



	if (girl->m_States&(1 << STATUS_SLAVE))
	{
		ss << "\nThe fact that she is your slave makes people think its less of a good deed on your part.";
		The_Player->disposition(dispo);
		wages = 0;
	}
	else
	{
		ss << "\nThe fact that your paying this girl to do this helps people think your a better person.";
		g_Gold.staff_wages(100);  // wages come from you
		The_Player->disposition(int(dispo*1.5));
	}




#pragma endregion
#pragma region	//	Enjoyment and Tiredness		//

	//enjoyed the work or not
	if (roll_a <= 5)
	{
		ss << "\nSome of the patrons abused her during the shift."; 
		enjoy -= 1;
	}
	else if (roll_a <= 25)
	{
		ss << "\nShe had a pleasant time working."; 
		enjoy += 3;
	}
	else
	{
		ss << "\nOtherwise, the shift passed uneventfully."; 
		enjoy += 1;
	}


	if (sex)
	{
		if (!brothel->m_RestrictNormal && (roll_b <= 50 || brothel->m_RestrictAnal)) //Tweak to avoid an issue when roll > 50 && anal is restricted
		{
			girl->m_Events.AddMessage(ss.str(), IMGTYPE_SEX, Day0Night1);
			g_Girls.UpdateSkill(girl, SKILL_NORMALSEX, 2);
			if (g_Girls.CheckVirginity(girl))
			{
				g_Girls.LoseVirginity(girl);	// `J` updated for trait/status
				ss << "She is no longer a virgin.\n";
			}
			if (!girl->calc_pregnancy(Cust, false, 1.0))
			{
				g_MessageQue.AddToQue(girl->m_Realname + " has gotten pregnant", 0);
			}
		}
		else if (!brothel->m_RestrictAnal)
		{
			girl->m_Events.AddMessage(ss.str(), IMGTYPE_ANAL, Day0Night1);
			g_Girls.UpdateSkill(girl, SKILL_ANAL, 2);
		}
		brothel->m_Happiness += 100;
		g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -20);
		g_Girls.UpdateEnjoyment(girl, ACTION_SEX, +3);
		fame += 1;
		dispo += 6;
	}
	else if (blow)
	{
		brothel->m_Happiness += (g_Dice % 70) + 60;
		dispo += 4;
		g_Girls.UpdateSkill(girl, SKILL_ORALSEX, 2);
		fame += 1;
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_ORAL, Day0Night1);
	}
	else
	{
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
	}

#pragma endregion
#pragma region	//	Money					//


#pragma endregion
#pragma region	//	Finish the shift			//

	// Money
	if (wages < 0)	wages = 0;	girl->m_Pay = (int)wages;
	if (tips < 0)	tips = 0;	girl->m_Tips = (int)tips;

	feed += (int)(jobperformance / 10);		//  1 feed per 10 point of performance

	int cost = 0;
	for (int i = 0; i < feed; i++)
	{
		cost += g_Dice % 3 + 2; // 2-5 gold per customer
	}
	brothel->m_Finance.centre_costs(cost);
	ss.str("");
	ss << girlName << " feed " << feed << " costing you " << cost << " gold.";
	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);


	// Improve stats
	int xp = 10, libido = 1, skill = 3;

	if (g_Girls.HasTrait(girl, "Quick Learner"))		{ skill += 1; xp += 3; }
	else if (g_Girls.HasTrait(girl, "Slow Learner"))	{ skill -= 1; xp -= 3; }
	if (g_Girls.HasTrait(girl, "Nymphomaniac"))			{ libido += 2; }
	if (girl->fame() < 10 && jobperformance >= 70)		{ fame += 1; }
	if (girl->fame() < 20 && jobperformance >= 100)		{ fame += 1; }
	if (girl->fame() < 40 && jobperformance >= 145)		{ fame += 1; }
	if (girl->fame() < 50 && jobperformance >= 185)		{ fame += 1; }


	g_Girls.UpdateStat(girl, STAT_FAME, fame);
	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	if (g_Dice % 2)
		g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, 1);
	g_Girls.UpdateSkill(girl, SKILL_SERVICE, skill);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);


	delete Cust;

#pragma endregion
	return false;
}