Example #1
0
void cGirlTorture::UpdateTraits()
{
	int nWeekMod = 1;
	bool harshtorture = false;
	/* `J` added to allow permanent trait gain on torture
	if TortureTraitWeekMod is set to a negative number in the config.xml
	then "Broken Will", "M*******t" and "Mind F****d" are permanent
	doubles chance of injuring girls when torturing them
	evil gained from torture is also doubled  */
	if (cfg.initial.torture_mod() < 0){ harshtorture = true; }
	else	{ nWeekMod = cfg.initial.torture_mod() * m_DungeonGirl->m_Weeks; }

	if (g_Dice.percent(30) && m_Girl->spirit() < 20 && m_Girl->health() < 20)
	{
		if (harshtorture)	{ m_Girl->add_trait("Broken Will", false); }
		else				{ m_Girl->add_trait("Broken Will", 5 + nWeekMod / 2); }
	}
	if (g_Dice.percent(30) && m_Girl->bdsm() > 30)
	{
		if (harshtorture)	{ m_Girl->add_trait("M*******t", false); }
		else				{ m_Girl->add_trait("M*******t", 10 + nWeekMod); }
	}
	if (g_Dice.percent(30) && m_Girl->health() < 10)
	{
		if (harshtorture)	{ m_Girl->add_trait("Mind F****d", false); }
		else				{ m_Girl->add_trait("Mind F****d", 10 + nWeekMod); }
	}
}
void cCustomers::SetGoals(sCustomer* customer)
{
	if (!customer) return;
	int a = g_Dice % NUM_GOALS, b = g_Dice % NUM_GOALS, c = g_Dice % NUM_GOALS;
	
	if ((g_Dice.percent(50) && a == GOAL_FIGHT) || (g_Dice.percent(80) && a == GOAL_RAPE))
	{
		customer->m_GoalA  = GOAL_SEX;
		customer->m_GoalB  = GOAL_FIGHT;
		customer->m_GoalC  = GOAL_RAPE;
		return;
	}


	// GOAL_UNDECIDED
	// GOAL_FIGHT
	// GOAL_RAPE
	// GOAL_SEX
	// GOAL_GETDRUNK
	// GOAL_GAMBLE
	// GOAL_ENTERTAINMENT
	// GOAL_XXXENTERTAINMENT
	// GOAL_MASSAGE
	// GOAL_STRIPSHOW
	// GOAL_FREAKSHOW
	// GOAL_CULTURALEXPLORER
	// GOAL_OTHER

	customer->m_GoalA = a;
	customer->m_GoalB = b;
	customer->m_GoalC = c;
}
Example #3
0
void cGirlTorture::add_trait(string trait, int pc)
{
	if (m_Girl->has_trait(trait)) return;
	/*
	*	WD:	To balance a crash bug workaround for Job Torturer
	*		unable to call GirlGangFight()
	*		Halve chance of gaining trait
	*/
	if (!m_TorturedByPlayer) pc /= 2;
	if (!g_Dice.percent(pc)) return;

	string sMsg = m_Girl->m_Realname + gettext(" has gained trait \"") + trait + gettext("\" from being tortured.");

	if (m_TorturedByPlayer)
	{
		g_MessageQue.AddToQue(sMsg, 2);
		m_Girl->m_Events.AddMessage(sMsg, IMGTYPE_TORTURE, EVENT_WARNING);
	}
	else MakeEvent(sMsg);

	// Add trait
	m_Girl->add_trait(trait);
}
Example #4
0
// `J` Job Farm - Laborers
bool cJobManager::WorkMilker(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKFARM;
	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, actiontype, 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 as a milker on the farm.\n\n";

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

	double wages = 20, tips = 0;
	int enjoy = 0;
	int imagetype = IMGTYPE_FARM;
	int msgtype = Day0Night1;

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

	double jobperformance = JP_Milker(girl, false);
	double drinks = jobperformance / 2;

	if (jobperformance >= 245)
	{
		ss << "Her milk bucket practically fills itself as she walks down the rows of cows.";
		drinks *= 5; roll_a += 10; roll_b += 25;
	}
	else if (jobperformance >= 185)
	{
		ss << "Her hands moved like lightning as she gracefully milks the cows teats.";
		drinks *= 4; roll_a += 5; roll_b += 18;
	}
	else if (jobperformance >= 145)
	{
		ss << "She knows exactly when the cows are ready to be milked and how to best milk them.";
		drinks *= 3; roll_a += 2; roll_b += 10;
	}
	else if (jobperformance >= 100)
	{
		ss << "She can milk the cows without spilling much.";
		drinks *= 2;
	}
	else if (jobperformance >= 70)
	{
		ss << "She isn't very good at aiming the teats into the bucket.";
		roll_a -= 2; roll_b -= 5;
	}
	else
	{
		ss << "She can't seem to get the hang of this.";
		wages -= 10; drinks *= 0.8; roll_a -= 5; roll_b -= 10;
	}
	ss << "\n\n";

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

	// Complications
	if (roll_a <= 10)
	{
		enjoy -= g_Dice % 3 + 1;
		ss << "The animals were uncooperative and some didn't even let her get near them.\n";
		drinks *= 0.8;
		if (g_Dice.percent(20))
		{
			enjoy--;
			ss << "Several animals kicked over the milking buckets and soaked " << girlName << ".\n";
			girl->happiness(-(1 + g_Dice % 5));
			drinks -= (5 + g_Dice % 6);
		}
		if (g_Dice.percent(20))
		{
			enjoy--;
			ss << "One of the animals urinated on " << girlName << " and contaminated the milk she had collected.\n";
			girl->happiness(-(1 + g_Dice % 3));
			drinks -= (5 + g_Dice % 6);
		}
		if (g_Dice.percent(20))
		{
			enjoy--;
			int healthmod = g_Dice % 10 + 1;
			girl->health(-healthmod);
			girl->happiness(-(healthmod + g_Dice % healthmod));
			ss << "One of the animals kicked " << girlName << " and ";
			if (girl->health() < 1)
			{
				ss << "killed her.\n";
				g_MessageQue.AddToQue(girlName + " was killed when an animal she was milking kicked her in the head.", COLOR_RED);
				return false;	// not refusing, she is dead
			}
			else ss << (healthmod > 5 ? "" : "nearly ") << "broke her arm.\n";
			drinks -= (5 + g_Dice % 6);
		}
	}
	else if (roll_a >= 90)
	{
		enjoy += g_Dice % 3 + 1;
		ss << "The animals were pleasant and cooperative today.\n";
		drinks *= 1.2;
	}
	else
	{
		enjoy += g_Dice % 2;
		ss << "She had an uneventful day milking.\n";
	}

#pragma endregion
#pragma region	//	Money					//

	// slave girls not being paid for a job that normally you would pay directly for do less work
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		drinks *= 0.9;
		wages = 0;
	}
	else
	{
		wages += drinks / 100; // `J` Pay her based on how much she brought in
	}

#pragma endregion
#pragma region	//	Create Items				//

	int milk = int(drinks / 10);	// plain milk is made here, breast milk from girls is made in WorkMilk
	if (milk > 0)
	{
		int milkmade[5] = { 0, 0, 0, 0, 0 };	// (total,gallon,quart,pint,shots}
		// check if the milk items exist and only do the checks if at least one of them does
		sInventoryItem* milkitems[4] = { g_InvManager.GetItem("Milk"), g_InvManager.GetItem("Milk (pt)"), g_InvManager.GetItem("Milk (qt)"), g_InvManager.GetItem("Milk (g)") };
		if (milkitems[0] != 0 || milkitems[1] != 0 || milkitems[2] != 0 || milkitems[3] != 0)
		{
			while (milk > 0)	// add milk
			{
				sInventoryItem* item = NULL;
				string itemname = "";
				/* */if (milkitems[3] && milk > 3 && g_Dice.percent(30))
				{
					milk -= 4;
					milkmade[0]++;
					milkmade[4]++;
					g_Brothels.AddItemToInventory(milkitems[3]);
				}
				else if (milkitems[2] && milk > 2 && g_Dice.percent(50))
				{
					milk -= 3;
					milkmade[0]++;
					milkmade[3]++;
					g_Brothels.AddItemToInventory(milkitems[2]);
				}
				else if (milkitems[1] && milk > 1 && g_Dice.percent(70))
				{
					milk -= 2;
					milkmade[0]++;
					milkmade[2]++;
					g_Brothels.AddItemToInventory(milkitems[1]);
				}
				else if (milkitems[0])
				{
					milk -= 1;
					milkmade[0]++;
					milkmade[1]++;
					g_Brothels.AddItemToInventory(milkitems[0]);
				}
				else milk--;	// add a reducer just in case.
			}
		}
		if (milkmade[0] > 0)
		{
			ss << girlName << " produced " << milkmade[0] << " bottles of milk for you, \n";
			if (milkmade[4] > 0) ss << milkmade[4] << " gallons\n";
			if (milkmade[3] > 0) ss << milkmade[3] << " quarts\n";
			if (milkmade[2] > 0) ss << milkmade[2] << " pints\n";
			if (milkmade[1] > 0) ss << milkmade[1] << " shots\n";
		}
	}

	// `J` zzzzzz - need to add the girl milking herself - can be done easier after WorkMilk is done



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

	ss << "\n" << girlName;
	if ((int)drinks > 0)
	{
		g_Brothels.add_to_drinks((int)drinks);
		ss << " brought in " << (int)drinks << " units of milk.";
	}
	else { ss << " was unable to collect any milk."; }

	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);

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

	// Improve stats
	int xp = 5, 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; }

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	// primary (+2 for single or +1 for multiple)
	g_Girls.UpdateSkill(girl, SKILL_ANIMALHANDLING, (g_Dice % skill) + 2);
	// secondary (-1 for one then -2 for others)
	g_Girls.UpdateSkill(girl, SKILL_HANDJOB, max(0, (g_Dice % skill) - 1));
	g_Girls.UpdateSkill(girl, SKILL_FARMING, max(0, (g_Dice % skill) - 2));
	g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, max(0, (g_Dice % skill) - 2));

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);


#pragma endregion
	return false;
}
Example #5
0
bool cGirlTorture::IsGirlInjured(unsigned int unModifier)
{  // modifier: 5 = 5% chance, 10 = 10% chance

	// Sanity check, Can't get injured
	if (m_Girl->has_trait("Incorporeal")) return false;


	/*
	*	WD	Injury was only possible if girl is pregnant or
	*		hasn't got the required traits.
	*
	*		Now check for injury first
	*		Use usigned int so can't pass negative chance
	*/
	string	sMsg;
	string	sGirlName = m_Girl->m_Realname;
	int		nMod = static_cast<int>(unModifier);
	if (cfg.initial.torture_mod() < 0){ nMod += nMod; }


	if (m_Girl->has_trait("Fragile"))	nMod += nMod;	// nMod *= 2;
	if (m_Girl->has_trait("Tough"))		nMod /= 2;
	if (nMod < 1) nMod = 1;		// `J` always at least a 1% chance

	// Did the girl get injured
	if (!g_Dice.percent(nMod)) return false;
	/*
	*	INJURY PROCESSING
	*	Only injured girls continue past here
	*/

	// Post any outstanding Player messages
	if (m_TorturedByPlayer && !m_Message.empty())
	{
		g_MessageQue.AddToQue(m_Message, 0);
		m_Girl->m_Events.AddMessage(m_Message, IMGTYPE_TORTURE, EVENT_SUMMARY);	// `J` added

		m_Message = sGirlName + ": ";
	}

	// getting hurt badly could lead to scars
	if (g_Dice.percent(nMod * 2) &&
		!m_Girl->has_trait("Small Scars") &&
		!m_Girl->has_trait("Cool Scars") &&
		!m_Girl->has_trait("Horrific Scars"))
	{
		int chance = g_Dice % 6;
		if (chance == 0)
		{
			m_Girl->add_trait("Horrific Scars", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("She was badly injured, and now has to deal with Horrific Scars.\n");
			else
				MakeEvent(sGirlName + gettext(" was badly injured, and now has Horrific Scars.\n"));
		}
		else if (chance <= 2)
		{
			m_Girl->add_trait("Small Scars", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("She was injured and now has a couple of Small Scars.\n");
			else
				MakeEvent(sGirlName + gettext(" was injured, and now has Small Scars.\n"));
		}
		else
		{
			m_Girl->add_trait("Cool Scars", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("She was injured and scarred. As scars go however, at least they are pretty Cool Scars.\n");
			else
				MakeEvent(sGirlName + gettext(" was injured and scarred. She now has Cool Scars.\n"));
		}
	}

	// in rare cases, she might even lose an eye
	if (g_Dice.percent((nMod / 2)) &&
		!m_Girl->has_trait("One Eye") &&
		!m_Girl->has_trait("Eye Patch"))
	{
		int chance = g_Dice % 3;
		if (chance == 0)
		{
			m_Girl->add_trait("One Eye", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("Oh, no! She was badly injured, and now only has One Eye!\n");
			else
				MakeEvent(sGirlName + gettext(" was badly injured and lost an eye.\n"));
		}
		else
		{
			m_Girl->add_trait("Eye Patch", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("She was injured and lost an eye, but at least she has a cool Eye Patch to wear.\n");
			else
				MakeEvent(sGirlName + gettext(" was injured and lost an eye, but at least she has a cool Eye Patch to wear.\n"));
		}
	}

	// or lose tough or become fragile
	if (m_Girl->has_trait("Tough"))
	{
		if (g_Dice.percent(nMod))
		{
			g_Girls.RemoveTrait(m_Girl, "Tough", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("Her body has become less Tough due to the extent of her injuries.\n");
			else
				MakeEvent("Due to " + sGirlName + gettext(" injuries her body has become less Tough.\n"));
		}
	}
	else if (!m_Girl->has_trait("Fragile"))
	{
		if (g_Dice.percent(nMod / 2))
		{
			m_Girl->add_trait("Fragile", false);
			if (m_TorturedByPlayer)
				m_Message += gettext("Her body has become rather Fragile due to the extent of her injuries.\n");
			else
				MakeEvent("Due to " + sGirlName + gettext(" injuries her body has become fragile.\n"));
		}
	}

	// and if pregnant, she might lose the baby; I'll assume inseminations can't be aborted so easily
	if ((m_Girl->carrying_human() && g_Dice.percent(nMod * 2)) ||
		(m_Girl->carrying_monster() && g_Dice.percent(nMod)))	// `J` added insemination loss chance
	{  // unintended abortion time
		//injured = true;
		m_Girl->m_ChildrenCount[CHILD08_MISCARRIAGES]++;
		m_Girl->clear_pregnancy();
		m_Girl->happiness(-20);
		m_Girl->spirit(-5);
		if (m_TorturedByPlayer)
			m_Message += gettext("Her unborn child has been lost due to the injuries she sustained, leaving her quite distraught.\n");
		else
			MakeEvent(gettext("Due to ") + sGirlName + gettext(" injuries she has had a miscarriage, leaving her quite distraught.\n"));
	}


	int damage = 5 + g_Dice % 10;								// Lose between 5 - 14 hp
	if (cfg.initial.torture_mod() < 0){ damage += damage / 2; }	// `J` Lose between 7 - 21 hp if harsh torture
	m_Girl->health(-damage);


	// Post any new Player messages in Red Message Box Colour 1 
	if (m_TorturedByPlayer && !m_Message.empty() && m_Message != sGirlName + ": ")
	{
		g_MessageQue.AddToQue(m_Message, COLOR_RED);
		m_Girl->m_Events.AddMessage(m_Message, IMGTYPE_TORTURE, EVENT_DAYSHIFT);	// `J` added

		m_Message = sGirlName + ": ";
	}

	return true;
}
// `J` Job Brothel - Brothel
bool cJobManager::WorkPeepShow(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
    int actiontype = ACTION_WORKSTRIP;
    stringstream ss;
    string girlName = girl->m_Realname;
    ss << girlName;
    if (g_Girls.DisobeyCheck(girl, actiontype, brothel))
    {
        ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
        girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
        return true;
    }
    ss << " let the customers watch her get naked.\n\n";

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


    int wages = g_Girls.GetStat(girl, STAT_ASKPRICE) + g_Dice % 50;
    int tips = max((g_Dice % 50) - 10, 0);
    double mod = 0.0;
    int imagetype = IMGTYPE_STRIP, enjoyment = 0;
    u_int sextype = SKILL_STRIP;
    int roll = g_Dice.d100();
    sCustomer* Cust = new sCustomer;


    double jobperformance = JP_PeepShow(girl, false);


    if (jobperformance >= 245)
    {
        mod = 3.0;
        ss << "She must be the perfect teaser she never goes to fast but never to slow, she knows just when to do things. The customers can't get enough of her.\n\n";
        /* */if (roll <= 20) {
            ss << "Knowing every trick in the book and not hesitating to use them, she makes a lot of money today.\n";
        }
        else if (roll <= 40) {
            ss << "She is just a gold mine.\n";
        }
        else if (roll <= 60) {
            ss << "She certainly knows how to sell the show. After hours of teasing she finally gets naked.\n";
        }
        else if (roll <= 80) {
            ss << girlName << " was requested by name by a single customer. He paid double of her daily earnings for the privilege of getting an exclusive performance.\n";
        }
        else { /*           */
            ss << girlName << " is performing today. Like always the cleaning crew have a lot of work after her shows.\n";
        }
    }
    else if (jobperformance >= 185)
    {
        mod = 2.0;
        ss << "She is unbelievable at this and is always finding new ways of pleasing the customers.\n\n";
        /* */if (roll <= 20) {
            ss << "She is really good at this, knowing how to tease customers into staying and paying for hours.\n";
        }
        else if (roll <= 40) {
            ss << girlName << " swinging her boobs and ass in a very sexual way. As a result causing heavy breathing from the booths.\n";
        }
        else if (roll <= 60) {
            ss << "Her body movement is flawless and very sensual, earning a nice sum today.\n";
        }
        else if (roll <= 80) {
            ss << girlName << " gave a very good performance, making her clients very satisfied with the time they spent here.\n";
        }
        else { /*           */
            ss << girlName << " was requested by name by a group of customers. She gave them a special performance for a really high price.\n";
        }
    }
    else if (jobperformance >= 145)
    {
        mod = 1.5;
        ss << "She's good at this job and knows a few tricks to drive the customers wild.\n\n";
        /* */if (roll <= 20) {
            ss << "She has a good body and sense of rhythm, but she strips too fast, so she make less money from today performance.\n";
        }
        else if (roll <= 40) {
            ss << "She makes the mistake of getting naked too fast, ending the show prematurely.\n";
        }
        else if (roll <= 60) {
            ss << "She certainly has the skills for this job, but with more work she will get even better.\n";
        }
        else if (roll <= 80) {
            ss << girlName << " comes on stage with some 'toys' that she uses to prolong her performance.\n";
        }
        else { /*           */
            ss << "Having confidence in her skills, " << girlName << " gives a very good performance.\n";
        }
    }
    else if (jobperformance >= 100)
    {
        mod = 1.0;
        ss << "She made a few mistakes but overall she is okay at this.\n\n";
        /* */if (roll <= 20) {
            ss << girlName << " can strip and people come here to see her do that but there is nothing extraordinary in her performance.\n";
        }
        else if (roll <= 40) {
            ss << "Pretty boring show, But at least she gets naked all the way thru.\n";
        }
        else if (roll <= 60) {
            ss << "Having stage fright, her movement seems mechanical, leaving paying customers unsatisfied.\n";
        }
        else if (roll <= 80) {
            ss << "Not too confident in herself, " << girlName << "'s tense performance rubs off on the customers.\n";
        }
        else { /*           */
            ss << "She did good today. With improving her skills, " << girlName << " could become one of the best.\n";
        }
    }
    else if (jobperformance >= 70)
    {
        mod = 0.9;
        ss << "She was nervous and made a few mistakes. She isn't that good at this.\n\n";
        /* */if (roll <= 20) {
            ss << "When it was time for " << girlName << " to take off her panties, she collapsed on the floor covering her breasts and crying.\n";
        }
        else if (roll <= 40) {
            ss << "Not being able to unbuckle her fancy bra, she struggled for minutes. Some of the customers left demanding their money back.\n";
        }
        else if (roll <= 60) {
            ss << "She gets naked but in a boring and not exciting way.\n";
        }
        else if (roll <= 80) {
            ss << "Trying a more advanced pose, she hurts herself, falling painfully on the floor.\n";
        }
        else { /*           */
            ss << girlName << " definitely tries to give a good performance, but having only good will isn't enough.\n";
        }
    }
    else
    {
        mod = 0.8;
        ss << "She was nervous and constantly making mistakes. She really isn't very good at this job.\n\n";
        /* */if (roll <= 20) {
            ss << "She is awful at this job. Her stage movement and striptease are lifeless.\n";
        }
        else if (roll <= 40) {
            ss << "Her stripping ability could be compared to getting undressed before a shower.\n";
        }
        else if (roll <= 60) {
            ss << "Her show was so bad, that you could swear you heard snoring from one booth.\n";
        }
        else if (roll <= 80) {
            ss << "When trying to take off her t-shirt, " << girlName << "'s head got stuck for minutes.\n";
        }
        else { /*           */
            ss << "Trying to give her best, " << girlName << " gave a poor performance.\n";
        }
    }


    //try and add randomness here
    if (g_Girls.GetStat(girl, STAT_LIBIDO) > 80)
    {
        if (g_Girls.HasTrait(girl, "Lesbian") && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus")))
        {
            ss << "\nShe was horny and she loves sex so she brought in another girl and had sex with her while the customers watched.\n";
            sextype = SKILL_LESBIAN;
            /* `J` g_Girls.GirlFucks handles skill gain from sex
            g_Girls.UpdateSkill(girl, SKILL_LESBIAN, 1);
            //*/
        }
        else if (g_Girls.HasTrait(girl, "Bisexual") && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus")))
        {
            if (roll <= 50)
            {
                ss << "\nShe was horny and she loves sex so she brought in another girl and had sex with her while the customers watched.\n";
                sextype = SKILL_LESBIAN;
                /* `J` g_Girls.GirlFucks handles skill gain from sex
                g_Girls.UpdateSkill(girl, SKILL_LESBIAN, 1);
                //*/
            }
            else
            {
                ss << "\nShe was horny and she loves sex so she brought in one of the customers and had sex with him while the others watched.";
                sextype = SKILL_NORMALSEX;
            }
        }
        else if (g_Girls.HasTrait(girl, "Straight") && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus")))
        {
            ss << "\nShe was horny and she loves sex so she brought in one of the customers and had sex with him while the others watched.\n";
            sextype = SKILL_NORMALSEX;
        }
        //New stuff
        else if (g_Girls.HasTrait(girl, "Futanari"))
        {
            //Addiction bypasses confidence check
            if (g_Girls.HasTrait(girl, "Cum Addict"))
            {
                //Autofellatio, belly gets in the way if pregnant, requires extra flexibility
                if (g_Girls.HasTrait(girl, "Flexible") && !(girl->is_pregnant()) && g_Dice.percent(50))
                {
                    ss << "\nDuring her shift " << girlName << " couldn't resist the temptation of taking a load of hot, delicious cum in her mouth and began to suck her own c**k. The customers enjoyed a lot such an unusual show.";
                    g_Girls.UpdateSkill(girl, SKILL_ORALSEX, 1);
                    g_Girls.UpdateStat(girl, STAT_HAPPINESS, 1);
                    tips += 30;
                }
                else
                {
                    //default Cum Addict
                    ss << "\n" << girlName << " won't miss a chance to taste some yummy cum. She came up on the stage with a goblet, cummed in it and then drank the content to entertain the customers.";
                    g_Girls.UpdateStat(girl, STAT_HAPPINESS, 1);
                    tips += 10;
                }
                GetMiscCustomer(brothel, Cust);
                brothel->m_Happiness += 100;
                g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -30);
                // work out the pay between the house and the girl
                wages += g_Girls.GetStat(girl, STAT_ASKPRICE) + 60;
                imagetype = IMGTYPE_MAST;
            }
            //Let's see if she has what it takes to do it: Confidence > 65 or Exhibitionist trait, maybe shy girls should be excluded
            else if (!g_Girls.HasTrait(girl, "Cum Addict") && g_Girls.HasTrait(girl, "Exhibitionist") || !g_Girls.HasTrait(girl, "Cum Addict") && g_Girls.GetStat(girl, STAT_CONFIDENCE) > 65)
            {
                //Some variety
                //Autopaizuri, requires very big breasts
                if (g_Dice.percent(25) && g_Girls.HasTrait(girl, "Abnormally Large Boobs") || g_Dice.percent(25) && (g_Girls.HasTrait(girl, "Titanic T**s")))
                {
                    ss << "\n" << girlName << " was horny and decided to deliver a good show. She put her c**k between her huge breasts and began to slowly massage it. The crowd went wild when she finally came on her massive t**s.";
                    g_Girls.UpdateSkill(girl, SKILL_TITTYSEX, 1);
                    tips += 30;
                }
                //cums over self
                else if (g_Girls.GetStat(girl, STAT_DIGNITY) < -40 && g_Dice.percent(25))
                {
                    ss << "\nThe customers were really impressed when " << girlName << " finished her show by cumming all over herself";
                    tips += 10;
                }
                //Regular futa masturbation
                else
                {
                    ss << "\n" << girlName << "'s c**k was hard all the time and she ended up cumming on stage. The customers enjoyed it but the cleaning crew won't be happy.";
                    brothel->m_Filthiness += 1;
                }
                GetMiscCustomer(brothel, Cust);
                brothel->m_Happiness += 100;
                g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -30);
                // work out the pay between the house and the girl
                wages += g_Girls.GetStat(girl, STAT_ASKPRICE) + 60;
                imagetype = IMGTYPE_MAST;
            }
            else
            {
                ss << "\nThere was a noticeable bulge in " << girlName << "'s panties but she didn't have enough confidence to m********e in public.";
            }
        }
        else
        {
            //GirlFucks handles all the stuff for the other events but it isn't used here so everything has to be added manually
            //It's is the same text as the XXX entertainer masturbation event, so I'll just copy the rest
            ss << "\nShe was horny and ended up masturbating for the customers, making them very happy.";
            GetMiscCustomer(brothel, Cust);
            brothel->m_Happiness += 100;
            g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -30);
            // work out the pay between the house and the girl
            wages += g_Girls.GetStat(girl, STAT_ASKPRICE) + 60;
            imagetype = IMGTYPE_MAST;
        }
    }
    else if (g_Dice.percent(5))  //glory hole event
    {
        ss << "A man managed to cut a hole out from his booth and made himself a glory hole, " << girlName
           << " saw his c**k sticking out and ";
        {
            if (g_Girls.HasTrait(girl, "Meek") || g_Girls.HasTrait(girl, "Shy"))
            {
                enjoyment -= 5;
                ss << "meekly ran away from it.\n";
            }
            else if (g_Girls.HasTrait(girl, "Lesbian"))
            {
                enjoyment -= 2;
                g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -10);
                ss << "she doesn't understand the appeal of them, which turned her off.\n";
            }
            else if (!brothel->m_RestrictNormal && !g_Girls.HasTrait(girl, "Virgin") && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus")) && g_Girls.GetStat(girl, STAT_LIBIDO) >= 80) //sex
            {
                sextype = SKILL_NORMALSEX;
                ss << "decided she needed to use it for her own entertainment.\n";
            }
            else if (!brothel->m_RestrictOral && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus") || g_Girls.HasTrait(girl, "Cum Addict")) && g_Girls.GetStat(girl, STAT_LIBIDO) >= 60) //oral
            {
                sextype = SKILL_ORALSEX;
                ss << "decided she needed to taste it.\n";
            }
            else if (!brothel->m_RestrictFoot && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus") || g_Girls.GetStat(girl, STAT_DIGNITY) < -30) && g_Girls.GetStat(girl, STAT_LIBIDO) >= 40) //foot
            {
                sextype = SKILL_FOOTJOB;
                imagetype = IMGTYPE_FOOT;
                ss << "decided she would give him a foot job for being so brave.\n";
            }
            else if (!brothel->m_RestrictHand && (g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus") || g_Girls.GetStat(girl, STAT_DIGNITY) < -30))	//hand job
            {
                sextype = SKILL_HANDJOB;
                ss << "decided she would give him a hand job for being so brave.\n";
            }
            else
            {
                ss << "pointed and laughed.\n";
            }

            /* `J` suggest adding bad stuff,
            else if (g_Girls.HasTrait(girl, "Merciless") && g_Girls.HasItem(girl, "Dagger") != -1 && g_Dice.percent(10))
            {
            imagetype = IMGTYPE_COMBAT;
            ss << "decided she would teach this guy a lesson and cut his dick off.\n";
            }
            *
            * This would probably require some other stuff and would deffinatly reduce her pay.
            * It may even get the girl arrested if the players suspicion were too high
            *
            //*/
        }
    }

    // `J` calculate base pay and tips with mod before special pay and tips are added
    tips = max(0, int(tips * mod));
    wages = max(0, int(wages * mod));

    if (g_Girls.GetStat(girl, STAT_BEAUTY) > 85 && g_Dice.percent(20))
    {
        ss << "Stunned by her beauty, a customer left her a great tip.\n\n";
        tips += g_Dice % 50 + 10;
    }

    if (sextype != SKILL_STRIP)
    {
        // `J` get the customer and configure them to what is already known about them
        GetMiscCustomer(brothel, Cust);
        Cust->m_Amount = 1;										// always only 1
        Cust->m_SexPref = sextype;								// they don't get a say in this
        if (sextype == SKILL_LESBIAN) Cust->m_IsWoman = true;	// make sure it is a lesbian

        string message = ss.str();
        g_Girls.GirlFucks(girl, Day0Night1, Cust, false, message, sextype);
        ss.str("");
        ss << message;
        brothel->m_Happiness += Cust->m_Stats[STAT_HAPPINESS];

        /* `J` g_Girls.GirlFucks handles libido and customer happiness
        Cust->m_Stats[STAT_HAPPINESS] = max(100, Cust->m_Stats[STAT_HAPPINESS] + 50);
        g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -20);
        //*/

        int sexwages = min(g_Dice % (Cust->m_Money / 4) + g_Girls.GetStat(girl, STAT_ASKPRICE), int(Cust->m_Money));
        Cust->m_Money -= sexwages;
        int sextips = max(0, int(g_Dice%Cust->m_Money - (Cust->m_Money / 2)));
        Cust->m_Money -= sextips;
        wages += sexwages;
        tips += sextips;

        ss << "The customer she had sex with gave her " << sexwages << " gold for her services";
        if (sextips > 0) ss << " and slipped her another " << sextips << " under the table.\n\n";
        else ss << ".\n\n";

        if (imagetype == IMGTYPE_STRIP)
        {
            /* */if (sextype == SKILL_ANAL)			imagetype = IMGTYPE_ANAL;
            else if (sextype == SKILL_BDSM)			imagetype = IMGTYPE_BDSM;
            else if (sextype == SKILL_NORMALSEX)	imagetype = IMGTYPE_SEX;
            else if (sextype == SKILL_BEASTIALITY)	imagetype = IMGTYPE_BEAST;
            else if (sextype == SKILL_GROUP)		imagetype = IMGTYPE_GROUP;
            else if (sextype == SKILL_LESBIAN)		imagetype = IMGTYPE_LESBIAN;
            else if (sextype == SKILL_ORALSEX)		imagetype = IMGTYPE_ORAL;
            else if (sextype == SKILL_TITTYSEX)		imagetype = IMGTYPE_TITTY;
            else if (sextype == SKILL_HANDJOB)		imagetype = IMGTYPE_HAND;
            else if (sextype == SKILL_FOOTJOB)		imagetype = IMGTYPE_FOOT;
        }
    }



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

    // work out the pay between the house and the girl
    girl->m_Tips = tips;
    girl->m_Pay = wages;
    girl->m_Events.AddMessage(ss.str(), imagetype, Day0Night1);

    // Improve stats
    int xp = 15, 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;
    }

    g_Girls.UpdateStat(girl, STAT_FAME, 1);
    g_Girls.UpdateStat(girl, STAT_EXP, xp);
    g_Girls.UpdateSkill(girl, SKILL_STRIP, g_Dice%skill + 1);
    g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill + 1);
    g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

    //gain traits
    if (jobperformance >= 140 && g_Dice.percent(25))
    {
        g_Girls.PossiblyGainNewTrait(girl, "Sexy Air", 80, ACTION_WORKSTRIP, girlName + " has been having to be sexy for so long she now reeks  sexiness.", Day0Night1);
    }
    if (sextype != SKILL_STRIP && g_Girls.GetStat(girl, STAT_DIGNITY) < 0 && g_Dice.percent(25))
    {
        g_Girls.PossiblyGainNewTrait(girl, "S**t", 80, ACTION_SEX, girlName + " has turned into quite a s**t.", Day0Night1);
    }

    //lose
    g_Girls.PossiblyLoseExistingTrait(girl, "Nervous", 30, ACTION_WORKSTRIP, girlName + " has had so many people see her naked she is no longer nervous about anything.", Day0Night1);

    delete Cust;
    return false;
}
// `J` Job Brothel - Hall
bool cJobManager::WorkHallEntertainer(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKHALL;
	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, actiontype, brothel))
	{
		//SIN - More informative mssg to show *what* she refuses
		//ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
		ss << " refused to entertain patrons in the gambling hall " << (Day0Night1 ? "tonight." : "today.");
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked as an entertainer in the gambling hall.\n\n";

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

	sGirl* dealeronduty = g_Brothels.GetRandomGirlOnJob(0, JOB_DEALER, Day0Night1);
	string dealername = (dealeronduty ? "Dealer " + dealeronduty->m_Realname + "" : "the Dealer");

	int wages = 25, tips = 0;
	int work = 0, fame = 0;
	int imagetype = IMGTYPE_BUNNY;
	int msgtype = Day0Night1;

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

	double jobperformance = JP_HallEntertainer(girl, false);

	//SIN: A little pre-randomness
	if (g_Dice.percent(50))
	{
		if (g_Girls.GetStat(girl, STAT_TIREDNESS) > 75)
		{
			ss << "She was very tired, negatively affecting her performance.\n";
			jobperformance -= 10;
		}
		else if (g_Girls.GetStat(girl, STAT_HAPPINESS) > 90)
		{
			ss << "Her cheeriness improved her performance.\n";
			jobperformance += 5;
		}
		if (g_Dice.percent(10))
		{
			if (g_Girls.GetSkill(girl, SKILL_STRIP) > 60)
			{
				ss << "A born stripper, " << girlName << " wears her clothes just short of showing flesh, just the way the customers like it.\n";
				jobperformance += 15;
			}
			if (g_Girls.GetStat(girl, STAT_PCHATE) > g_Girls.GetStat(girl, STAT_PCFEAR))
			{
				ss << " " << girlName << " opened with some rather rude jokes about you. While this annoys you a little, ";
				if (girl->has_trait( "Your Daughter"))
				{
					ss << "she is your daughter, and ";
				}
				ss << "it seems to get the audience on her side.\n";
				jobperformance += 15;
			}
		}
	}

	if (jobperformance >= 245)
	{
		ss << " She must be the perfect entertainer customers go on and on about her and always come to see her when she works.\n\n";
		wages += 155;
		if (roll_b <= 20)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << "The heat of her passion and strength of her fierce nature make " << girlName << "'s songs absolutely riveting to listen to.\n";
			}
			else
			{
				ss << "Every one of " << girlName << "'s jokes elicits a wave of laughter from the crowd of patrons, many of whom have no interest in gambling.\n";
			}
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Elegant"))
			{
				ss << girlName << "'s very appearance in the door of the gambling hall leads to applause and the sudden appearance of a clear way to the stage steps.\n";
			}
			else
			{
				ss << "Her voice is that of an angel, and her humor is as sharp and cutting as a blade.\n";
			}
		}
		else if (roll_b <= 60)
		{
			ss << "Each shift, " << girlName << " ends her show by blowing a kiss to her fans, producing waves of applause and cheers.\n";
		}
		else if (roll_b <= 80)
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "There is no way to resist the raw charisma " << girlName << " practically exudes, drawing everybody around her towards her stage.\n";
			}
			else
			{
				ss << "She could probably excel in any club or entertainment center - fortunately, " << girlName << "'s in yours, drawing customers.\n";
			}
		}
		else
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << "You feel inexpressibly proud that " << girlName << ", your daughter, is such a skilled entertainer.\n";
			}
			else
			{
				ss << girlName << " is downright ideal for this job.  Her presentation and material are flawless\n";
			}
		}
	}
	else if (jobperformance >= 185)
	{
		ss << " She's unbelievable at this and is always getting praised by the customers for her work.\n\n";
		wages += 95;
		if (roll_b <= 20)
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << girlName << " isn't perfect, but she's your own flesh and blood, which is more then close enough.\n";
			}
			else
			{
				ss << girlName << " begun to acquire her own following - a small crowd of people came in just to listen to her and buy drinks.\n";
			}
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << "The savagery of " << girlName << "'s temper has honed her wit to a razor's edge, letting her jab away at the audience and still rake in the tips.\n";
			}
			else if (girl->has_trait( "Elegant"))
			{
				ss << "She cooly paces the edge of the stage as she sings, each step deliberate and perfectly poised, as if " << girlName << " was some noble pacing her seat of power.\n";
			}
			else
			{
				ss << "Her jokes are almost always funny as " << girlName << "'s repertoire develops and expands.\n";
			}
		}
		else if (roll_b <= 60)
		{
			ss << girlName << "'s arrival on the stage at the beginning of her shift is greeted by scattered applause by the last few gamblers from the previous shift, and the new clients.\n";
		}
		else if (roll_b <= 80)
		{
			ss << girlName << "'s soothing voice seems to glide over the noise and bustling of the gamblers and dealers.\n";
		}
		else
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "While her technical skills could use improvement, " << girlName << "'s delivery is beyond reproach.\n";
			}
			else
			{
				ss << " Each shift the tips " << girlName << " collects seem to grow in size!\n";
			}
		}
	}
	else if (jobperformance >= 145)
	{
		ss << " She's good at this job and gets praised by the customers often.\n\n";
		wages += 55;
		if (roll_b <= 20)
		{
			ss << girlName << " managed to provide amusement for anybody who happened to listen to her.\n";
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << "Her jokes are a bit more violent then they perhaps should be, but the clients seem to like " << girlName << ".\n";
			}
			else if (girl->has_trait( "Elegant"))
			{
				ss << "The elegance " << girlName << " brings to all things enhances her already pleasant singing.\n";
			}
			else
			{
				ss << "Most of the jokes " << girlName << " told were amusing.\n";
			}
		}
		else if (roll_b <= 60)
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "While " << girlName << "'s repertoire of jokes and other amusements could stand expansion, she's got the presentation down pat.\n";
			}
			else
			{
				ss << "Her singing was pleasing, if bland.  Her voice was nice, if slightly untrained.\n";
			}
		}
		else if (roll_b <= 80)
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << "Though you'll never admit it, you're happy that " << girlName << " has carved out a niche that doesn't involve renting her c**t to public servants.\n";
			}
			else
			{
				ss << girlName << " earned a decent tip today for her sincere, if not always effective, attempts to entertain the clients.\n";
			}
		}
		else
		{
			ss << "A couple of gamblers parted with some of their hard-earned winnings after swearing that her singing had brought them luck.\n";
		}
	}
	else if (jobperformance >= 100)
	{
		ss << " She made a few mistakes but overall she is okay at this.\n\n";
		wages += 15;
		if (roll_b <= 20)
		{
			ss << girlName << " managed to elicit a few chuckles, and got a few tips.\n";
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "The tips she received were far more than " << girlName << "'s skills had any reason to bring in.\n";
			}
			else
			{
				ss << "While she won't win any contests, " << girlName << " isn't a terrible singer.\n";
			}
		}
		else if (roll_b <= 60)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << "While " << girlName << "'s jokes tend to fall flat, nobody seems to have the bravery to tell her that.\n";
			}
			else
			{
				ss << girlName << " monologued the guests for an hour or so.  While nobody seemed particularly interested, nobody looked pissed either.\n";
			}
		}
		else if (roll_b <= 80)
		{
			if (girl->has_trait( "Elegant"))
			{
				ss << "Her air of sophistication lets " << girlName << " get away with telling boring jokes.\n";
			}
			else
			{
				ss << "While most of the jokes " << girlName << " tells are old and worn out, a few were rather amusing.\n";
			}
		}
		else
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << girlName << " isn't impressive in any way, but she is your daughter, so you dutifully clap as she descends from the stage.\n";
			}
			else
			{
				ss << "The slow song " << girlName << " sang at the end of shift really had her full emotion and heart.  A pity that she felt so bored and tired.\n";
			}
		}
	}
	else if (jobperformance >= 70)
	{
		ss << " She was nervous and made a few mistakes. She isn't that good at this.\n\n";
		wages -= 5;
		if (roll_b <= 20)
		{
			ss << "While her jokes aren't actually driving anyone off, nobody seems to find " << girlName << " entertaining either.\n";
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "Even though her jokes were stale and boring, the audience couldn't seem to make themselves let " << girlName << " down, and laughed regardless.\n";
			}
			else
			{
				ss << "Her singing is barely acceptable, but fortunately the bustling of the gambling hall drowns " << girlName << " out for the most part.\n";
			}
		}
		else if (roll_b <= 60)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << girlName << " cursed the audience roundly for their dislike of her music.\n";
			}
			else
			{
				ss << girlName << " tells bland jokes and sings forgettable songs.\n";
			}
		}
		else if (roll_b <= 80)
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << "You wonder if your daughter, child of your loins, might do better on her back then on the stage.\n";
			}
			else
			{
				ss << girlName << " doesn't appear to be enjoying herself, an emotion she has in common with the clientele.\n";
			}
		}
		else
		{
			ss << "For all the reaction she's getting, you could probably replace " << girlName << " with a simple mannequin.\n";
		}
	}
	else
	{
		ss << " She was nervous and constantly making mistakes. She really isn't very good at this job.\n\n";
		wages -= 15;
		if (roll_b <= 20)
		{
			if (girl->has_trait( "Clumsy"))
			{
				ss << girlName << " trips and falls flat on her face when climbing up the stage stairs.  The crowd cheers loudly.\n";
			}
			else if (girl->has_trait( "Big Boobs") || girl->has_trait( "Abnormally Large Boobs"))
			{
				ss << "You have a feeling if she wasn't so well endowed no one would show up for her show.\n";
			}
			else
			{
				ss << "You stuck your head into the hall halfway through shift, and swore off the gin for the third time this week after hearing " << girlName << "'s horrible singing.\n";
			}
		}
		else if (roll_b <= 40)
		{
			if (girl->has_trait( "Fearless"))
			{
				ss << "Despite the crowd's displeasure, " << girlName << " keeps herself cool and collected, apparently unaffected by their ire.\n";
			}
			else
			{
				ss << "She managed to aggravate several customers with her poor taste in jokes.\n";
			}
		}
		else if (roll_b <= 60)
		{
			if (girl->has_trait( "Your Daughter"))
			{
				ss << "As " << girlName << " butchers another song, you feel bitterly ashamed by your relationship to your worthless child.\n";
			}
			else
			{
				ss << girlName << "'s as funny as a peasant uprising and about as appreciated by her audience.\n";
			}
		}
		else if (roll_b <= 80)
		{
			if (girl->has_trait( "Aggressive"))
			{
				ss << "When the crowd booed her, " << girlName << " responded by throwing a shoe at one of the loudest and most insulting members.\n";
			}
			else
			{
				ss << "Her audience seems paralyzed, as if they couldn't believe that a human body could produce those sounds, much less call them \"singing\".\n";
			}
		}
		else
		{
			if (girl->has_trait( "Charming") || girl->has_trait( "Charismatic"))
			{
				ss << "The poor quality of her routine was offset by her natural charisma.\n";
			}
			else
			{
				ss << "For some reason, " << girlName << " attempted a dramatic monologue and feigned suicide on stage.  Needless to say, she didn't receive any tips.\n";
			}
		}
	}


	//base tips, aprox 5-30% of base wages
	tips += (int)(((5 + jobperformance / 8) * wages) / 100);

	//try and add randomness here
	if (g_Girls.GetStat(girl, STAT_BEAUTY) > 85 && g_Dice.percent(20))
	{
		ss << "Stunned by her beauty a customer left her a great tip.\n\n";
		tips += 25;
	}

	if (girl->has_trait( "Clumsy") && g_Dice.percent(15))
	{
		ss << "Her clumsy nature caused her to spill a drink on a customer resulting in them storming off without paying.\n";
		wages -= 15;
	}

	if (girl->has_trait( "Pessimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			ss << "Her pessimistic mood depressed the customers making them tip less.\n";
			tips -= 10;
		}
		else
		{
			ss << girlName << " was in a poor mood so the patrons gave her a bigger tip to try and cheer her up.\n";
			tips += 10;
		}
	}

	if (girl->has_trait( "Optimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			ss << girlName << " was in a cheerful mood but the patrons thought she needed to work more on her services.\n";
			tips -= 10;
		}
		else
		{
			ss << " Her optimistic mood made patrons cheer up increasing the amount they tip.\n";
			tips += 10;
		}
	}

	if (g_Dice.percent(5) && (girl->has_trait( "Charming") || girl->has_trait( "Charismatic")))
	{
		if (jobperformance < 125)
		{
			ss << "Despite her poor performance, people still applaud loudly for her.\n";
			tips -= 10;
		}
		else
		{
			ss << "People love to see her perform, and " << girlName << " collects a massive tip!.\n";
			tips += 100;
		}
	}

	if (g_Dice.percent(5) && (girl->has_trait( "Princess") || girl->has_trait( "Queen")))
	{
		if (jobperformance < 125)
		{
			ss << "Her royal bitchiness combined with the poor entertainment pisses the audience off.\n";
			tips -= 15;
		}
		else
		{
			ss << girlName << " owns the stage, imperious eyes flashing out across the audience.  Tips are very good tonight.\n";
			tips += 25;
		}
	}

	if (g_Brothels.GetNumGirlsOnJob(0, JOB_DEALER, false) >= 1 && g_Dice.percent(25))
	{
		if (jobperformance < 125)
		{
			ss << girlName << " tried to distract the patrons but due to her lack of skills she distracted " << dealername << " causing you to lose some money.\n";
			wages -= 10;
		}
		else
		{
			ss << girlName << " was able to perfectly distract some patrons while the " << dealername << " cheated to make some more money.\n";
			wages += 25;
		}
	}


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

	//enjoyed the work or not
	if (roll_a <= 5)
	{
		ss << "\nSeveral patrons heckled her and made her shift generally unpleasant.";
		work -= 1;
	}
	else if (roll_a <= 25)
	{
		ss << "\nShe had a great time working.";
		work += 3;
	}
	else
	{
		ss << "\nOtherwise, the shift passed uneventfully.";
		work += 1;
	}

#pragma endregion
#pragma region	//	Money					//


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


	g_Girls.UpdateEnjoyment(girl, actiontype, work);
	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);


	wages += (g_Dice % ((int)(((g_Girls.GetStat(girl, STAT_BEAUTY) + g_Girls.GetStat(girl, STAT_CHARISMA)) / 2)*0.5f))) + 10;
	// Money
	girl->m_Tips = max(0, tips);
	girl->m_Pay = max(0, wages);


	// Improve girl
	int xp = 10, libido = 1, skill = 2;

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

	g_Girls.UpdateStat(girl, STAT_FAME, fame);
	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateStat(girl, STAT_CONFIDENCE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);


#pragma endregion
	return false;
}
Example #8
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 #9
0
// `J` Job Brothel - Bar
bool cJobManager::WorkBarPiano(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKMUSIC;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	if (g_Girls.DisobeyCheck(girl, actiontype, brothel))
	{
		ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " played the piano in the bar.";

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

	sGirl* singeronduty = g_Brothels.GetRandomGirlOnJob(0, JOB_SINGER, Day0Night1);
	string singername = (singeronduty ? "Singer " + singeronduty->m_Realname + "" : "the Singer");

	double wages = 20, tips = 0;
	int work = 0;

	int roll = g_Dice.d100();

	double jobperformance = JP_BarPiano(girl, false);

	if (jobperformance >= 245)
	{
		ss << " She plays with the grace of an angel. Customers come from miles around to listen to her play.\n\n";
		wages += 155;
		if (roll <= 20)
		{
			ss << girlName << "'s playing brought many patrons to tears as she played a song full of sadness.\n";
			brothel->m_Happiness += 5;
		}
		else if (roll <= 40)
		{
			ss << "Nice melody fills the room when " << girlName << " is behind the piano.\n";
			brothel->m_Happiness += 10;
		}
		else if (roll <= 60)
		{
			ss << "Knowing that she is good, " << girlName << " played all the tunes blindfolded.\n";
			brothel->m_Fame += 10;
		}
		else if (roll <= 80)
		{
			ss << "Being confident in her skill, " << girlName << " played today using only one hand.\n";
			brothel->m_Fame += 10;
		}
		else
		{
			ss << girlName << "'s soothing playing seems to glide over the noise and bustling of the bar.\n";
			brothel->m_Happiness += 10;
		}
	}
	else if (jobperformance >= 185)
	{
		ss << " She's unbelievable at this and is always getting praised by the customers for her playing skills.\n\n";
		wages += 95;
		if (roll <= 20)
		{
			ss << girlName << " begun to acquire her own following - a small crowd of people came in just to listen to her and buy drinks\n";
			brothel->m_Fame += 5;
			wages += 10;
		}
		else if (roll <= 40)
		{
			ss << "Her playing fills the room. Some customers hum the melody under their noses.\n";
			brothel->m_Happiness += 5;
		}
		else if (roll <= 60)
		{
			ss << "After making a mistake she improvised a passage to the next song.\n";
		}
		else if (roll <= 80)
		{
			ss << "She plays without music sheets having all the songs memorized.\n";
			brothel->m_Fame += 5;
		}
		else
		{
			ss << girlName << "'s soothing playing seems to glide over the noise and bustling of the bar.\n";
		}
	}
	else if (jobperformance >= 145)
	{
		ss << " Her playing is really good and gets praised by the customers often.\n\n";
		wages += 55;
		if (roll <= 20)
		{
			ss << "Her playing was pleasing, if bland.  Her rythem was nice, if slightly untrained.\n";
		}
		else if (roll <= 40)
		{
			ss << girlName << " doesn't have any trouble playing the piano.\n";
		}
		else if (roll <= 60)
		{
			ss << "Give " << girlName << " any kind of music sheet and she will play it. She is really good at this.\n";
			brothel->m_Happiness += 5;
		}
		else if (roll <= 80)
		{
			ss << "When asked to play one of the more complicated tunes she gave her all.\n";
		}
		else
		{
			ss << "The slow song " << girlName << " played at the end of shift really had her full emotion and heart.\n";
		}
	}
	else if (jobperformance >= 100)
	{
		ss << " She hits a few right notes but she still has room to improve.\n\n";
		wages += 15;
		if (roll <= 20)
		{
			ss << "While she won't win any contests, " << girlName << " isn't a terrible pianist.\n";
		}
		else if (roll <= 40)
		{
			ss << girlName << "'s performance today was good. She is a promising pianist.\n";
		}
		else if (roll <= 60)
		{
			ss << "She gets the key order right most of the time.\n";
		}
		else if (roll <= 80)
		{
			ss << "You could tell that there was something like a melody, but " << girlName << " still needs a lot of practice.\n";
		}
		else
		{
			ss << "The slow song " << girlName << " played at the end of shift really had her full emotion and heart.  A pity that she felt so bored and tired.\n";
		}
	}
	else if (jobperformance >= 70)
	{
		ss << " She almost never hits a right note. Lucky for you most of the customers are too drunk and horny to care.\n\n";
		wages -= 5;
		if (roll <= 20)
		{
			ss << "Her playing is barely acceptable, but fortunately the bustling of the bar drowns " << girlName << " out for the most part.\n";
		}
		else if (roll <= 40)
		{
			ss << "She is terrible at this. Some customers left after she started to play.\n";
			brothel->m_Happiness -= 5;
		}
		else if (roll <= 60)
		{
			ss << "You could count on the fingers of one hand the part in her play that was clean.\n";
		}
		else if (roll <= 80)
		{
			ss << "She is bad at playing the piano.\n";
		}
		else
		{
			ss << girlName << " knows a note.  To bad its the only one she knows and plays it over and over.\n";
		}
	}
	else
	{
		ss << " She didn't play the piano so much as banged on it.\n\n";
		wages -= 15;
		if (roll <= 20)
		{
			ss << "Her audience seems paralyzed, as if they couldn't believe that a piano was capable of making such noise.\n";
			brothel->m_Happiness -= 10;
		}
		else if (roll <= 40)
		{
			ss << "After ten seconds you wanted to grab an axe and end the instrument's misery under " << girlName << "'s attempt to play.\n";
			brothel->m_Happiness -= 5;
		}
		else if (roll <= 60)
		{
			ss << "Noone else would call this random key-mashing 'playing', but " << girlName << " thinks otherwise.\n";
		}
		else if (roll <= 80)
		{
			ss << "When " << girlName << " started to play, the bar emptied almost instantly. This could be useful in a fire.\n";
		}
		else
		{
			ss << girlName << " banged on the piano clearly having no clue which note was which.\n";
		}
		//SIN - bit of randomness.
		if (g_Dice.percent(brothel->m_Filthiness / 50)) ss << "Soon after she started her set, some rats jumped out of the piano and fled the building. Patrons could be heard laughing.\n\n";
	}


	//base tips, aprox 5-30% of base wages
	tips += (((5 + jobperformance / 8) * wages) / 100);

	//try and add randomness here
	if (g_Girls.GetStat(girl, STAT_BEAUTY) > 85 && g_Dice.percent(20))
	{
		ss << "Stunned by her beauty a customer left her a great tip.\n\n"; tips += 15;
	}

	if (g_Girls.HasTrait(girl, "Clumsy") && g_Dice.percent(5))
	{
		ss << "Her clumsy nature caused her to close the lid on her fingers making her have to stop playing for a few hours.\n\n"; wages -= 15;
	}

	if (g_Girls.HasTrait(girl, "Pessimist") && g_Dice.percent(20))
	{
		if (jobperformance < 125)
		{
			ss << "Her pessimistic mood depressed the customers making them tip less.\n\n"; tips -= 10;
		}
		else
		{
			ss << girlName << " was in a poor mood so the patrons gave her a bigger tip to try and cheer her up.\n\n"; tips += 10;
		}
	}

	if (g_Girls.HasTrait(girl, "Optimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			ss << girlName << " was in a cheerful mood but the patrons thought she needed to work more on her on her playing.\n\n"; tips -= 10;
		}
		else
		{
			ss << "Her optimistic mood made patrons cheer up increasing the amount they tip.\n\n"; tips += 10;
		}
	}

	if (g_Girls.HasTrait(girl, "Psychic") && g_Dice.percent(20))
	{
		ss << "She used her Psychic skills to know exactly what the patrons wanted to hear her play.\n"; tips += 15;
	}

	if (g_Girls.HasTrait(girl, "Assassin") && g_Dice.percent(5))
	{
		if (jobperformance < 150)
		{
			ss << "A patron bumped into the piano causing her to miss a note. This pissed her off and using her Assassin skills she killed him before even thinking about it, resulting in patrons fleeing the building.\n"; wages -= 50;
		}
		else
		{
			ss << "A patron bumped into the piano, but with her skill she didn't miss a note. The patron was lucky to leave with his life.\n";
		}
	}

	if (g_Girls.HasTrait(girl, "Horrific Scars") && g_Dice.percent(15))
	{
		if (jobperformance < 150)
		{
			ss << "A patron gasped at her Horrific Scars making her uneasy. But they didn't feel sorry for her.\n";
		}
		else
		{
			ss << "A patron gasped at her Horrific Scars making her sad. Feeling bad about it as she played so well, they left a good tip.\n"; tips += 15;
		}
	}

	if (g_Brothels.GetNumGirlsOnJob(0, JOB_SINGER, false) >= 1 && g_Dice.percent(25))
	{
		if (jobperformance < 125)
		{
			ss << girlName << " played poorly with " << singername << " making people leave.\n"; tips -= 10;
		}
		else
		{
			ss << girlName << " played well with " << singername << " increasing tips.\n"; tips += 40;
		}
	}


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

	g_Girls.UpdateEnjoyment(girl, ACTION_WORKMUSIC, work);
	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
	int roll_max = (g_Girls.GetStat(girl, STAT_BEAUTY) + g_Girls.GetStat(girl, STAT_CHARISMA));
	roll_max /= 4;
	wages += 10 + g_Dice%roll_max;
	if (wages < 0) wages = 0;
	if (tips < 0) tips = 0;
	girl->m_Pay = (int)wages;
	girl->m_Tips = (int)tips;

	// 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; }

	g_Girls.UpdateStat(girl, STAT_FAME, 1);
	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	if (g_Dice % 2 == 1)
		g_Girls.UpdateStat(girl, STAT_CONFIDENCE, g_Dice%skill);
	else
		g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	//gain traits
	g_Girls.PossiblyGainNewTrait(girl, "Elegant", 75, ACTION_WORKMUSIC, "Playing the piano has given " + girlName + " an Elegant nature.", Day0Night1);

	//lose traits
	g_Girls.PossiblyLoseExistingTrait(girl, "Nervous", 30, ACTION_WORKMUSIC, girlName + " seems to finally be getting over her shyness. She's not always so Nervous anymore.", Day0Night1);

	return false;
}
// Job Movie Studio - // nice Job - Action Scene
//This film will use her combat and magic skills, and will be more popular if she's hot.
bool cJobManager::WorkFilmAction(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKMOVIE;
	//Taken care of in building flow, leaving it in for robustness
	if (g_Studios.GetNumGirlsOnJob(0, JOB_CAMERAMAGE, SHIFT_NIGHT) == 0 || g_Studios.GetNumGirlsOnJob(0, JOB_CRYSTALPURIFIER, SHIFT_NIGHT) == 0)
	{
		girl->m_Events.AddMessage("There was no crew to film the scene, so she took the day off", IMGTYPE_PROFILE, EVENT_NOWORK);
		return false;
	}

	stringstream ss;
	string girlName = girl->m_Realname;
	int wages = 50;
	int tips = 0;
	int enjoy = 0;
	int bonus = 0;
	double jobperformance = JP_FilmAction(girl, false);

	//g_Girls.UnequipCombat(girl);	// not for actress (yet)

	ss << girlName;
	int roll = g_Dice.d100();
	if (roll <= 10 && g_Girls.DisobeyCheck(girl, ACTION_WORKMOVIE, brothel))
	{
		ss << " refused to shoot an action scenes today.\n";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	else if (g_Girls.GetStat(girl, STAT_TIREDNESS) > 75)
	{
		ss << " was too tired to take part in an action scene.\n\n";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	else ss << " worked as an actress in an action scene.\n\n";


	//JOB
	ss << girlName;
	int OPTIONS = 3; //Right now this number of options applies for all levels of job
	if (jobperformance >= 350)
	{
		ss << " made an outstanding action scene,";
		AddStory(&ss);
		ss << " It will definitely win her some fans.";
		g_Girls.UpdateStat(girl, STAT_FAME, 3);
		bonus = 12;
	}
	else if (jobperformance >= 245)
	{
		ss << " made a great action scene,";
		AddStory(&ss);
		ss << " It should win her some fans.";
		g_Girls.UpdateStat(girl, STAT_FAME, 2);
		bonus = 6;
	}
	else if (jobperformance >= 185)
	{
		ss << " made a fairly good action scene,";
		AddStory(&ss);
		ss << " Her fans will enjoy it.";
		bonus = 4;
		g_Girls.UpdateStat(girl, STAT_FAME, 1);
	}
	else if (jobperformance >= 145)
	{
		ss << " made an uninspired action scene,";
		AddStory(&ss);
		ss << " Her diehard fans might enjoy it.";
		bonus = 2;
	}
	else if (jobperformance >= 100)
	{
		ss << " made a weak action scene,";
		AddStory(&ss);
		bonus = 1;
		ss << "\nThe CamerMage advised " << girlName << " how to improve her performance";
		if (g_Dice.percent(40))
		{
			ss << " and her scene got a little better after this.";
			bonus++;
		}
		else
		{
			ss << ", but she wouldn't listen.";
		}
	}
	else
	{
		ss << " made an awful action scene,";
		AddStory(&ss);
		ss << " Even her fans will hate it.";
		g_Girls.UpdateStat(girl, STAT_FAME, -1);
	}

	ss << "\n";

	//Enjoyed? If she performed well, she'd should have enjoyed it.
	if (jobperformance >= 200)
	{
		enjoy += (g_Dice % 3 + 1);
		ss << "She loved performing on film today.\n\n";
	}
	else if (jobperformance >= 100)
	{
		enjoy += g_Dice % 2;
		ss << "She enjoyed this performance.\n\n";
	}
	else
	{
		enjoy -= (g_Dice % 3 + 2);
		ss << "She found this awkward and did not enjoy it.\n\n";
	}

	// remaining modifiers are in the AddScene function --PP
	int finalqual = g_Studios.AddScene(girl, JOB_FILMACTION, bonus);
	ss << "Her scene is valued at: " << finalqual << " gold.\n";

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_COMBAT, Day0Night1);

	// work out the pay between the house and the girl
	if (girl->is_slave() && !cfg.initial.slave_pay_outofpocket())
	{
		wages = 0;	// You own her so you don't have to pay her.
	}
	else
	{
		wages += finalqual * 2;
	}
	girl->m_Tips = max(0, tips);
	girl->m_Pay = max(0, wages);

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

	if (girl->has_trait( "Quick Learner"))		{ skill += 1; xp += 3; }
	else if (girl->has_trait( "Slow Learner"))	{ skill -= 1; xp -= 3; }
	if (girl->has_trait( "Nymphomaniac"))			{ libido += 2; }

	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_COMBAT, g_Dice%skill + 1);
	g_Girls.UpdateSkill(girl, SKILL_MAGIC, g_Dice%skill + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	g_Girls.UpdateEnjoyment(girl, ACTION_COMBAT, enjoy);
	g_Girls.UpdateEnjoyment(girl, ACTION_WORKMOVIE, enjoy);

	//gain traits
	if (jobperformance >= 140 && g_Dice.percent(50))
	{
		if (g_Girls.PossiblyGainNewTrait(girl, "Brawler", 60, ACTION_COMBAT, "She has performed in enough fight scenes that she has become quite a brawler.", Day0Night1));
		else if (g_Girls.PossiblyGainNewTrait(girl, "Tough", 70, ACTION_COMBAT, "She has performed in enough fight scenes that she has become quite tough.", Day0Night1));
		else if (g_Girls.PossiblyGainNewTrait(girl, "Agile", 80, ACTION_COMBAT, "She has performed martial arts scenes that she is becoming agile.", Day0Night1));
		else (g_Girls.PossiblyGainNewTrait(girl, "Fleet of Foot", 90, ACTION_COMBAT, "She has performed so many action scenes that she has become fast on her feet.", Day0Night1));
	}

	if (jobperformance >= 140 && g_Dice.percent(50))
	{
		if (g_Girls.PossiblyGainNewTrait(girl, "Charismatic", 60, ACTION_WORKMOVIE, "She has performed in enough movie scenes that she has become charismatic.", Day0Night1));
		else if (g_Girls.PossiblyGainNewTrait(girl, "Actress", 70, ACTION_WORKMOVIE, "She has performed in enough movie scenes that she has become a good actress.", Day0Night1));
		else g_Girls.PossiblyGainNewTrait(girl, "Sexy Air", 80, ACTION_WORKSTRIP, girlName + " has been having to be sexy for so long she now reeks sexiness.", Day0Night1);
	}

	// nice job bonus-------------------------------------------------------
	//BONUS - Nice jobs show off her assets and make her happy, increasing fame and love.

	int MrNiceGuy = g_Dice % 6, MrFair = g_Dice % 6;
	MrNiceGuy = (MrNiceGuy + MrFair)/3;				//Should come out around 1-2 most of the time.

	g_Girls.UpdateStat(girl, STAT_HAPPINESS, MrNiceGuy);
	g_Girls.UpdateStat(girl, STAT_FAME, MrNiceGuy);
	g_Girls.UpdateStat(girl, STAT_PCLOVE, MrNiceGuy);
	g_Girls.UpdateStat(girl, STAT_PCHATE, -MrNiceGuy);
	g_Girls.UpdateStat(girl, STAT_PCFEAR, -MrNiceGuy);
	The_Player->disposition(MrNiceGuy);

	//----------------------------------------------------------------------

	return false;
}
Example #11
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;
}
// `J` Job Brothel - General
bool cJobManager::WorkSecurity(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKSECURITY;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	if (g_Girls.DisobeyCheck(girl, actiontype, brothel))
	{
		ss << " refused to work security in your brothel " << (Day0Night1 ? "tonight." : "today.");
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked Security in the brothel.\n\n";




	int enjoy = 0;
	int wages = 0;
	int tips = 0;
	int roll_a = g_Dice.d100(), roll_b = g_Dice.d100(), roll_c = g_Dice.d100();
	int imagetype = IMGTYPE_COMBAT;

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

	sGirl* stripperonduty = g_Brothels.GetRandomGirlOnJob(brothel->m_id, JOB_BARSTRIPPER, Day0Night1);
	string strippername = (stripperonduty ? "Stripper " + stripperonduty->m_Realname + "" : "the Stripper");

	sGirl* whoreonduty = g_Brothels.GetRandomGirlOnJob(brothel->m_id, JOB_WHOREBROTHEL, Day0Night1);
	string whorename = (whoreonduty ? "W***e " + whoreonduty->m_Realname + "" : "the W***e");


	double SecLev = JP_Security(girl, false);


	// Complications
	if (roll_a <= 25)
	{
        switch(g_Dice%5)
        {
        case 2: //'Mute' Unrulely Customers rape her
        {
            enjoy-=g_Dice%3+1;
            SecLev-=SecLev/10;
            ss<< "She tried to Fight off some unruly patrons, but they turned on her and raped her.";
            int custCount=g_Dice%4+1;
            customer_rape(girl,custCount);
            break;
        }
		case 3:
		{
			enjoy -= g_Dice % 3 + 1;
			double secLvlMod = SecLev / 10.0;
			ss << "She stumbled across some patrons trying to rape a female customer.\n";
			int combatMod = (girl->combat() + girl->magic() + girl->agility()) / 3;
			if (g_Dice.percent(combatMod))
			{
				ss << "She succeeded in saving the girl from being raped."; //'Mute" TODO add posiblity of adding female customers to dungeon
				SecLev += secLvlMod;
			}
			else
			{
				SecLev -= secLvlMod;
				int rapers = g_Dice % 4 + 1;
				ss << "She failed in saving her. They where both raped by " << rapers << " men.\n";
				customer_rape(girl, rapers);
			}
			break;
		}
        default:
        {
            enjoy -= g_Dice % 3 + 1;
            SecLev -= SecLev / 10;
            ss << "She had to deal with some very unruly patrons that gave her a hard time.";
            break;
        }
        }

	}
	else if (roll_a >= 75)
	{
		enjoy += g_Dice % 3 + 1;
		SecLev += SecLev / 10;
		ss << "She successfully handled unruly patrons.";
	}
	else
	{
		enjoy += g_Dice % 2;
		ss << "She had an uneventful day watching over the brothel.";
	}
	ss << "\n\n";

	if (girl->libido() >= 70 && g_Dice.percent(20))
	{
		int choice = g_Dice % 2;
		ss << "Her libido caused her to get distracted while watching ";
		/*might could do more with this FIXME CRAZY*/
		if (girl->has_trait( "Lesbian"))	choice = 0;
		if (girl->has_trait( "Straight"))	choice = 1;
		switch (choice)
		{
		case 0:
			ss << (stripperonduty ? strippername : "one of the strippers") << " dance.\n";
			break;
		case 1:
		default:
			ss << (whoreonduty ? whorename : "one of the w****s") << " with a client.\n";
			break;
		}
		SecLev -= 20;
		ss << "\n\n";

	}

	if ((girl->libido() > 50 && g_Dice.percent(girl->libido() / 5)) || (girl->has_trait( "Nymphomaniac") && g_Dice.percent(20)))
	{
		ss <<"\nGave some bonus service to the well behaved patrons, ";
		int l = 0;
		switch (g_Dice % 4)		// `J` just roll for the 4 sex options and flash only if sex is restricted
		{
		case 1:	if (!brothel->m_RestrictOral)	{ l = 10;	imagetype = IMGTYPE_ORAL;	ss << "She sucked them off";	break; }
		case 2:	if (!brothel->m_RestrictTitty)	{ l = 7;	imagetype = IMGTYPE_TITTY;	ss << "She used her t**s to get them off";	break; }
		case 3:	if (!brothel->m_RestrictHand)	{ l = 6;	imagetype = IMGTYPE_HAND;	ss << "She jerked them off";	break; }
		case 4:	if (!brothel->m_RestrictFoot)	{ l = 4;	imagetype = IMGTYPE_FOOT;	ss << "She used her feet to get them off";	break; }
		default:/*                         */	{ l = 2;	imagetype = IMGTYPE_STRIP;	ss << "She flashed them";	break; }
		}
		ss << ".\n\n";
		g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -l, true);
	}

	if (SecLev < 10) SecLev = 10;
	brothel->m_SecurityLevel += int(SecLev);

	ss << "\nPatrolling the building, " << girlName << " increased the security level by " << int(SecLev) << ".";
	girl->m_Events.AddMessage(ss.str(), imagetype, Day0Night1);

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

	/* */if (girl->has_trait( "Quick Learner"))		{ skill += 1; xp += 5; }
	else if (girl->has_trait( "Slow Learner"))	{ skill -= 1; xp -= 5; }
	/* */if (girl->has_trait( "Nymphomaniac"))			{ libido += 2; }

	wages += 70;
	girl->m_Tips = max(0, tips);
	girl->m_Pay = max(0, wages);

	//g_Gold.staff_wages(70);  // wages come from
	// 'Mute' Updated
	girl->exp(xp);
	girl->combat((g_Dice%skill)+1);
	girl->magic((g_Dice%skill)+1);
	girl->agility((g_Dice%skill)+1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);


	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	// Copy-pasta from WorkExploreCatacombs
	g_Girls.PossiblyGainNewTrait(girl, "Tough", 15, actiontype, "She has become pretty Tough from all of the fights she's been in.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Adventurer", 45, actiontype, "She has been in enough tough spots to consider herself Adventurer.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Aggressive", 60, actiontype, "She is getting rather Aggressive from her enjoyment of combat.", Day0Night1);
	return false;
}
Example #13
0
// `J` Job Clinic - Surgery
bool cJobManager::WorkRepairShop(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_GENERAL;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	g_Girls.UnequipCombat(girl);	// not for patients

	if (!g_Girls.HasTrait(girl, "Construct") && !g_Girls.HasTrait(girl, "Half-Construct"))
	{
		ss << girlName << " has no artificial parts so she was sent to the Healing center.";
		if (Day0Night1 == SHIFT_DAY) girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_WARNING);
		if (girl->m_DayJob == JOB_GETREPAIRS)	girl->m_DayJob = JOB_GETHEALING;
		if (girl->m_NightJob == JOB_GETREPAIRS)	girl->m_NightJob = JOB_GETHEALING;
		return false;	// not refusing
	}

	int nummecs = g_Clinic.GetNumGirlsOnJob(0, JOB_MECHANIC, Day0Night1);
	int numnurse = g_Clinic.GetNumGirlsOnJob(0, JOB_NURSE, Day0Night1);

	// `J` base recovery copied freetime recovery
	int health = 10 + (girl->constitution() / 10);
	int tiredness = 10 + g_Dice % 21;	// build up as positive then apply as negative
	int happy = 10 + g_Dice % 11;
	int mana = 5 + (girl->magic() / 5);
	int libido = (g_Girls.HasTrait(girl, "Nymphomaniac") ? 15 : 5);

	if (nummecs + numnurse < 1)
	{
		ss << "You don't have any Mechanics or Nurses on duty so " << girlName << " just rests in a hospital bed.";
	}
	else
	{
		ss << girlName << " does nothing while ";
	}
	if (nummecs > 0)
	{
		ss << "the Mechanic" << (nummecs > 1 ? "s" : "");
		if (g_Girls.HasTrait(girl, "Half-Construct") && girl->m_DayJob == JOB_GETREPAIRS && girl->m_NightJob == JOB_GETREPAIRS)
		{	// if fixed by Mechanic for both shifts.
			health += 20;	// Total 40 healing per day, heals less because Mechanic does not fix living tissue.
		}
		else
		{
			health += 30;
		}
	}
	if (nummecs > 0 && numnurse > 0) { ss << " and"; }
	if (numnurse > 0)
	{
		ss << " the Nurse" << (numnurse > 1 ? "s" : "");
		health += 10;
		tiredness += 10;
		happy += 10;
		mana += (girl->magic() / 5);
	}
	if (nummecs + numnurse >= 4 && g_Dice.percent(50))	// lots of people making sure she is in good working order
	{
		g_Girls.UpdateStat(girl, STAT_CONSTITUTION, 1);
	}
	ss << (((nummecs > 1 && numnurse < 1) || numnurse > 1) ? " take" : " takes") << " care of her.";

	// Improve girl
	if (g_Girls.HasTrait(girl, "Lesbian"))		libido += numnurse;
	if (g_Girls.HasTrait(girl, "M*******t"))	libido += 1;
	if (g_Girls.HasTrait(girl, "Nymphomaniac"))	libido += 2;

	g_Girls.UpdateStat(girl, STAT_HEALTH, health, false);
	g_Girls.UpdateStat(girl, STAT_TIREDNESS, -tiredness, false);
	g_Girls.UpdateStat(girl, STAT_HAPPINESS, happy);
	g_Girls.UpdateStat(girl, STAT_MANA, mana);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);
	if (g_Dice % 10 == 0) g_Girls.UpdateSkill(girl, SKILL_MEDICINE, 1);	// `J` she watched what the doctors and nurses were doing

	g_Girls.UpdateStat(girl, STAT_EXP, 1);   // Just because!

	// send her to the waiting room when she is healthy
	if (girl->health() > 90 && girl->tiredness() < 10)
	{
		if (nummecs + numnurse < 1)	ss << "\n\nShe wanders out of the Clinic when she is feeling better.";
		else						ss << "\n\nShe has been released from the Clinic.";
		if (girl->m_DayJob == JOB_GETHEALING)	girl->m_DayJob = JOB_CLINICREST;
		if (girl->m_NightJob == JOB_GETHEALING)	girl->m_NightJob = JOB_CLINICREST;
		if (girl->m_DayJob == JOB_GETREPAIRS)	girl->m_DayJob = JOB_CLINICREST;
		if (girl->m_NightJob == JOB_GETREPAIRS)	girl->m_NightJob = JOB_CLINICREST;
	}

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);

	return false;
}
Example #14
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 #15
0
// `J` Job Farm - Staff - job_is_cleaning
bool cJobManager::WorkFarmHand(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKFARM; int actiontype2 = ACTION_WORKCLEANING;
	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 (roll_a <= 50 && (g_Girls.DisobeyCheck(girl, actiontype, brothel) || g_Girls.DisobeyCheck(girl, actiontype2, brothel)))
	{
		ss << " refused to work on the farm.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked cleaning and repairing the farm.\n\n";

	

	g_Girls.UnequipCombat(girl);	// put that shit away

	double CleanAmt = ((g_Girls.GetSkill(girl, SKILL_SERVICE) / 10) + 5) * 10;
	CleanAmt += JP_FarmHand(girl, false);

	int enjoyC = 0, enjoyF = 0;
	double wages = 0, tips = 0;
	bool playtime = false;




	if (roll_a <= 10)
	{
		enjoyC -= g_Dice % 3; enjoyF -= g_Dice % 3;
		CleanAmt = CleanAmt * 0.8;
		/* */if (roll_b < 30)	ss << "She spilled a bucket of something unpleasant all over herself.";
		else if (roll_b < 60)	ss << "She stepped in something unpleasant.";
		else /*            */	ss << "She did not like working on the farm today.";
	}
	else if (roll_a >= 90)
	{
		enjoyC += g_Dice % 3; enjoyF += g_Dice % 3;
		CleanAmt = CleanAmt * 1.1;
		/* */if (roll_b < 50)	ss << "She cleaned the building while humming a pleasant tune.";
		else /*            */	ss << "She had a great time working today.";
	}
	else
	{
		enjoyC += g_Dice % 2; enjoyF += g_Dice % 2;
		ss << "The shift passed uneventfully.";
	}
	ss << "\n\n";

	// slave girls not being paid for a job that normally you would pay directly for do less work
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		CleanAmt = CleanAmt * 0.9;
		wages = 0;
	}
	else
	{
		wages = int(CleanAmt); // `J` Pay her based on how much she cleaned
	}

	// `J` if she can clean more than is needed, she has a little free time after her shift
	if (brothel->m_Filthiness < CleanAmt / 2) playtime = true;
	ss << "\n\nCleanliness rating improved by " << int(CleanAmt);
	if (playtime)	// `J` needs more variation
	{
		ss << "\n\n" << girlName << " finished her cleaning early so she ";
		if (Day0Night1 == SHIFT_DAY && roll_c % 3 == 1)	// 33% chance she will watch the sunset when working day shift
		{
			ss << "sat beneath an oak tree and watched the sunset.";
			g_Girls.UpdateStat(girl, STAT_TIREDNESS, -((g_Dice % 5) + 2));
		}
		else if (roll_c < 25)
		{
			ss << "played with the baby animals a bit.";
			g_Girls.UpdateSkill(girl, SKILL_ANIMALHANDLING, (g_Dice % 2) + 1);
		}
		else if (roll_c < 50)
		{
			ss << "played in the dirt a bit.";
			g_Girls.UpdateSkill(girl, SKILL_FARMING, (g_Dice % 2));
		}
		else
		{
			ss << "sat in a rocking chair on the farm house front porch whittling.";
			g_Girls.UpdateSkill(girl, SKILL_CRAFTING, (g_Dice % 3));
			g_Girls.UpdateStat(girl, STAT_TIREDNESS, -(g_Dice % 3));
		}
		g_Girls.UpdateStat(girl, STAT_HAPPINESS, (g_Dice % 4) + 2);
	}

#if 0

	// `J` Farm Bookmark - adding in items that can be created in the farm















#endif




	// do all the output
	girl->m_Events.AddMessage(ss.str(), IMGTYPE_MAID, Day0Night1);
	brothel->m_Filthiness -= int(CleanAmt);

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

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

	if (enjoyC + enjoyF > 2)							{ xp += 1; 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; }

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	// primary (+2 for single or +1 for multiple)
	g_Girls.UpdateSkill(girl, SKILL_SERVICE, (g_Dice % skill));
	// secondary (-1 for one then -2 for others)
	g_Girls.UpdateSkill(girl, SKILL_CRAFTING, max(0, (g_Dice % skill) - 1));
	g_Girls.UpdateSkill(girl, SKILL_FARMING, max(0, (g_Dice % skill) - 2));
	g_Girls.UpdateStat(girl, STAT_STRENGTH, max(0, (g_Dice % skill) - 2));

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoyF);
	g_Girls.UpdateEnjoyment(girl, actiontype2, enjoyC);
	// Gain Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyGainNewTrait(girl, "Maid", 90, actiontype2, girlName + " has cleaned enough that she could work professionally as a Maid anywhere.", Day0Night1);
	// Lose Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyLoseExistingTrait(girl, "Clumsy", 30, actiontype2, "It took her spilling hundreds of buckets, and just as many reprimands, but " + girl->m_Realname + " has finally stopped being so Clumsy.", Day0Night1);

	return false;
}
Example #16
0
// `J` Job Farm - Producers
bool cJobManager::WorkBrewer(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKCOOKING;
	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, actiontype, 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 as a brewer on the farm.\n\n";

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

	double wages = 20, tips = 0;
	int enjoy = 0;
	int imagetype = IMGTYPE_COOK;
	int msgtype = Day0Night1;

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


	double jobperformance = JP_Brewer(girl, false);
	double drinksproduced = jobperformance;

	if (jobperformance >= 245)
	{
		ss << " She must be the perfect at this.";
		wages += 155;
	}
	else if (jobperformance >= 185)
	{
		ss << " She's unbelievable at this.";
		wages += 95;
	}
	else if (jobperformance >= 145)
	{
		ss << " She's good at this job.";
		wages += 55;
	}
	else if (jobperformance >= 100)
	{
		ss << " She made a few mistakes but overall she is okay at this.";
		wages += 15;
	}
	else if (jobperformance >= 70)
	{
		ss << " She was nervous and made a few mistakes. She isn't that good at this.";
		wages -= 5;
	}
	else
	{
		ss << " She was nervous and constantly making mistakes. She really isn't very good at this job.";
		wages -= 15;
	}
	ss << "\n\n";



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



	if (wages < 0) wages = 0;
#if 1
	//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;
	}
#else
	if (roll_a <= 10)
	{
		enjoyC -= g_Dice % 3; enjoyF -= g_Dice % 3;
		CleanAmt = int(CleanAmt * 0.8);
		/* */if (roll_b < 30)	ss << "She spilled a bucket of something unpleasant all over herself.";
		else if (roll_b < 60)	ss << "She stepped in something unpleasant.";
		else /*            */	ss << "She did not like working on the farm today.";
	}
	else if (roll_a >= 90)
	{
		enjoyC += g_Dice % 3; enjoyF += g_Dice % 3;
		CleanAmt = int(CleanAmt * 1.1);
		/* */if (roll_b < 50)	ss << "She cleaned the building while humming a pleasant tune.";
		else /*            */	ss << "She had a great time working today.";
	}
	else
	{
		enjoyC += g_Dice % 2; enjoyF += g_Dice % 2;
		ss << "The shift passed uneventfully.";
	}
	ss << "\n\n";
#endif


#pragma endregion
#pragma region	//	Create Items				//


	// `J` Farm Bookmark - adding in items that can be created in the farm
	string itemmade = "";
	string itemtext = "";
	int numbermade = 0;
	sInventoryItem* item = NULL;

	if (g_Dice.percent(min(90.0, jobperformance / 2)))
	{
		int chooseitem = g_Dice % (girl->magic() < 80 ? 80 : 100);	// limit some of the more magical items

		/* */if (chooseitem < 25) { itemmade = "Alcohol";					numbermade = (g_Dice % 5) + 2;	itemtext = " bottles of Alcohol "; }
		else if (chooseitem < 50) { itemmade = "Alcohol ";					numbermade = (g_Dice % 5) + 2;	itemtext = " bottles of Alcohol "; }
		else if (chooseitem < 55) { itemmade = "RigJuice";					numbermade = (g_Dice % 5) + 2;	itemtext = " bottles of RigJuice "; }
		else if (chooseitem < 60) { itemmade = "Radicola";					numbermade = (g_Dice % 5) + 2;	itemtext = " bottles of Radicola "; }
		else if (chooseitem < 65) { itemmade = "Black Cat Beer";			numbermade = 1;	itemtext = " bottle of Black Cat Beer "; }
		else if (chooseitem < 70) { itemmade = "Crossgate Egg Nog";			numbermade = 1;	itemtext = " bottle of Crossgate Egg Nog "; }
		else if (chooseitem < 75) { itemmade = "Nightmare Fuel";			numbermade = 1;	itemtext = " bottle of Nightmare Fuel "; }
		else if (chooseitem < 80) { itemmade = "Nightmare Fuel X";			numbermade = 1;	itemtext = " bottle of Nightmare Fuel "; }
		else if (chooseitem < 83) { itemmade = "Nightmare Fuel XY";			numbermade = 1;	itemtext = " bottle of Nightmare Fuel "; }
		else if (chooseitem < 84) { itemmade = "Nightmare Fuel XYZ";		numbermade = 1;	itemtext = " bottle of Nightmare Fuel "; }
		else if (chooseitem < 85) { itemmade = "Bimbo Liqueur";				numbermade = 1;	itemtext = " bottle of Bimbo Liqueur "; }
		else if (chooseitem < 86) { itemmade = "Mississippi Queen (Ch)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 87) { itemmade = "Mississippi Queen (De)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 88) { itemmade = "Mississippi Queen (FF)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 89) { itemmade = "Mississippi Queen (Fg)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 90) { itemmade = "Mississippi Queen (Fl)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 91) { itemmade = "Mississippi Queen (IW)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 92) { itemmade = "Mississippi Queen (MF)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 93) { itemmade = "Mississippi Queen (Mk)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 94) { itemmade = "Mississippi Queen (Ml)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 95) { itemmade = "Mississippi Queen (Op)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 96) { itemmade = "Mississippi Queen (Ps)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 97) { itemmade = "Mississippi Queen (Rt)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 98) { itemmade = "Mississippi Queen (St)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else if (chooseitem < 99) { itemmade = "Mississippi Queen (To)";	numbermade = 1;	itemtext = " Mississippi Queen "; }
		else /*                */ { itemmade = "Mississippi Queen (Tw)";	numbermade = 1;	itemtext = " Mississippi Queen "; }

		item = g_InvManager.GetItem(itemmade);

	}
	if (item)
	{
		msgtype = EVENT_GOODNEWS;
		ss << "\n\n" << girlName << " made ";
		if (numbermade == 1) ss << "one ";
		else ss << numbermade << " ";
		ss << itemmade << " for you.";
		for (int i = 0; i < numbermade; i++)
			g_Brothels.AddItemToInventory(item);
	}





#pragma endregion
#pragma region	//	Money					//



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


	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);

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

	// Improve stats
	int xp = 5, 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; }

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	// primary (+2 for single or +1 for multiple)
	g_Girls.UpdateSkill(girl, SKILL_BREWING, (g_Dice % skill) + 2);
	// secondary (-1 for one then -2 for others)
	g_Girls.UpdateSkill(girl, SKILL_HERBALISM, max(0, (g_Dice % skill) - 1));
	g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, max(0, (g_Dice % skill) - 2));
	g_Girls.UpdateSkill(girl, SKILL_COOKING, max(0, (g_Dice % skill) - 2));

#pragma endregion
	return false;
}
// `J` Job Arena - Fighting
bool cJobManager::WorkFightBeast(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
    int actiontype = ACTION_COMBAT;
    stringstream ss;
    string girlName = girl->m_Realname;
    ss << girlName;

    if (g_Brothels.GetNumBeasts() < 1)
    {
        ss << " had no beasts to fight.";
        girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
        return false;	// not refusing
    }
    int roll = g_Dice.d100();
    if (roll <= 10 && g_Girls.DisobeyCheck(girl, actiontype, brothel))
    {
        ss << " refused to fight beasts today.\n";
        girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
        return true;
    }


    g_Girls.EquipCombat(girl);	// ready armor and weapons!
    Uint8 fight_outcome = 0;
    int wages = 175, enjoy = 0;
    double jobperformance = JP_FightBeast(girl, false);

    if (roll <= 15)
    {
        ss << " didn't like fighting beasts today.";
        enjoy -= 3;
    }
    else if (roll >= 90)
    {
        ss << " loved fighting beasts today.";
        enjoy += 3;
    }
    else
    {
        ss << " had a pleasant time fighting beasts today.";
        enjoy += 1;
    }
    ss << "\n\n";

    // TODO need better dialog

    sGirl* tempgirl = g_Girls.CreateRandomGirl(18, false, false, false, true, false);
    if (tempgirl)		// `J` reworked incase there are no Non-Human Random Girls
    {
        fight_outcome = g_Girls.girl_fights_girl(girl, tempgirl);
    }
    else
    {
        g_LogFile.write("Error: You have no Non-Human Random Girls for your girls to fight\n");
        g_LogFile.write("Error: You need a Non-Human Random Girl to allow WorkFightBeast randomness");
        fight_outcome = 7;
    }
    if (fight_outcome == 7)
    {
        ss << "The beasts were not cooperating and refused to fight.\n\n";
        ss << "(Error: You need a Non-Human Random Girl to allow WorkFightBeast randomness)";
        girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);
    }
    else if (fight_outcome == 1)	// she won
    {
        ss << "She had fun fighting beasts today.";
        enjoy += 3;
        girl->m_Events.AddMessage(ss.str(), IMGTYPE_COMBAT, Day0Night1);
        int roll_max = girl->fame() + girl->charisma();
        roll_max /= 4;
        wages += 10 + g_Dice%roll_max;
        girl->m_Pay = wages;
        g_Girls.UpdateStat(girl, STAT_FAME, 2);
    }
    else  // she lost or it was a draw
    {
        ss << "She was unable to win the fight.";
        enjoy -= 1;
        //Crazy i feel there needs be more of a bad outcome for losses added this... Maybe could use some more
        if (m_JobManager.is_sex_type_allowed(SKILL_BEASTIALITY, brothel) && !g_Girls.HasTrait(girl, "Virgin"))
        {
            ss << " So as punishment you allow the beast to have its way with her.";
            enjoy -= 1;
            g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -50);
            g_Girls.UpdateSkill(girl, SKILL_BEASTIALITY, 2);
            girl->m_Events.AddMessage(ss.str(), IMGTYPE_BEAST, Day0Night1);
            if (!girl->calc_insemination(The_Player, false, 1.0))
            {
                g_MessageQue.AddToQue(girl->m_Realname + " has gotten inseminated", 0);
            }
        }
        else
        {
            ss << " So you send your men in to cage the beast before it can harm her.";
            girl->m_Events.AddMessage(ss.str(), IMGTYPE_COMBAT, Day0Night1);
            g_Girls.UpdateStat(girl, STAT_FAME, -1);
        }
    }

    int kills = g_Dice % 6 - 4;		 		// `J` how many beasts she kills 0-2
    if (g_Brothels.GetNumBeasts() < kills)	// or however many there are
        kills = g_Brothels.GetNumBeasts();
    if (kills < 0) kills = 0;				// can't gain any
    g_Brothels.add_to_beasts(kills);

    if (girl->is_pregnant())
    {
        if (g_Girls.GetStat(girl, STAT_STRENGTH) >= 60)
        {
            ss << "\n\nAll that fighting proved to be quite exhausting for a pregnant girl, even for one as strong as " << girlName << " .\n";
        }
        else
        {
            ss << "\n\nAll that fighting proved to be quite exhausting for a pregnant girl like " << girlName << " .\n";
        }
        g_Girls.UpdateStat(girl, STAT_TIREDNESS, 10 - g_Girls.GetStat(girl, STAT_STRENGTH) / 20 );
    }

    // Cleanup
    if (tempgirl) delete tempgirl;
    tempgirl = 0;


    if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
    {
        wages = 0;
    }

    int earned = 0;
    for (int i = 0; i < jobperformance; i++)
    {
        earned += g_Dice % 10 + 5; // 5-15 gold per customer  This may need tweaked to get it where it should be for the pay
    }
    brothel->m_Finance.arena_income(earned);
    ss.str("");
    ss << girlName << " drew in " << jobperformance << " people to watch her and you earned " << earned << " from it.";
    girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);

    g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
    // Improve girl
    int fightxp = (fight_outcome == 1 ? 3 : 1);
    int xp = 3 * fightxp, libido = 2, 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;
    }

    g_Girls.UpdateStat(girl, STAT_EXP, xp);
    g_Girls.UpdateSkill(girl, SKILL_COMBAT, g_Dice%fightxp + skill);
    g_Girls.UpdateSkill(girl, SKILL_MAGIC, g_Dice%fightxp + skill);
    g_Girls.UpdateStat(girl, STAT_AGILITY, g_Dice%fightxp + skill);
    g_Girls.UpdateStat(girl, STAT_CONSTITUTION, g_Dice%fightxp + skill);
    g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);
    g_Girls.UpdateSkill(girl, SKILL_BEASTIALITY, g_Dice%fightxp * 2 + skill);

    g_Girls.PossiblyGainNewTrait(girl, "Tough", 20, actiontype, "She has become pretty Tough from all of the fights she's been in.", Day0Night1);
    g_Girls.PossiblyGainNewTrait(girl, "Aggressive", 60, actiontype, "She is getting rather Aggressive from her enjoyment of combat.", Day0Night1);
    g_Girls.PossiblyGainNewTrait(girl, "Fleet of Foot", 30, actiontype, "She is getting rather fast from all the fighting.", Day0Night1);
    if (g_Dice.percent(25) && g_Girls.GetStat(girl, STAT_STRENGTH) >= 60 && g_Girls.GetSkill(girl, SKILL_COMBAT) > g_Girls.GetSkill(girl, SKILL_MAGIC))
    {
        g_Girls.PossiblyGainNewTrait(girl, "Strong", 60, ACTION_COMBAT, girlName + " has become pretty Strong from all of the fights she's been in.", Day0Night1);
    }

    //lose traits
    g_Girls.PossiblyLoseExistingTrait(girl, "Fragile", 75, actiontype, girl->m_Realname + " has had to heal from so many injuries you can't say she is fragile anymore.", Day0Night1);

    return false;
}
// `J` Job House - General - job_is_cleaning
bool cJobManager::WorkCleanHouse(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKCLEANING;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	int roll_a = g_Dice.d100(), roll_b = g_Dice.d100();
	if (roll_a <= 50 && g_Girls.DisobeyCheck(girl, actiontype, brothel))
	{
		ss << " refused to clean your house.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked cleaning your house.\n\n";

	

	g_Girls.UnequipCombat(girl);	// put that shit away

	double CleanAmt = ((g_Girls.GetSkill(girl, SKILL_SERVICE) / 10) + 5) * 10;
	CleanAmt += JP_CleanHouse(girl, false);

	int enjoy = 0;
	int wages = 0;
	int jobperformance = 0;
	bool playtime = false;

	if (roll_a <= 10)
	{
		enjoy -= g_Dice % 3 + 1;
		CleanAmt *= 0.8;
		if (roll_b < 50)	ss << "She spilled a bucket of something unpleasant all over herself.";
		else				ss << "She did not like cleaning your house today.";

	}
	else if (roll_a >= 90)
	{
		enjoy += g_Dice % 3 + 1;
		CleanAmt *= 1.1;
		if (roll_b < 50)	ss << "She cleaned the building while humming a pleasant tune.";
		else				ss << "She had a great time working today.";
	}
	else
	{
		enjoy += g_Dice % 2;
		ss << "The shift passed uneventfully.";
	}
	ss << "\n\n";

	// slave girls not being paid for a job that normally you would pay directly for do less work
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		CleanAmt *= 0.9;
		wages = 0;
	}
	else
	{
		wages = (int)CleanAmt; // `J` Pay her based on how much she cleaned
	}

	// `J` if she can clean more than is needed, she has a little free time after her shift
	if (brothel->m_Filthiness < CleanAmt / 2) playtime = true;
	ss << gettext("\n\nCleanliness rating improved by ") << CleanAmt;
	if (playtime)	// `J` needs more variation
	{
		ss << "\n\n" << girlName << " finished her cleaning early so she just sat around the house.";
		g_Girls.UpdateStat(girl, STAT_TIREDNESS, -((g_Dice % 5) + 2));
		g_Girls.UpdateStat(girl, STAT_HAPPINESS, (g_Dice % 5) + 2);
	}

	// do all the output
	girl->m_Events.AddMessage(ss.str(), IMGTYPE_MAID, Day0Night1);
	brothel->m_Filthiness -= (int)CleanAmt;
	girl->m_Pay = wages;

	// Improve girl
	int xp = 5, libido = 1, skill = 3;
	if (enjoy > 1)										{ xp += 1; 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; }

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 2);
	g_Girls.UpdateSkill(girl, SKILL_SERVICE, (g_Dice % skill) + 2);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
	// Gain Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyGainNewTrait(girl, "Maid", 70, actiontype, girlName + " has cleaned enough that she could work professionally as a Maid anywhere.", Day0Night1);
	// Lose Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyLoseExistingTrait(girl, "Clumsy", 30, actiontype, "It took her spilling hundreds of buckets, and just as many reprimands, but " + girl->m_Realname + " has finally stopped being so Clumsy.", Day0Night1);

	return false;
}
// `J` Job Farm - Staff - Learning_Job
bool cJobManager::WorkFarmResearch(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKTRAINING;
	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, actiontype, 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 as a reseacher on the farm.";

	g_Girls.UnequipCombat(girl);	// put that shit away
	
	double wages = 20, tips = 0;
	int enjoy = 0;
	int imagetype = IMGTYPE_PROFILE;
	int msgtype = Day0Night1;

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

	int train = 0;												// main skill trained
	int tanm = girl->m_Skills[SKILL_ANIMALHANDLING];			// Starting level - train = 1
	int tfar = girl->m_Skills[SKILL_FARMING];					// Starting level - train = 2
	int tmag = girl->m_Skills[SKILL_MAGIC];						// Starting level - train = 3
	int ther = girl->m_Skills[SKILL_HERBALISM];					// Starting level - train = 4
	int tint = girl->m_Stats[STAT_INTELLIGENCE];				// Starting level - train = 5
	bool gaintrait = false;										// posibility of gaining a trait
	int skill = 0;												// gian for main skill trained
	int dirtyloss = brothel->m_Filthiness / 100;				// training time wasted with bad equipment
	int sgAnm = 0, sgFar = 0, sgMag = 0, sgHer = 0, sgInt = 0;	// gains per skill


	/* */if (roll_a <= 5)	skill = 7;
	else if (roll_a <= 15)	skill = 6;
	else if (roll_a <= 30)	skill = 5;
	else if (roll_a <= 60)	skill = 4;
	else /*             */	skill = 3;
	/* */if (g_Girls.HasTrait(girl, "Quick Learner"))	{ skill += 1; }
	else if (g_Girls.HasTrait(girl, "Slow Learner"))	{ skill -= 1; }
	skill -= dirtyloss;
	ss << "The Farm Lab is ";
	if (dirtyloss <= 0) ss << "clean and tidy";
	if (dirtyloss == 1) ss << "dirty and the equipment has not been put back in its place";
	if (dirtyloss == 2) ss << "messy. The equipment is damaged and strewn about the building";
	if (dirtyloss == 3) ss << "filthy and some of the equipment is broken";
	if (dirtyloss >= 4) ss << "in complete disarray and the equipment barely usable";
	ss << ".\n\n";
	if (skill < 1) skill = 1;	// always at least 1 

	do{		// `J` New method of selecting what job to do
		/* */if (roll_b < 20  && tanm < 100)	train = 1;	// animalhandling
		else if (roll_b < 40  && tfar < 100)	train = 2;	// farming
		else if (roll_b < 60  && tmag < 100)	train = 3;	// magic
		else if (roll_b < 80  && ther < 100)	train = 4;	// herbalism
		else if (roll_b < 100 && tint < 100)	train = 5;	// intelligence
		roll_b -= 10;
	} while (train == 0 && roll_b > 0);
	if (train == 0 || g_Dice.percent(5)) gaintrait = true;

	if (train == 1) { sgAnm = skill; ss << "She researches animals.\n"; }				else sgAnm = g_Dice % 2;
	if (train == 2) { sgFar = skill; ss << "She researches farming techniques.\n"; }	else sgFar = g_Dice % 2;
	if (train == 3) { sgMag = skill; ss << "She researches magical techniques.\n"; }	else sgMag = g_Dice % 2;
	if (train == 4) { sgHer = skill; ss << "She researches plants and their uses.\n"; }	else sgHer = g_Dice % 2;
	if (train == 5) { sgInt = skill; ss << "She researches general topics.\n"; }		else sgInt = g_Dice % 2;

	if (sgAnm + sgFar + sgMag + sgHer + sgInt > 0)
	{
		ss << "She managed to gain:\n";
		if (sgAnm > 0) { ss << sgAnm << " Animal Handling\n";	g_Girls.UpdateSkill(girl, SKILL_ANIMALHANDLING, sgAnm); }
		if (sgFar > 0) { ss << sgFar << " Farming\n";			g_Girls.UpdateSkill(girl, SKILL_FARMING, sgFar); }
		if (sgMag > 0) { ss << sgMag << " Magic\n";				g_Girls.UpdateSkill(girl, SKILL_MAGIC, sgMag); }
		if (sgHer > 0) { ss << sgHer << " Herbalism\n";			g_Girls.UpdateSkill(girl, SKILL_HERBALISM, sgHer); }
		if (sgInt > 0) { ss << sgInt << " Intelligence\n";		g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, sgInt); }
	}
	
	int trycount = skill;
	while (gaintrait && trycount > 0)	// `J` Try to add a trait 
	{
		trycount--;
		switch (g_Dice % 10)
		{
		case 0:
			break;
		case 1:
			break;
		case 2:
			if (g_Girls.HasTrait(girl, "Dependant"))
			{
				g_Girls.RemoveTrait(girl, "Dependant");
				ss << "She seems to be getting over her Dependancy with her training.";
				gaintrait = false;
			}
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:

			break;
		case 6:

			break;

		default:	break;	// no trait gained
		}
	}
	ss << "\n\n";

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


	//enjoyed the work or not
	/* */if (roll_c <= 10)	{ enjoy -= g_Dice % 3 + 1;	ss << "She did not enjoy her time training."; }
	else if (roll_c >= 90)	{ enjoy += g_Dice % 3 + 1;	ss << "She had a pleasant time training."; }
	else /*             */	{ enjoy += g_Dice % 2;		ss << "Otherwise, the shift passed uneventfully."; }
	
	ss << "\n\n";

#pragma endregion
#pragma region	//	Create Items				//



	// `J` Farm Bookmark - adding in items that can be created in the farm
	if (girl->intelligence() + girl->crafting() > 100 && g_Dice.percent(girl->intelligence() + girl->crafting() / 10))	// 10-20%
	{
		sInventoryItem* item = NULL;
		string itemname = "";
		int tries = skill;
		while (itemname == "" && tries > 0)
		{
			switch (g_Dice % 20)
			{
				/*	For each item available, the girl making it must have:
				Skills:
				*	If an item gives less than 40 skill points, the girl must have 40 more than the amount given in that skill
				*	If it gives more than 40 points, there will need to be some magic included.
				*	If there are multiple skills, add 40 to each bonus and if skills (a+b+c) > bonus total
				Stats:
				*	Stats will need more variation in how high they are needed because it is less knowledge than conditioning
				Traits:
				*	Most traits will require some magic
				Randomness:
				*	There also should be a g_Dice.percent() with the main Skills averaged and divided by 10
				*		If there are 3 skills, then g_Dice.percent((a+b+c)/30)
				*/
			case 0:
				if (girl->farming() > 50 && girl->animalhandling() > 50
					&& g_Dice.percent(girl->farming() + girl->animalhandling() / 20))
					itemname = "Farmer's Guide";		// +10 Farming, +10 AnimalHandling
				break;
			case 1:
				if (girl->constitution() > 60 && g_Dice.percent(girl->constitution() / 10))
					itemname = "Manual of Health";		// (+15 Beast/Group, +10 Cons/Str, +5 BDSM/Comb)
				break;
			case 2:
				if (girl->magic() > 60 && g_Dice.percent(girl->magic() / 10))
					itemname = "Manual of Magic";		// +20 magic
				break;
			case 3:
				if (girl->magic() > 80 && g_Dice.percent(girl->magic() / 10))
					itemname = "Codex of the Arcane";	// +40 magic
				break;
			case 4:
				if (girl->lesbian() > 40 && g_Dice.percent(girl->lesbian() / 10))
					itemname = "Manual of Two Roses";	// +20 Lesbian
				break;
			case 5:
			{
				if (girl->lesbian() > 80 && g_Dice.percent(girl->lesbian() / 10))
					itemname = "Codex of Sappho";		// +40 Lesbian
			}break;
			case 6:
				if (girl->bdsm() > 60 && g_Dice.percent(girl->bdsm() / 10))
					itemname = "Manual of Bondage";		// (+20 BDSM, +5 Cons)
				break;
			case 7:
				if (girl->combat() > 60 && g_Dice.percent(girl->combat() / 10))
					itemname = "Manual of Arms";		// (+20 Com)
				break;
			case 8:
				if (girl->performance() + girl->strip() > 100 && g_Dice.percent((girl->performance() + girl->strip()) / 20))
					itemname = "Manual of the Dancer";	// (+15 Serv/Strip/Perf, +5 Norm/Agi)
				break;
			case 9:
				if (girl->normalsex() + girl->oralsex() + girl->anal() > 150 && g_Dice.percent((girl->normalsex() + girl->oralsex() + girl->anal()) / 30))
					itemname = "Manual of Sex";			// (+15 Norm, +10 Oral, +5 Anal)
				break;
			case 10:
			{
				if (girl->magic() < 80 && girl->mana() < 20) break;
				int manacost = 60;
				/* */if (girl->has_trait("Sterile"))		manacost = 80;
				else if (girl->has_trait("Fertile"))		manacost = 40;
				else if (girl->has_trait("Broodmother"))	manacost = 20;
				if (girl->mana() >= manacost && g_Dice.percent(girl->magic() - manacost))
				{
					girl->mana(-manacost);
					itemname = "Fertility Tome";				// (-Sterile, +Fertile, +50 Normal Sex, +100 Libido)
				}
			}break;
			case 11:
			{
				// Noble, Princess and Queen needs 40, everyone else needs 60 to make this
				if (girl->has_trait("Noble") || girl->has_trait("Princess") || girl->has_trait("Queen"))
					if (girl->refinement() < 40 || girl->service() < 40 || girl->intelligence() < 40)		break;
				else if (girl->refinement() < 60 && girl->service() < 60 && girl->intelligence() < 60)		break;
				// she can make it, now does she?
				if (g_Dice.percent((girl->refinement() + girl->service() + girl->intelligence()) / 30))
					itemname = "Codex of the Courtesan";		// (+20 Serv/Strip/Refin, +10 Mor/Dig/Cha/Int/Lib/Conf/Oral)
			}break;
			case 12:
			{
				int manacost = 70;
				// Dominatrix, M*******t and Sadistic needs 50, everyone else needs 70 to make this
				if (girl->has_trait("Dominatrix") || girl->has_trait("M*******t") || girl->has_trait("Sadistic"))
				{
					if (girl->bdsm() < 50 || girl->magic() < 50 || girl->mana() < 50)		break;
					manacost = 50;
				}
				else if (girl->bdsm() < 70 && girl->magic() < 70 && girl->mana() < 70)		break;
				// she can make it, now does she?
				if (g_Dice.percent((girl->bdsm() + girl->magic()) / 20))
				{
					girl->mana(-manacost);
					itemname = "Codex of Submission";		// (+30 Obed, -30 Spi/Dig, +20 BDSM, +10 Anal/Group/Oral/Hand/Foot)
				}
			}break;
			case 13:
			{
				if (girl->combat() > 80 && g_Dice.percent(girl->combat() / 10))
					itemname = "Codex of Mars";			// (+40 Com, Adds Brawler)
			}break;
			case 14:
			{
				if (girl->normalsex() + girl->oralsex() + girl->anal() > 170 && g_Dice.percent((girl->normalsex() + girl->oralsex() + girl->anal()) / 30))
					itemname = "Codex of Eros";			// (+30 Norm, +10 Anal/Oral)
			}break;
			case 15:
			{
				if (girl->medicine() + girl->intelligence() > 110 && g_Dice.percent((girl->medicine() + girl->intelligence()) / 20))
					itemname = "Codex of Asclepius";	// (+20 Med, +10 Int)
			}break;
			case 16:
			{
				/*

				*/
			}break;
			case 17:
			{
				/*

				*/
			}break;
			case 18:
			{
				/*

				*/
			}break;

			default:
				break;
			}
		}
		
		item = g_InvManager.GetItem(itemname);
		if (item)
		{
			g_Brothels.AddItemToInventory(item);
			ss << girlName << " managed to create a " << itemname << " by compiling her notes together.\n";
		}
	}



#pragma endregion
#pragma region	//	Money					//

	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket())) { wages = 0; }
	else { wages = 25 + (skill * 5); } // `J` Pay her more if she learns more


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


	
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);

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

	// Improve stats
	int xp = 5 + skill, libido = int(1 + skill / 2);

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

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

#pragma endregion
	return false;
}
// `J` Job Brothel - Sleazy Bar
bool cJobManager::WorkSleazyBarmaid(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKCLUB;
	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, actiontype, brothel))
	{
		ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked as a bartender in the strip club.\n\n";

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

	int HateLove = 0;
	HateLove = g_Girls.GetStat(girl, STAT_PCLOVE) - g_Girls.GetStat(girl, STAT_PCHATE);
	double wages = 15, tips = 0;
	int enjoy = 0, fame = 0;
	int imagetype = IMGTYPE_ECCHI;
	int msgtype = Day0Night1;

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

	double jobperformance = JP_SleazyBarmaid(girl, false);



	if (jobperformance >= 245)
	{
		ss << " She must be the perfect bar tender customers go on and on about her and always come to see her when she works.\n\n";
		wages += 155;
	}
	else if (jobperformance >= 185)
	{
		ss << " She's unbelievable at this and is always getting praised by the customers for her work.\n\n";
		wages += 95;
	}
	else if (jobperformance >= 145)
	{
		ss << " She's good at this job and gets praised by the customers often.\n\n";
		wages += 55;
	}
	else if (jobperformance >= 100)
	{
		ss << " She made a few mistakes but overall she is okay at this.\n\n";
		wages += 15;
	}
	else if (jobperformance >= 70)
	{
		ss << " She was nervous and made a few mistakes. She isn't that good at this.\n\n";
		wages -= 5;
	}
	else
	{
		ss << " She was nervous and constantly making mistakes. She really isn't very good at this job.\n\n";
		wages -= 15;
	}


	//base tips, aprox 10-20% of base wages
	tips += (((10 + jobperformance / 22) * wages) / 100);
	
	//try and add randomness here
	if (g_Girls.GetStat(girl, STAT_BEAUTY) > 85 && g_Dice.percent(20))
	{
		ss << "Stunned by her beauty a customer left her a great tip.\n\n"; tips += 25;
	}

	if (g_Girls.GetStat(girl, STAT_BEAUTY) > 99 && g_Dice.percent(5))
	{
		ss << girlName << " looked absolutely stunning during her shift and was unable to hide it. Instead of her ass or t**s, the patrons couldn't glue their eyes off her face, and spent a lot more than usual on tipping her.\n"; tips += 50;
	}

	if (g_Girls.GetStat(girl, STAT_CHARISMA) > 85 && g_Dice.percent(20))
	{
		ss << girlName << " surprised a couple of gentlemen discussing some complicated issue by her insightful comments when she was taking her order. They decided her words were worth a heavy tip.\n"; tips += 35;
	}

	if (g_Girls.HasTrait(girl, "Clumsy") && g_Dice.percent(15))
	{
		ss << "Her clumsy nature caused her to spill a drink on a customer resulting in them storming off without paying.\n"; wages -= 15;
	}

	if (g_Girls.HasTrait(girl, "Pessimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			ss << "Her pessimistic mood depressed the customers making them tip less.\n"; tips -= 10;
		}
		else
		{
			ss << girlName << " was in a poor mood so the patrons gave her a bigger tip to try and cheer her up.\n"; tips += 10;
		}
	}

	if (g_Girls.HasTrait(girl, "Optimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			ss << girlName << " was in a cheerful mood but the patrons thought she needed to work more on her services.\n"; tips -= 10;
		}
		else
		{
			ss << "Her optimistic mood made patrons cheer up increasing the amount they tip.\n"; tips += 10;
		}
	}
	// `J` slightly higher percent compared to regular barmaid, I would think sleazy barmaid's uniform is more revealing
	if ((g_Dice.percent(5) && g_Girls.HasTrait(girl, "Busty Boobs")) ||
		(g_Dice.percent(10) && g_Girls.HasTrait(girl, "Big Boobs")) ||
		(g_Dice.percent(15) && g_Girls.HasTrait(girl, "Giant Juggs")) ||
		(g_Dice.percent(20) && g_Girls.HasTrait(girl, "Massive Melons")) ||
		(g_Dice.percent(25) && g_Girls.HasTrait(girl, "Abnormally Large Boobs")) ||
		(g_Dice.percent(30) && g_Girls.HasTrait(girl, "Titanic T**s")))
	{
		if (jobperformance < 150)
		{
			ss << "A patron was staring obviously at her large breasts. But she had no idea how to take advantage of it.\n";
		}
		else
		{
			ss << "A patron was staring obviously at her large breasts. So she over charged them for drinks while they drooled not paying any mind to the price.\n"; wages += 15;
		}
	}

	if (g_Girls.HasTrait(girl, "Meek") && g_Dice.percent(5) && jobperformance < 125)
	{
		ss << girlName << " spilled a drink all over a man's lap. He told her she had to lick it up and forced her to clean him up which she Meekly accepted and went about licking his c**k clean.\n";
		imagetype = IMGTYPE_ORAL;
		enjoy -= 3;
	}

	if (g_Dice.percent(5)) //may get moved to waitress
	{
		ss << "A drunken patron decide to grab " << girlName << "'s boob. ";
		if (g_Girls.HasTrait(girl, "Meek"))
		{
			ss << "She was shocked and didn't react. The man molested her for a few minutes!\n";
		}
		else if (g_Girls.HasTrait(girl, "Tough"))
		{
			ss << "She knocked him out! You could swear that she knocked a couple of his teeth out too!\n";
		}
		else if (g_Girls.HasTrait(girl, "Your Daughter"))
		{
			ss << "She screamed do you know who my dad is? He will have your head for this!\n";
		}
		else if (g_Girls.HasTrait(girl, "Your Wife"))
		{
			ss << "She screamed do you know who my husband is? He will have your head for this!\n";
		}
		else if (HateLove >= 80) //loves you
		{
			ss << "She screamed do you know who my love is? He will have your head for this!\n";
		}
		else
		{
			ss << "She screamed and shook his hand off.\n";
		}
	}

	if ((g_Girls.HasTrait(girl, "Nymphomaniac") || g_Girls.HasTrait(girl, "Succubus")) && g_Girls.GetStat(girl, STAT_LIBIDO) > 80 && g_Dice.percent(20) && !g_Girls.HasTrait(girl, "Virgin") && !g_Girls.HasTrait(girl, "Lesbian"))
	{
		if (roll_b <= 50)
		{
			ss << girlName << " dragged one of the less sober clients outside into a back alley and ordered him to f**k her senseless against a wall. After the deed, the poor fellow passed out and " << girlName << " returned to her job as if nothing happened.\n";
		}
		else
		{
			ss << girlName << " spotted a relatively good-looking guy walking into the bathroom alone. She followed him inside, and as he tried to exit the bathroom stall, he got pushed back in by her. " << girlName << " didn't waste any time and in a matter of seconds was vigorously f*****g the client. After the deed, the client made sure " << girlName << " had a pretty hefty wad of money stuck behind her skirt.\n"; tips += 50;
		}
		imagetype = IMGTYPE_SEX;
		g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, -20);
		g_Girls.UpdateSkill(girl, SKILL_NORMALSEX, 1);
		sCustomer* Cust = new sCustomer; g_Customers.GetCustomer(Cust, brothel); Cust->m_Amount = 1;
		if (!girl->calc_pregnancy(Cust, false, 1.0))
		{
			g_MessageQue.AddToQue(girl->m_Realname + " has gotten pregnant.", 0);
		}
		delete Cust;
	}

#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;
	}


#pragma endregion
#pragma region	//	Money					//


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


	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
	girl->m_Events.AddMessage(ss.str(), imagetype, Day0Night1);


	int roll_max = (g_Girls.GetStat(girl, STAT_BEAUTY) + g_Girls.GetStat(girl, STAT_CHARISMA));
	roll_max /= 4;
	wages += 10 + g_Dice%roll_max;
	// Money
	if (wages < 0)	wages = 0;	girl->m_Pay = (int)wages;
	if (tips < 0)	tips = 0;	girl->m_Tips = (int)tips;

	// Improve stats
	int xp = 15, 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 (!g_Girls.HasTrait(girl, "Straight"))	{ libido += min(3, g_Brothels.GetNumGirlsOnJob(0, JOB_BARSTRIPPER, false)); }
	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() < 60 && jobperformance >= 185)		{ fame += 1; }

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

	//gained
	g_Girls.PossiblyGainNewTrait(girl, "Charismatic", 60, actiontype, "Dealing with customers at the bar and talking with them about their problems has made " + girlName + " more Charismatic.", Day0Night1);
	if (jobperformance < 100 && roll_a <= 2) { g_Girls.PossiblyGainNewTrait(girl, "Assassin", 10, actiontype, girlName + "'s lack of skill at mixing drinks has been killing people left and right making her into quite the Assassin.", Day0Night1); }
	if (g_Dice.percent(25) && g_Girls.GetStat(girl, STAT_DIGNITY) < 0 && (imagetype == IMGTYPE_SEX || imagetype == IMGTYPE_ORAL))
	{
		g_Girls.PossiblyGainNewTrait(girl, "S**t", 80, ACTION_SEX, girlName + " has turned into quite a s**t.", Day0Night1);
	}

	//lose
	g_Girls.PossiblyLoseExistingTrait(girl, "Nervous", 20, actiontype, girlName + " seems to finally be getting over her shyness. She's not always so Nervous anymore.", Day0Night1);


#pragma endregion
	return false;
}
Example #21
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
}
Example #22
0
// `J` Job Farm - Laborers
bool cJobManager::WorkFarmer(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKFARM;
	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, actiontype, 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 tending crops on the farm.\n\n";

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

	double wages = 20, tips = 0;
	int enjoy = 0;
	int imagetype = IMGTYPE_FARM;
	int msgtype = Day0Night1;

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

	double jobperformance = (int)JP_Farmer(girl, false);
	double foodproduced = jobperformance;
	int alchemyproduced = 0;
	int goodsproduced = 0;

	if (jobperformance >= 245)
	{
		ss << "Her basket practically fills itself as she walks down the rows of crops.";
		foodproduced *= 5; roll_a += 10; roll_b += 25;
	}
	else if (jobperformance >= 185)
	{
		ss << "Her hands moved like lightning as she picked only the best crops.";
		foodproduced *= 4; roll_a += 5; roll_b += 18;
	}
	else if (jobperformance >= 145)
	{
		ss << "She knows exactly when the crops are ready to be picked and how to best collect them.";
		foodproduced *= 3; roll_a += 2; roll_b += 10;
	}
	else if (jobperformance >= 100)
	{
		ss << "She can pick the crops fairly well without too many culls.";
		foodproduced *= 2;
	}
	else if (jobperformance >= 70)
	{
		ss << "She isn't very good at knowing which plants are ripe and which should have been left a little longer.";
		roll_a -= 2; roll_b -= 5;
	}
	else
	{
		ss << "She seems to take more of the unuseable parts of the plants than she takes the edible parts.";
		wages -= 10; foodproduced *= 0.8; roll_a -= 5; roll_b -= 10;
	}
	ss << "\n\n";

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

	int tired = (300 - (int)jobperformance);	// this gets divided in roll_a by (8, 10 or 12) so it will end up around 0-40 tired
	if (roll_a <= 10)
	{
		tired /= 8;
		enjoy -= g_Dice % 3;
		if (roll_b < 20)	// injury
		{
			girl->health(-(1 + g_Dice % 5));
			foodproduced *= 0.8;
			if (g_Dice.percent(girl->magic() / 2))
			{
				girl->mana(-10 - (g_Dice % 10));
				ss << "While trying to use magic to do her work for her, the magic rebounded on her";
			}
			else ss << "She cut herself while working";
			if (girl->health() <= 0)
			{
				ss << " killing her.";
				g_MessageQue.AddToQue(girlName + " was killed in an accident at the Farm.", COLOR_RED);
				return false;	// not refusing, she is dead
			}
			else ss << ".";
		}
		else	// unhappy
		{
			foodproduced *= 0.9;
			ss << "She did not like working in the fields today.";
			girl->happiness(-(g_Dice % 11));
		}
	}
	else if (roll_a >= 90)
	{
		tired /= 12;
		foodproduced *= 1.1;
		enjoy += g_Dice % 3;
		/* */if (roll_b < 50)	ss << "She kept a steady pace by humming a pleasant tune.";
		else /*            */	ss << "She had a great time working today.";
	}
	else
	{
		tired /= 10;
		enjoy += g_Dice % 2;
		ss << "The shift passed uneventfully.";
	}
	ss << "\n\n";

#pragma endregion
#pragma region	//	Create Items				//

	if (g_Dice.percent((girl->farming() + girl->magic()) / 10) && g_Dice.percent(jobperformance / 10))
	{
		string itemname = ""; int itemnumber = 1;
		/* */if (roll_c > 30)	{ itemname = "Nut of Knowledge";		itemnumber = (roll_c > 90 ? g_Dice % 3 + 2 : 1); }
		else if (roll_c > 10)	{ itemname = "Mango of Knowledge";		itemnumber = (roll_c > 28 ? 2 : 1); }
		else/*            */	{ itemname = "Watermelon of Knowledge"; itemnumber = (roll_c == 9 ? 2 : 1); }

		sInventoryItem* item = g_InvManager.GetItem(itemname);
		if (item)
		{
			for (int i = 0; i < itemnumber; i++) g_Brothels.AddItemToInventory(item);
			ss << "While picking crops, " << girlName << " sensed a magical aura and found ";
			if (itemnumber == 1) ss << "a"; else ss << itemnumber;
			ss << " " << itemname << ".\n";
			foodproduced -= itemnumber;
		}
	}
	if (g_Dice.percent(girl->herbalism() / 2) && g_Dice.percent(jobperformance / 10))
	{
		alchemyproduced = 1 + g_Dice % (girl->herbalism() / 10);
		ss << "While sorting the day's haul, " << girlName << " came across ";
		if (alchemyproduced == 1) ss << "a specimen";
		else ss << alchemyproduced << " specimens";
		ss << " that would work well in potions.\n";
		foodproduced -= alchemyproduced;
	}
	if (g_Dice.percent(girl->crafting() / 2) && g_Dice.percent(jobperformance / 10))
	{
		goodsproduced = 1 + g_Dice % (girl->crafting() / 10);
		ss << girlName << " created ";
		if (goodsproduced == 1) ss << "a little toy";
		else ss << goodsproduced << " little toys";
		ss << " from the unuseable parts of her crops.\n";
	}
	if (foodproduced <= 0) foodproduced = 0;

#pragma endregion
#pragma region	//	Money					//

	// slave girls not being paid for a job that normally you would pay directly for do less work
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		foodproduced *= 0.9;
		wages = 0;
	}
	else
	{
		wages += foodproduced / 100; // `J` Pay her based on how much she brought in
	}

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

	if (foodproduced > 0)
	{
		g_Brothels.add_to_food((int)foodproduced);
		ss << "\n" << girlName << " brought in " << (int)foodproduced << " units of food.";
	}
	if (alchemyproduced > 0)	g_Brothels.add_to_alchemy((int)alchemyproduced);
	if (goodsproduced > 0)		g_Brothels.add_to_goods((int)goodsproduced);

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

	// Base Improvement and trait modifiers
	int xp = 5, libido = 1, skill = 3;
	/* */if (girl->has_trait("Quick Learner"))	{ skill += 1; xp += 3; }
	else if (girl->has_trait("Slow Learner"))	{ skill -= 1; xp -= 3; }
	/* */if (girl->has_trait("Nymphomaniac"))	{ libido += 2; }
	// EXP and Libido
	int I_xp = (g_Dice % xp) + 1;							g_Girls.UpdateStat(girl, STAT_EXP, I_xp);
	int I_libido = (g_Dice % libido) + 1;					g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, I_libido);
	if (tired > 0) girl->tiredness(tired);

	// primary improvement (+2 for single or +1 for multiple)
	int I_farming = (g_Dice % skill) + 2;					g_Girls.UpdateSkill(girl, SKILL_FARMING, I_farming);
	// secondary improvement (-1 for one then -2 for others)
	int I_strength = max(0, (g_Dice % skill) - 1);			g_Girls.UpdateStat(girl, STAT_STRENGTH, I_strength);
	int I_constitution = max(0, (g_Dice % skill) - 2);		g_Girls.UpdateStat(girl, STAT_CONSTITUTION, I_constitution);
	int I_intelligence = max(0, (g_Dice % skill) - 2);		g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, I_intelligence);

	// Update Enjoyment
	if (jobperformance < 50) enjoy -= 1; if (jobperformance < 0) enjoy -= 1;	// if she doesn't do well at the job, she enjoys it less
	if (jobperformance > 200) enjoy *= 2;		// if she is really good at the job, her enjoyment (positive or negative) is doubled
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	// Gain Traits
	g_Girls.PossiblyGainNewTrait(girl, "Tough", 50, actiontype, "Working in the heat of the sun has made " + girlName + " rather Tough.", Day0Night1);

	if (cfg.debug.log_show_numbers())
	{
		ss << "\n\nNumbers:"
			<< "\n Job Performance = " << (int)jobperformance
			<< "\n Wages = " << (int)wages
			<< "\n Tips = " << (int)tips
			<< "\n Xp = " << I_xp
			<< "\n Libido = " << I_libido
			<< "\n Farming = " << I_farming
			<< "\n Strength = " << I_strength
			<< "\n Constitution = " << I_constitution
			<< "\n Intelligence = " << I_intelligence
			<< "\n Tiredness = " << tired
			<< "\n Enjoy " << girl->enjoy_jobs[actiontype] << " = " << enjoy
			;
	}

	// Push out the turn report
	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);

#pragma endregion
	return false;
}
// `J` Job Centre - General - job_is_cleaning
bool cJobManager::WorkCleanCentre(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKCLEANING;
	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 (roll_a <= 50 && g_Girls.DisobeyCheck(girl, actiontype, brothel))
	{
		ss << " refused to clean the Centre.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked cleaning the Centre.\n\n";

	g_Girls.UnequipCombat(girl);	// put that shit away

	double CleanAmt = JP_CleanCentre(girl, false);
	int enjoy = 0;
	int wages = 0;
	int tips = 0;
	int imagetype = IMGTYPE_MAID;
	int msgtype = Day0Night1;
	bool playtime = false;

	if (roll_a <= 10)
	{
		enjoy -= g_Dice % 3 + 1;
		CleanAmt *= 0.8;
		if (roll_b < 50)	ss << "She spilled a bucket of something unpleasant all over herself.";
		else				ss << "She did not like cleaning the Centre today.";
	}
	else if (roll_a >= 90)
	{
		enjoy += g_Dice % 3 + 1;
		CleanAmt *= 1.1;
		if (roll_b < 50)	ss << "She cleaned the building while humming a pleasant tune.";
		else				ss << "She had a great time working today.";
	}
	else
	{
		enjoy += g_Dice % 2;
		ss << "The shift passed uneventfully.";
	}
	ss << "\n\n";

	// slave girls not being paid for a job that normally you would pay directly for, do less work
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		CleanAmt *= 0.9;
		wages = 0;
	}
	else
	{
		wages = min(30, int(30 + (CleanAmt / 10))); // `J` Pay her based on how much she cleaned
	}

	// `J` if she can clean more than is needed, she has a little free time after her shift
	if (brothel->m_Filthiness < CleanAmt / 2) playtime = true;
	ss << "\n\nCleanliness rating improved by " << (int)CleanAmt;
	if (playtime)	// `J` needs more variation
	{
		if (roll_a < 20 && roll_b < 60 && roll_c < 50)
		{
			ss << "\n\n" << girlName << " finished her cleaning early so took a long bath to clean herself off.";
			girl->happiness((g_Dice % 3) + 1);
			girl->tiredness(-(g_Dice % 3));
			imagetype = IMGTYPE_BATH;
		}
		else if (roll_c < 50)
		{
			ss << "\n\n" << girlName << " finished her cleaning early so she played with the children a bit.";
			girl->happiness((g_Dice % 5) + 3);
			girl->tiredness(g_Dice % 3);
			girl->morality(g_Dice % 2);
		}
		else
		{
			ss << "\n\n" << girlName << " finished her cleaning early so she took nap.";
			girl->happiness(g_Dice % 3);
			girl->tiredness(-1 - (g_Dice % 10));
			girl->morality(-(g_Dice % 2));
		}

	}

	brothel->m_Filthiness -= (int)CleanAmt;

	// `J` - Finish the shift - CleanCentre

	// Push out the turn report
	girl->m_Events.AddMessage(ss.str(), imagetype, msgtype);
	// Money
	girl->m_Tips = max(0, tips);
	girl->m_Pay = max(0, wages);

	// Base Improvement and trait modifiers
	int xp = 5, libido = 1, skill = 3;
	/* */if (girl->has_trait("Quick Learner"))	{ skill += 1; xp += 3; }
	else if (girl->has_trait("Slow Learner"))	{ skill -= 1; xp -= 3; }
	/* */if (girl->has_trait("Nymphomaniac"))	{ libido += 2; }
	// EXP and Libido
	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido,false);


	// primary improvement (+2 for single or +1 for multiple)
	g_Girls.UpdateSkill(girl, SKILL_SERVICE, (g_Dice % skill) + 2);
	// secondary improvement (-1 for one then -2 for others)
	g_Girls.UpdateStat(girl, STAT_MORALITY, max(-1, (g_Dice % skill) - 1));		// possibly go down but mostly go up
	g_Girls.UpdateStat(girl, STAT_REFINEMENT, max(-1, (g_Dice % skill) - 2));	// possibly go up or down


	// Update Enjoyment
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
	// Gain Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyGainNewTrait(girl, "Maid", 70, actiontype, girlName + " has cleaned enough that she could work professionally as a Maid anywhere.", Day0Night1);
	// Lose Traits
	if (g_Dice.percent(girl->service()))
		g_Girls.PossiblyLoseExistingTrait(girl, "Clumsy", 30, actiontype, "It took her spilling hundreds of buckets, and just as many reprimands, but " + girl->m_Realname + " has finally stopped being so Clumsy.", Day0Night1);

	return false;
}
// `J` Job Arena - Fighting
bool cJobManager::WorkFightArenaGirls(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_COMBAT;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	if (g_Girls.DisobeyCheck(girl, actiontype, 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 << " was assigned to fight other girls in the arena.\n\n";

	
	int wages = 0, fight_outcome = 0, enjoyment = 0, fame = 0, imagetype = IMGTYPE_COMBAT;

	double jobperformance = JP_FightArenaGirls(girl, false);

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

	sGirl* tempgirl = g_Girls.CreateRandomGirl(18, false, false, false, false, false, true);
	if (tempgirl) fight_outcome = g_Girls.girl_fights_girl(girl, tempgirl);
	else fight_outcome = 7;			// `J` reworked incase there are no Non-Human Random Girls
	if (fight_outcome == 7)
	{
		g_LogFile.write("Error: You have no Arena Girls for your girls to fight\n");
		g_LogFile.write("Error: You need an Arena Girl to allow WorkFightArenaGirls randomness");
		ss << "There were no Arena Girls for her to fight.\n\n(Error: You need an Arena Girl to allow WorkFightArenaGirls randomness)";
		imagetype = IMGTYPE_PROFILE;
	}
	else if (fight_outcome == 1)	// she won
	{
		enjoyment = g_Dice % 3 + 1;
		fame = g_Dice % 3 + 1;
		sGirl* ugirl = 0;
		if (g_Dice.percent(10))		// chance of getting unique girl
		{
			ugirl = g_Girls.GetRandomGirl(false, false, true);
		}
		if (ugirl)
		{
			stringstream msg;	// goes to the girl and the g_MessageQue
			stringstream Umsg;	// goes to the new girl
			stringstream Tmsg;	// temp msg
			ugirl->m_Stats[STAT_HEALTH] = g_Dice % 50 + 1;
			ugirl->m_Stats[STAT_HAPPINESS] = g_Dice % 80 + 1;
			ugirl->m_Stats[STAT_TIREDNESS] = g_Dice % 50 + 50;
			ugirl->m_States |= (1 << STATUS_ARENA);
			msg << girlName << " won her fight against " << ugirl->m_Realname << ".\n\n";
			Umsg << ugirl->m_Realname << " lost her fight against your girl " << girlName << ".\n\n";
			Tmsg << ugirl->m_Realname;
			if (g_Dice.percent(50))
			{
				ugirl->m_States |= (1 << STATUS_SLAVE);
				Tmsg << "'s owner could not afford to pay you your winnings so he gave her to you instead.\n\n";
			}
			else
			{
				Tmsg << " put up a good fight so you let her live as long as she came work for you.\n\n";
				wages = 100 + g_Dice % (girl->fame() + girl->charisma());
			}
			msg << Tmsg.str();
			Umsg << Tmsg.str();
			ss << msg.str();
			g_MessageQue.AddToQue(msg.str(), 0);
			ugirl->m_Events.AddMessage(Umsg.str(), IMGTYPE_PROFILE, EVENT_DUNGEON);

			g_Brothels.GetDungeon()->AddGirl(ugirl, DUNGEON_NEWARENA);
		}
		else
		{
			ss << girlName << " won her fight.";
			wages = 100 + g_Dice % (girl->fame() + girl->charisma());
		}
	}
	else if (fight_outcome == 2) // she lost
	{
		enjoyment = -(g_Dice % 3 + 1);
		fame = -(g_Dice % 3 + 1);
		ss << "She lost the fight.";
		int cost = 150;
		brothel->m_Finance.arena_costs(cost);
		ss << " You had to pay " << cost << " gold cause your girl lost.";
		/*that should work but now need to make if you lose the girl if you dont have the gold zzzzz FIXME*/
	}
	else if (fight_outcome == 0)  // it was a draw
	{
		enjoyment = g_Dice % 3 - 2;
		fame = g_Dice % 3 - 2;
		ss << "The fight ended in a draw.";
	}

	if (girl->is_pregnant())
	{
		if (g_Girls.GetStat(girl, STAT_STRENGTH) >= 60)
		{
			ss << "\n\nAll that fighting proved to be quite exhausting for a pregnant girl, even for one as strong as " << girlName << " .\n";
		}
		else
		{
			ss << "\n\nAll that fighting proved to be quite exhausting for a pregnant girl like " << girlName << " .\n";
		}
		g_Girls.UpdateStat(girl, STAT_TIREDNESS, 10 - g_Girls.GetStat(girl, STAT_STRENGTH) / 20 );
	}

	if (tempgirl) delete tempgirl; tempgirl = 0;	// Cleanup


	// Improve girl
	int fightxp = (fight_outcome == 1) ? 3 : 1;
	int xp = 5 * fightxp, libido = 5, skill = 1;

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

	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket()))
	{
		wages = 0;
	}

	girl->m_Pay = wages;
	girl->m_Events.AddMessage(ss.str(), imagetype, Day0Night1);
	g_Girls.UpdateStat(girl, STAT_FAME, fame);
	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateSkill(girl, SKILL_COMBAT, g_Dice%fightxp + skill);
	g_Girls.UpdateSkill(girl, SKILL_MAGIC, g_Dice%fightxp + skill);
	g_Girls.UpdateStat(girl, STAT_AGILITY, g_Dice%fightxp + skill);
	g_Girls.UpdateStat(girl, STAT_CONSTITUTION, g_Dice%fightxp + skill);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoyment);

	/* `J` this will be a place holder until a better payment system gets done
	*
	*/
	int earned = 0;
	for (int i = 0; i < jobperformance; i++)
	{
		earned += g_Dice % 10 + 5; // 5-15 gold per customer  This may need tweaked to get it where it should be for the pay
	}
	brothel->m_Finance.arena_income(earned);
	ss.str("");
	ss << girlName << " drew in " << jobperformance << " people to watch her and you earned " << earned << " from it.";
	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);


	//gain traits
	g_Girls.PossiblyGainNewTrait(girl, "Tough", 65, actiontype, "She has become pretty Tough from all of the fights she's been in.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Fleet of Foot", 55, actiontype, "She is getting rather fast from all the fighting.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Aggressive", 70, actiontype, "She is getting rather Aggressive from her enjoyment of combat.", Day0Night1);
	if (g_Dice.percent(25) && g_Girls.GetStat(girl, STAT_STRENGTH) >= 65 && g_Girls.GetSkill(girl, SKILL_COMBAT) > g_Girls.GetSkill(girl, SKILL_MAGIC))
	{
		g_Girls.PossiblyGainNewTrait(girl, "Strong", 60, ACTION_COMBAT, girlName + " has become pretty Strong from all of the fights she's been in.", Day0Night1);
	}
	if (g_Dice.percent(25) && g_Girls.GetSkill(girl, SKILL_COMBAT) >= 60 && g_Girls.GetSkill(girl, SKILL_COMBAT) > g_Girls.GetSkill(girl, SKILL_MAGIC))
	{
		g_Girls.PossiblyGainNewTrait(girl, "Brawler", 60, ACTION_COMBAT, girlName + " has become pretty good at fighting.", Day0Night1);
	}
	//lose traits
	g_Girls.PossiblyLoseExistingTrait(girl, "Fragile", 35, actiontype, girlName + " has had to heal from so many injuries you can't say she is fragile anymore.", Day0Night1);
	return false;
}
Example #25
0
// `J` Job Clinic - Staff - Learning_Job
bool cJobManager::WorkIntern(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKTRAINING;
	stringstream ss; string girlName = girl->m_Realname;
	if (g_Girls.HasTrait(girl, "AIDS"))
	{
		ss << "Health laws prohibit anyone with AIDS from working in the Medical profession so " << girlName << " was sent to the waiting room.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_WARNING);
		girl->m_PrevDayJob = girl->m_PrevNightJob = girl->m_DayJob = girl->m_NightJob = JOB_CLINICREST;
		return false;
	}
	if (girl->m_Skills[SKILL_MEDICINE] + girl->m_Stats[STAT_INTELLIGENCE] + girl->m_Stats[STAT_CHARISMA] >= 300)
	{
		ss << "There is nothing more she can learn here so she is promoted to ";
		if (girl->is_slave())	{ ss << "Nurse.";	girl->m_DayJob = girl->m_NightJob = JOB_NURSE; }
		else /*            */	{ ss << "Doctor.";	girl->m_DayJob = girl->m_NightJob = JOB_DOCTOR; }
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_GOODNEWS);
		return false;	// not refusing
	}
	ss << girlName;
	if (g_Girls.DisobeyCheck(girl, actiontype, 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 << " trains in the Medical field.\n\n";

	g_Girls.UnequipCombat(girl);	// put that shit away
	
	int enjoy = 0;												// 
	int wages = 0;												// 
	int train = 0;												// main skill trained
	int tmed = girl->m_Skills[SKILL_MEDICINE];					// Starting level - train = 1
	int tint = girl->m_Stats[STAT_INTELLIGENCE];				// Starting level - train = 2
	int tcha = girl->m_Stats[STAT_CHARISMA];					// Starting level - train = 3
	bool gaintrait = false;										// posibility of gaining a trait
	bool promote = false;										// posibility of getting promoted to Doctor or Nurse
	int skill = 0;												// gian for main skill trained
	int dirtyloss = brothel->m_Filthiness / 100;				// training time wasted with bad equipment
	int sgMed = 0, sgInt = 0, sgCha = 0;						// gains per skill
	int roll_a = g_Dice.d100();									// roll for main skill gain
	int roll_b = g_Dice.d100();									// roll for main skill trained
	int roll_c = g_Dice.d100();									// roll for enjoyment





	/* */if (roll_a <= 5)	skill = 7;
	else if (roll_a <= 15)	skill = 6;
	else if (roll_a <= 30)	skill = 5;
	else if (roll_a <= 60)	skill = 4;
	else /*             */	skill = 3;
	/* */if (g_Girls.HasTrait(girl, "Quick Learner"))	{ skill += 1; }
	else if (g_Girls.HasTrait(girl, "Slow Learner"))	{ skill -= 1; }
	skill -= dirtyloss;
	ss << "The Clinic is ";
	if (dirtyloss <= 0) ss << "clean and tidy";
	if (dirtyloss == 1) ss << "dirty and the equipment has not been put back in its place";
	if (dirtyloss == 2) ss << "messy. The equipment is damaged and strewn about the building";
	if (dirtyloss == 3) ss << "filthy and some of the equipment is broken";
	if (dirtyloss >= 4) ss << "in complete disarray and the equipment barely usable";
	ss << ".\n\n";
	if (skill < 1) skill = 1;	// always at least 1 
	
	do{		// `J` New method of selecting what job to do
		/* */if (roll_b < 40  && tmed < 100)	train = 1;	// medicine
		else if (roll_b < 70  && tint < 100)	train = 2;	// intelligence
		else if (roll_b < 100 && tcha < 100)	train = 3;	// charisma
		roll_b -= 10;
	} while (train == 0 && roll_b > 0);
	if (train == 0 || g_Dice.percent(5)) gaintrait = true;
	if (train == 0 && girl->medicine() > 70 && girl->intelligence() > 70)	promote = true;
	
	if (train == 1) { sgMed = skill; ss << "She learns how to work with medicine better.\n"; }	else sgMed = g_Dice % 3;
	if (train == 2) { sgInt = skill; ss << "She got smarter today.\n"; }						else sgInt = g_Dice % 2;
	if (train == 3) { sgCha = skill; ss << "She got more charismatic today.\n"; }				else sgCha = g_Dice % 2;

	if (sgMed + sgInt + sgCha > 0)
	{
		ss << "She managed to gain:\n";
		if (sgMed > 0) { ss << sgMed << " Medicine.\n";		g_Girls.UpdateSkill(girl, SKILL_MEDICINE, sgMed); }
		if (sgInt > 0) { ss << sgInt << " Intelligence.\n";	g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, sgInt); }
		if (sgCha > 0) { ss << sgCha << " Charisma.\n";		g_Girls.UpdateStat(girl, STAT_CHARISMA, sgCha); }
	}

	int trycount = 10;
	while (gaintrait && trycount > 0)	// `J` Try to add a trait 
	{
		trycount--;
		switch (g_Dice % 10)
		{
		case 0:
			if (g_Girls.HasTrait(girl, "Nervous"))
			{
				g_Girls.RemoveTrait(girl, "Nervous");
				ss << "She seems to be getting over her Nervousness with her training.";
				gaintrait = false;
			}
			break;
		case 1:
			if (g_Girls.HasTrait(girl, "Meek"))
			{
				g_Girls.RemoveTrait(girl, "Meek");
				ss << "She seems to be getting over her Meakness with her training.";
				gaintrait = false;
			}
			break;
		case 2:
			if (g_Girls.HasTrait(girl, "Dependant"))
			{
				g_Girls.RemoveTrait(girl, "Dependant");
				ss << "She seems to be getting over her Dependancy with her training.";
				gaintrait = false;
			}
			break;
		case 3:
			if (!g_Girls.HasTrait(girl, "Charismatic"))
			{
				g_Girls.AddTrait(girl, "Charismatic");
				ss << "Dealing with patients and talking with them about their problems has made " << girlName << " more Charismatic.";
				gaintrait = false;
			}
			break;
		case 4:
			break;
		case 5:

			break;
		case 6:

			break;

		default:	break;	// no trait gained
		}
	}



	//enjoyed the work or not
	/* */if (roll_c <= 10)	{ enjoy -= g_Dice % 3 + 1;	ss << "Some of the patrons abused her during the shift."; }
	else if (roll_c >= 90)	{ enjoy += g_Dice % 3 + 1;	ss << "She had a pleasant time working."; }
	else /*             */	{ enjoy += g_Dice % 2;		ss << "Otherwise, the shift passed uneventfully."; }
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, Day0Night1);

	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket())) { wages = 0; }
	else { wages = 25 + (skill * 5); } // `J` Pay her more if she learns more
	girl->m_Pay = wages;

	// Improve stats
	int xp = 5 + skill, libido = int(1 + skill / 2);

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

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	if (girl->m_Skills[SKILL_MEDICINE] + girl->m_Stats[STAT_INTELLIGENCE] + girl->m_Stats[STAT_CHARISMA] >= 300) promote = true;
	if (promote)
	{
		ss.str("");
		ss << girlName << " has completed her Internship and has been promoted to ";
		if (girl->is_slave())	{ ss << "Nurse.";	girl->m_DayJob = girl->m_NightJob = JOB_NURSE; }
		else /*            */	{ ss << "Doctor.";	girl->m_DayJob = girl->m_NightJob = JOB_DOCTOR; }
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_GOODNEWS);
	}

	return false;
}
// `J` Job Arena - Fighting - Learning_Job - Combat_Job
bool cJobManager::WorkCombatTraining(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_COMBAT, actiontype2 = ACTION_WORKTRAINING;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	if (girl->m_Skills[SKILL_COMBAT] + girl->m_Skills[SKILL_MAGIC] + girl->m_Stats[STAT_AGILITY] +
		girl->m_Stats[STAT_CONSTITUTION] + girl->m_Stats[STAT_STRENGTH] >= 500)
	{
		ss << "There is nothing more she can learn here so she takes the rest of the day off.";
		girl->m_NightJob = girl->m_DayJob = JOB_ARENAREST;
		return false;	// not refusing
	}
	if (g_Girls.DisobeyCheck(girl, actiontype, 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 << " trains for combat.\n\n";

	g_Girls.EquipCombat(girl);	// Ready for combat training
	
	int enjoy = 0;												// 
	int wages = 0;												// 
	int train = 0;												// main skill trained
	int tcom = girl->m_Skills[SKILL_COMBAT];					// Starting level - train = 1
	int tmag = girl->m_Skills[SKILL_MAGIC];						// Starting level - train = 2
	int tagi = girl->m_Stats[STAT_AGILITY];						// Starting level - train = 3
	int tcon = girl->m_Stats[STAT_CONSTITUTION];				// Starting level - train = 4
	int tstr = girl->m_Stats[STAT_STRENGTH];					// Starting level - train = 5
	bool gaintrait = false;										// posibility of gaining a trait
	int skill = 0;												// gian for main skill trained
	int dirtyloss = brothel->m_Filthiness / 100;				// training time wasted with bad equipment
	int sgCmb = 0, sgMag = 0, sgAgi = 0, sgCns = 0, sgStr = 0;	// gains per skill
	int roll_a = g_Dice.d100();									// roll for main skill gain
	int roll_b = g_Dice.d100();									// roll for main skill trained
	int roll_c = g_Dice.d100();									// roll for enjoyment



	/* */if (roll_a <= 5)	skill = 7;
	else if (roll_a <= 15)	skill = 6;
	else if (roll_a <= 30)	skill = 5;
	else if (roll_a <= 60)	skill = 4;
	else /*             */	skill = 3;
	/* */if (g_Girls.HasTrait(girl, "Quick Learner"))	{ skill += 1; }
	else if (g_Girls.HasTrait(girl, "Slow Learner"))	{ skill -= 1; }
	skill -= dirtyloss;
	ss << "The Arena is ";
	if (dirtyloss <= 0) ss << "clean and tidy";
	if (dirtyloss == 1) ss << "dirty and the equipment has not been put back in its place";
	if (dirtyloss == 2) ss << "messy. The equipment is damaged and strewn about the building";
	if (dirtyloss == 3) ss << "filthy and some of the equipment is broken";
	if (dirtyloss >= 4) ss << "in complete disarray and the equipment barely usable";
	ss << ".\n\n";
	if (skill < 1) skill = 1;	// always at least 1 

	do{		// `J` New method of selecting what job to do
		/* */if (roll_b < 20  && tcom < 100)	train = 1;	// combat
		else if (roll_b < 40  && tmag < 100)	train = 2;	// magic
		else if (roll_b < 60  && tagi < 100)	train = 3;	// agility
		else if (roll_b < 80  && tcon < 100)	train = 4;	// constitution
		else if (roll_b < 100 && tstr < 100)	train = 5;	// strength
		roll_b -= 10;
	} while (train == 0 && roll_b > 0);
	if (train == 0 || g_Dice.percent(5)) gaintrait = true;

	if (train == 1) { sgCmb = skill; ss << "She trains in general combat techniques.\n"; }	else sgCmb = g_Dice % 2;
	if (train == 2) { sgMag = skill; ss << "She trains to control her magic.\n"; }			else sgMag = g_Dice % 2;
	if (train == 3) { sgAgi = skill; ss << "She trains her agility.\n"; }					else sgAgi = g_Dice % 2;
	if (train == 4) { sgCns = skill; ss << "She works on her constitution.\n"; }			else sgCns = g_Dice % 2;
	if (train == 5) { sgStr = skill; ss << "She lifts weights to get stronger.\n"; }		else sgStr = g_Dice % 2;

	if (sgCmb + sgMag + sgAgi + sgCns + sgStr > 0)
	{
		ss << "She managed to gain:\n";
		if (sgCmb > 0) { ss << sgCmb << " Combat\n";		g_Girls.UpdateSkill(girl, SKILL_COMBAT, sgCmb); }
		if (sgMag > 0) { ss << sgMag << " Magic\n";			g_Girls.UpdateSkill(girl, SKILL_MAGIC, sgMag); }
		if (sgAgi > 0) { ss << sgAgi << " Agility\n";		g_Girls.UpdateStat(girl, STAT_AGILITY, sgAgi); }
		if (sgCns > 0) { ss << sgCns << " Constitution\n";	g_Girls.UpdateStat(girl, STAT_CONSTITUTION, sgCns); }
		if (sgStr > 0) { ss << sgStr << " Strength\n";		g_Girls.UpdateStat(girl, STAT_STRENGTH, sgStr); }
	}

	int trycount = 20;
	while (gaintrait && trycount > 0)	// `J` Try to add a trait 
	{
		trycount--;
		switch (g_Dice % 10)
		{
		case 0:
			if (g_Girls.HasTrait(girl, "Fragile"))
			{
				g_Girls.RemoveTrait(girl, "Fragile");
				ss << "She has had to heal from so many injuries you can't say she is fragile anymore.";
				gaintrait = false;
			}
			else if (!g_Girls.HasTrait(girl, "Tough"))
			{
				g_Girls.AddTrait(girl, "Tough");
				ss << "She has become pretty Tough from her training.";
				gaintrait = false;
			}
			break;
		case 1:
			if (!g_Girls.HasTrait(girl, "Adventurer"))
			{
				g_Girls.AddTrait(girl, "Adventurer");
				ss << "She has been in enough tough spots to consider herself an Adventurer.";
				gaintrait = false;
			}
			break;
		case 2:
			if (g_Girls.HasTrait(girl, "Nervous") || g_Girls.HasTrait(girl, "Meek") || g_Girls.HasTrait(girl, "Dependant"))
			{
				if (g_Dice.percent(50) && g_Girls.HasTrait(girl, "Nervous"))
				{
					g_Girls.RemoveTrait(girl, "Nervous");
					ss << "She seems to be getting over her Nervousness with her training.";
					gaintrait = false;
				}
				else if (g_Dice.percent(50) && g_Girls.HasTrait(girl, "Meek"))
				{
					g_Girls.RemoveTrait(girl, "Meek");
					ss << "She seems to be getting over her Meakness with her training.";
					gaintrait = false;
				}
				else if (g_Dice.percent(50) && g_Girls.HasTrait(girl, "Dependant"))
				{
					g_Girls.RemoveTrait(girl, "Dependant");
					ss << "She seems to be getting over her Dependancy with her training.";
					gaintrait = false;
				}
			}
			else
			{
				if (g_Dice.percent(50) && !g_Girls.HasTrait(girl, "Aggressive"))
				{
					g_Girls.AddTrait(girl, "Aggressive");
					ss << "She is getting rather Aggressive from her enjoyment of combat.";
					gaintrait = false;
				}
				else if (g_Dice.percent(50) && !g_Girls.HasTrait(girl, "Fearless"))
				{
					g_Girls.AddTrait(girl, "Fearless");
					ss << "She is getting rather Fearless from her enjoyment of combat.";
					gaintrait = false;
				}
				else if (g_Dice.percent(50) && !g_Girls.HasTrait(girl, "Audacity"))
				{
					g_Girls.AddTrait(girl, "Audacity");
					ss << "She is getting rather Audacious from her enjoyment of combat.";
					gaintrait = false;
				}
			}
			break;
		case 3:
			if (!g_Girls.HasTrait(girl, "Strong"))
			{
				g_Girls.AddTrait(girl, "Strong");
				ss << "She is getting rather Strong from handling heavy weapons and armor.";
				gaintrait = false;
			}
			break;
		case 4:
			break;
		case 5:

			break;
		case 6:

			break;

		default:	break;	// no trait gained
		}
	}


		/*

		Small Scars
		Cool Scars
		Horrific Scars
		Bruises
		Idol
		Agile
		Fleet of Foot
		Clumsy
		Strong
		Merciless
		Delicate
		Brawler
		Assassin
		M*******t
		Sadistic
		Tsundere
		Twisted
		Yandere


		Missing Nipple

		Muggle
		Weak Magic
		Strong Magic
		Powerful Magic

		Broken Will
		Iron Will

		Eye Patch
		One Eye

		Shy
		Missing Teeth


		No Arms
		One Arm
		No Hands
		One Hand
		Missing Finger
		Missing Fingers

		No Feet
		No Legs
		One Foot
		One Leg
		Missing Toe
		Missing Toes


		Muscular
		Plump
		Great Figure



		*/



	//enjoyed the work or not
	/* */if (roll_c <= 10)	{ enjoy -= g_Dice % 3 + 1;	ss << "She did not enjoy her time training."; }
	else if (roll_c >= 90)	{ enjoy += g_Dice % 3 + 1;	ss << "She had a pleasant time training."; }
	else /*             */	{ enjoy += g_Dice % 2;		ss << "Otherwise, the shift passed uneventfully."; }
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);
	g_Girls.UpdateEnjoyment(girl, actiontype2, enjoy);

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_COMBAT, Day0Night1);
	brothel->m_Filthiness += 2;	// fighting is dirty
	if ((girl->is_slave() && !cfg.initial.slave_pay_outofpocket())) { wages = 0; }
	else { wages = 25 + (skill * 5); } // `J` Pay her more if she learns more
	girl->m_Pay = wages;

	// Improve stats
	int xp = 5 + skill, libido = int(1 + skill / 2);

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

	g_Girls.UpdateStat(girl, STAT_EXP, (g_Dice % xp) + 1);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	return false;
}
// `J` Job Centre - Anger Management
bool cJobManager::WorkCentreAngerManagement(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	int actiontype = ACTION_WORKTHERAPY;
	// if she was not in thearpy yesterday, reset working days to 0 before proceding
	if (girl->m_YesterDayJob != JOB_ANGER) { girl->m_WorkingDay = girl->m_PrevWorkingDay = 0; }
	girl->m_DayJob = girl->m_NightJob = JOB_ANGER;	// it is a full time job

	if (!g_Girls.HasTrait(girl, "Aggressive") &&		// if the girl doesnt need this
		!g_Girls.HasTrait(girl, "Tsundere") &&
		!g_Girls.HasTrait(girl, "Yandere"))
	{
		ss << " doesn't need anger management so she was sent to the waiting room.";
		if (Day0Night1 == 0)	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_WARNING);
		girl->m_YesterDayJob = girl->m_YesterNightJob = girl->m_DayJob = girl->m_NightJob = JOB_CENTREREST;
		girl->m_PrevWorkingDay = girl->m_WorkingDay = 0;
		return false; // not refusing
	}
	if (g_Centre.GetNumGirlsOnJob(brothel->m_id, JOB_COUNSELOR, true) < 1 || g_Centre.GetNumGirlsOnJob(brothel->m_id, JOB_COUNSELOR, false) < 1)
	{
		ss << " has no counselor to help her on the " << (Day0Night1 ? "night" : "day") << " Shift.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_WARNING);
		return false;	// not refusing
	}
	if (g_Dice.percent(20) || g_Girls.DisobeyCheck(girl, actiontype, brothel))	// `J` - yes, OR, not and.
	{
		g_Girls.UpdateEnjoyment(girl, actiontype, -1);
		if (Day0Night1) girl->m_WorkingDay--;
		if (g_Dice.percent(10))
		{
			g_Girls.UpdateEnjoyment(girl, actiontype, -5);
			bool runaway = false;
			// if there is no counselor, it should not get to here
			sGirl* counselor = g_Centre.GetRandomGirlOnJob(0, JOB_COUNSELOR, Day0Night1);	
			ss << "\n\n" << girlName << " fought hard with her counselor " << counselor->m_Realname;
			int winner = g_Girls.girl_fights_girl(girl, counselor);
			if (winner == 1)	// the patient won
			{
				ss << " and won.\n\n";
				g_Girls.UpdateEnjoyment(girl, ACTION_COMBAT, 5);
				g_Girls.UpdateEnjoyment(counselor, ACTION_WORKCOUNSELOR, -5);
				g_Girls.UpdateEnjoyment(counselor, ACTION_COMBAT, -2);

				if (g_Dice.percent(10))	// and ran away
				{
					runaway = true;
					stringstream smess;
					smess << girlName << " fought with her counselor and ran away.\nSend your goons after her to attempt recapture.\nShe will escape for good after 6 weeks.\n";
					g_MessageQue.AddToQue(smess.str(), COLOR_RED);

					g_Centre.RemoveGirl(0, girl, false);
					girl->m_RunAway = 6;
					girl->m_NightJob = girl->m_DayJob = JOB_RUNAWAY;
					g_Brothels.AddGirlToRunaways(girl);
					return true;
				}
			}
			else	// the counselor won
			{
				ss << " and lost.\n\n";
				g_Girls.UpdateEnjoyment(girl, actiontype, -5);
				g_Girls.UpdateEnjoyment(girl, ACTION_COMBAT, -5);
				g_Girls.UpdateEnjoyment(counselor, ACTION_WORKCOUNSELOR, -1);
				g_Girls.UpdateEnjoyment(counselor, ACTION_COMBAT, 2);
			}
			stringstream ssc;
			ssc << counselor->m_Realname << " had to defend herself from " << girlName << " who she was counceling.\n";
			if (runaway) ss << girlName << " ran out of the Counceling Centre and has not been heard from since.";
			counselor->m_Events.AddMessage(ssc.str(), IMGTYPE_COMBAT, EVENT_WARNING);
		}
		else
		{
			ss << "She fought with her counselor and did not make any progress this week.";
		}
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " underwent therapy for mental issues.\n\n";

	g_Girls.UnequipCombat(girl);	// not for patient

	int enjoy = 0;
	int msgtype = Day0Night1;
	if (!Day0Night1) girl->m_WorkingDay++;

	g_Girls.UpdateStat(girl, STAT_HAPPINESS, g_Dice % 30 - 20);
	g_Girls.UpdateStat(girl, STAT_SPIRIT, g_Dice % 5 - 10);
	g_Girls.UpdateStat(girl, STAT_MANA, g_Dice % 5 - 10);

	// `J` % chance a counselor will save her if she almost dies
	int healthmod = (g_Dice % 15) - 11;
	if (girl->health() + healthmod < 1 && g_Dice.percent(95 + (girl->health() + healthmod)) &&
		(g_Centre.GetNumGirlsOnJob(brothel->m_id, JOB_COUNSELOR, true) > 0 || g_Centre.GetNumGirlsOnJob(brothel->m_id, JOB_COUNSELOR, false) > 0))
	{	// Don't kill the girl from therapy if a Counselor is on duty
		g_Girls.SetStat(girl, STAT_HEALTH, 1);
		g_Girls.UpdateStat(girl, STAT_PCFEAR, 5);
		g_Girls.UpdateStat(girl, STAT_PCLOVE, -10);
		g_Girls.UpdateStat(girl, STAT_PCHATE, 10);
		ss << "She almost died in rehab but the Counselor saved her.\n";
		ss << "She hates you a little more for forcing this on her.\n\n";
		msgtype = EVENT_DANGER;
		enjoy -= 2;
	}
	else
	{
		g_Girls.UpdateStat(girl, STAT_HEALTH, healthmod);
		enjoy += (healthmod / 5) + 1;
	}

	if (girl->health() < 1)
	{
		ss << "She died in anger management.";
		msgtype = EVENT_DANGER;
	}

	if (girl->m_WorkingDay >= 3 && Day0Night1)
	{
		enjoy += g_Dice % 10;
		g_Girls.UpdateEnjoyment(girl, ACTION_WORKCOUNSELOR, g_Dice % 6 - 2);	// `J` She may want to help others with their problems
		g_Girls.UpdateStat(girl, STAT_HAPPINESS, g_Dice % 10);
		
		ss << "The therapy is a success.\n";
		msgtype = EVENT_GOODNEWS;
		if (g_Girls.HasTrait(girl, "Aggressive"))
		{
			g_Girls.RemoveTrait(girl, "Aggressive");
			ss << "She is no longer Aggressive.\n";
		}
		else if (g_Girls.HasTrait(girl, "Tsundere"))
		{
			g_Girls.RemoveTrait(girl, "Tsundere");
			ss << "She is no longer a Tsundere.\n";
		}
		else if (g_Girls.HasTrait(girl, "Yandere"))
		{
			g_Girls.RemoveTrait(girl, "Yandere");
			ss << "She is no longer a Yandere.\n";
		}

		girl->m_PrevWorkingDay = girl->m_WorkingDay = 0;

		if (g_Girls.HasTrait(girl, "Aggressive") || g_Girls.HasTrait(girl, "Tsundere") || g_Girls.HasTrait(girl, "Yandere"))
		{
			ss << "\nShe should stay in anger management to treat her other anger issues.";
		}
		else // get out of therapy
		{
			ss << "\nShe has been released from therapy.";
			girl->m_YesterDayJob = girl->m_YesterNightJob = girl->m_DayJob = girl->m_NightJob = JOB_CENTREREST;
			girl->m_PrevWorkingDay = girl->m_WorkingDay = 0;
			girl->m_PrevDayJob = girl->m_PrevNightJob = 255;
		}
	}
	else
	{
		ss << "The therapy is in progress (" << (3 - girl->m_WorkingDay) << " day remaining).";
	}

	// Improve girl
	int libido = 1;

	if (g_Girls.HasTrait(girl, "Nymphomaniac"))			{ libido += 2; }

	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);
	girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, msgtype);
	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	return false;
}
Example #28
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
}
// `J` Job Brothel - Brothel
bool cJobManager::WorkWhore(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_SEX;
	// put that shit away, you'll scare off the customers!
	g_Girls.UnequipCombat(girl);


	/*
	*	WD:	Modified to fix customer service problems.. I hope :)
	*
	*	Change logic as original code is based on linked list of customers
	*	not random generation for each call to GetCustomer()
	*
	*	Pricing issues seem to be resolved with getting lots of money
	*	from customer that cant pay
	*
	*	The numbers I have added need to be tested
	*
	*	Limit number customers a girl can f**k to 10 max
	*
	*	Limit the number of customers a girl can see if they will
	*	f**k her from 5 to Max Customers * 2
	*
	*	Redid the code for deadbeat customers
	*
	*	% Chance of customers without any money getting service is
	*  percent(50 - INTELLIGENCE) / 5) where  20 < INTELLIGENCE < 100
	*	If caught will set deadbeat flag
	*
	*	GetCustomer() is generating a lot of poor customers changed
	*	code to add pay to customers funds instead of generating
	*	New customer.
	*
	*	% Chance of customer refusing to pay despite having funds is
	*	percent((40 - HAPPINESS) / 2) && percent(CONFIDENCE - 25)
	*	If caught by guards they will pay
	*
	*	Only decrement filthiness when service is performed in brothel
	*
	*	Street Work will not decrement number customers
	*  Street work will only service 66% number of customers
	*	Street Work will only generate 66% of brothel income
	*	Street Work Really needs its own NumCustomers() counter
	*
	*	Rival gangs can damage girls doing Street Work
	*  % Chance of destroying rival gang is depended on best of
	*	SKILL_COMBAT & SKILL_MAGIC / 5
	*
	*	Changed message for rival gangs attacking street girls to give
	*	EVENT_WARNING
	*
	*	GROUP sex code caculations now consolidated to one place
	*
	*  Fixed end of shift messages
	*
	*	Fame only to be done in GirlFucks()
	*
	*	Now Base Customer HAPPINESS = 60, code conslidated from 2 places in file
	*
	*/

	string fuckMessage = "";
	string message = "";
	string girlName = girl->m_Realname;
	int iNum = 0;
	int iOriginal = 0;
	int	AskPrice = g_Girls.GetStat(girl, STAT_ASKPRICE);
	int pay;
	int tip;
	int LoopCount;
	bool group = false;	// Group sex flag
	bool bCustCanPay;				// Customer has enough money to pay 
	bool acceptsGirl;				// Customer will sleep girl
	bool bStreetWork;				// Girl Doing StreetWork

	u_int SexType = 0;
	u_int job = (Day0Night1 ? girl->m_NightJob : girl->m_DayJob);
	bStreetWork = (job == JOB_WHORESTREETS);
	stringstream ss;

	girl->m_Pay = 0;

	// work out how many customers the girl can service

	// Changed the number of custmers stats add.. reasone was that old value, 
	// it was only adding 1 customer per stat, unless stat was 100 for beauty and Charisma. Fame would add a max of 3. and only if was = 10
	// there would be NO point in doing this, if it defaults to NumCusts++ since it is basically the same effect.	-PP

	// Max number on customers the girl can f**k
	int b = g_Girls.GetStat(girl, STAT_BEAUTY), c = g_Girls.GetStat(girl, STAT_CHARISMA), f = g_Girls.GetStat(girl, STAT_FAME);
	int NumCusts = min(10, 3 + ((b + 1) / 50) + ((c + 1) / 50) + ((f + 1) / 25));

	int NumSleptWith = 0;		// Total num customers she f***s this session

	if (bStreetWork)
	{
		NumCusts = NumCusts * 2 / 3;
		AskPrice = AskPrice * 2 / 3;
	}

	NumCusts = min(NumCusts, 10);		// No more than 10 Customers per shift

	// Complications

	/*
	*	WD:	Rival Gang is incompleate
	*
	*	Chance of defeating gane is based on  combat / magic skill
	*	Added Damage and Tiredness
	*	ToDo Girl fightrivalgang() if its implemented
	*
	*/

	if (bStreetWork && g_Dice.percent(5))
	{
		cRival* rival = g_Brothels.GetRivalManager()->GetRandomRival();
		if (rival)
		{
			if (rival->m_NumGangs > 0)
			{
				ss.str("");
				summary += girlName + " was attacked by enemy goons. \n";
				//message		+= "She ran into some enemy goons and was attacked.\n";
				ss << girlName << " ran into some enemy goons and was attacked.\n";

				// WD: Health loss, Damage 0-15, 25% chance of 0 damage
				iNum = max(g_Dice % 20 - 5, 0);
				iOriginal = g_Girls.GetStat(girl, STAT_HEALTH);
				g_Girls.UpdateStat(girl, STAT_HEALTH, -iNum);
				iNum = iOriginal - g_Girls.GetStat(girl, STAT_HEALTH);

				if (iNum > 0)
				{
					//message += "She fought back and was hurt.\n";	
					ss << "She fought back and was hurt taking " << iNum << " points of damage.\n";
				}
				else
					ss << "She fought back taking no damage.\n";

				// WD:	Tiredness (5 + 2 * damage) points avg is (6 + Health Damage) is bell curve
				iNum = g_Dice % (iNum)+g_Dice % (iNum)+5;
				g_Girls.UpdateStat(girl, STAT_TIREDNESS, iNum);
				message = ss.str();

				// WD:	If girl used magic to defend herself she will use mana
				if (g_Girls.GetStat(girl, STAT_MANA)  > 20 && g_Girls.GetSkill(girl, SKILL_MAGIC) > g_Girls.GetSkill(girl, SKILL_COMBAT))
				{
					g_Girls.UpdateStat(girl, STAT_MANA, -20);
					iNum = g_Girls.GetSkill(girl, SKILL_MAGIC) / 5;		// WD: Chance to destroy rival gang
				}
				else
					iNum = g_Girls.GetSkill(girl, SKILL_COMBAT) / 5;	// WD: Chance to destroy rival gang

				// WD:	Destroy rival gang
				if (g_Dice.percent(iNum))
					rival->m_NumGangs--;


				girl->m_Events.AddMessage(message, IMGTYPE_PROFILE, EVENT_WARNING);
				// WD TRACE Enemy Goons {girl->m_Name} dmg= {iNum} msg= {message}
			}
		}
	}



	// WD: Set the limits on the Number of customers a girl can try and f**k
	LoopCount = max(NumCusts * 2, 5);

	// WD: limit to number of customers left
	if (!bStreetWork && LoopCount >g_Customers.GetNumCustomers())
		LoopCount = g_Customers.GetNumCustomers();

#if 0 
	// `J` - set to 1 to debug "CustNoPay.script"
	SetGameFlag(FLAG_CUSTNOPAY);
#endif

	for (int i = 0; i < LoopCount; i++)	// Go through all customers
	{
		// WD:	Move exit test to top of loop
		// if she has already slept with the max she can attact then stop processing her f*****g routine
		if (NumSleptWith >= NumCusts) break;

		// WD:	Init Loop variables
		pay = AskPrice;
		SexType = 0;
		group = false;
		acceptsGirl = false;
		// WD:	Create Customer
		sCustomer Cust;
		g_Customers.GetCustomer(Cust, brothel);

		// `J` check for disease
		if (g_Girls.detect_disease_in_customer(brothel, girl, Cust)) continue;

		// filter out unwanted sex types (unless it is street work)
		if (!bStreetWork && !is_sex_type_allowed(Cust.m_SexPref, brothel) && !is_sex_type_allowed(Cust.m_SexPrefB, brothel))
		{
			brothel->m_RejectCustomers++;
			continue;	// `J` if both their sexprefs are banned then they leave
		}
		else if (!bStreetWork && !is_sex_type_allowed(Cust.m_SexPref, brothel)) // it their first sexpref is banned then switch to the second
		{
			Cust.m_SexPref = Cust.m_SexPrefB;
			Cust.m_Stats[STAT_HAPPINESS] = 32 + g_Dice % 9 + g_Dice % 9;	// `J` and they are less happy
		}
		else	// `J` otherwise they are happy with their first choice.
		{
			// WD:	Set the customers begining happiness/satisfaction
			Cust.m_Stats[STAT_HAPPINESS] = 42 + g_Dice % 10 + g_Dice % 10; // WD: average 51 range 42 to 60
		}

		// WD:	Consolidate GROUP Sex Calcs here
		//		adjust price by number of parcitipants
		if (Cust.m_Amount > 1)
		{
			group = true;
			pay *= (int)Cust.m_Amount;
			if (Cust.m_SexPref == SKILL_GROUP) pay = pay * 17 / 10;
			if (Cust.m_SexPref == SKILL_STRIP) pay = pay * 14 / 10;
			// WD: this is complicated total for 1.7 * pay * num of customers
			// pay += (int)((float)(pay*(Cust.m_Amount))*0.7f); 
		}

		// WD: Has the customer have enough money
		bCustCanPay = Cust.m_Money >= (unsigned)pay;

		// WD:	TRACE Customer Money = {Cust.m_Money}, Pay = {pay}, Can Pay = {bCustCanPay}

		// WD:	If the customer doesn't have enough money, he will only sleep with her if he is stupid
		if (!bCustCanPay && !g_Dice.percent((50 - Cust.m_Stats[STAT_INTELLIGENCE]) / 5))
		{
			//continue;
			// WD: Hack to avoid many newcustomer() calls
			Cust.m_Money += (unsigned)pay;
			bCustCanPay = true;
		}

		// test for specific girls
		if (girl->has_trait("Skeleton"))
		{
			fuckMessage = "The customer sees that you are offering up a Skeleton for sex and is scared, if you allow that kind of thing in your brothels, what else do you allow? They left in a hurry, afraid of what might happen if they stay.\n\n";
			brothel->m_Fame -= 5;
			g_Brothels.GetPlayer()->customerfear(2);
			acceptsGirl = false;
			continue;
		}
		if (Cust.m_Fetish == FETISH_SPECIFICGIRL)
		{
			if (Cust.m_ParticularGirl == g_Brothels.GetGirlPos(brothel->m_id, girl))
			{
				fuckMessage = "This is the customer's favorite girl.\n\n";
				acceptsGirl = true;
			}
		}
		else if (girl->has_trait("Zombie") && Cust.m_Fetish == FETISH_FREAKYGIRLS && g_Dice.percent(10))
		{
			fuckMessage = "This customer is intrigued to f**k a Zombie girl.\n\n";
			acceptsGirl = true;
		}
		else
		{
			// 50% chance of getting something a little weirder during the night
			if (Day0Night1 && Cust.m_Fetish < NUM_FETISH - 2 && g_Dice.percent(50)) Cust.m_Fetish += 2;

			// Check for fetish match
			if (g_Girls.CheckGirlType(girl, Cust.m_Fetish))
			{
				fuckMessage = "The customer loves this type of girl.\n\n";
				acceptsGirl = true;
			}
		}

		// Other ways the customer will accept the girl
		if (acceptsGirl == false)
		{
			if (girl->has_trait("Zombie"))
			{
				fuckMessage = "The customer sees that you are offering up a Zombie girl and is scared, if you allow that kind of thing in your brothels, what else do you allow? They left in a hurry, afraid of what might happen if they stay.\n\n";
				brothel->m_Fame -= 10;
				g_Brothels.GetPlayer()->customerfear(5);
				acceptsGirl = false;
			}
			else if (Cust.m_Stats[STAT_LIBIDO] >= 80)
			{
				fuckMessage = "Customer chooses her because they are very horny.\n\n";
				acceptsGirl = true;
			}
			else if (((g_Girls.GetStat(girl, STAT_BEAUTY) + g_Girls.GetStat(girl, STAT_CHARISMA)) / 2) >= 90)	// if she is drop dead gorgeous
			{
				fuckMessage = "Customer chooses her because they are stunned by her beauty.\n\n";
				acceptsGirl = true;
			}
			else if (g_Girls.GetStat(girl, STAT_FAME) >= 80)	// if she is really famous
			{
				fuckMessage = "Customer chooses her because she is so famous.\n\n";
				acceptsGirl = true;
			}
			// WD:	Use Magic only as last resort
			else if (g_Girls.GetSkill(girl, SKILL_MAGIC) > 50 && g_Girls.GetStat(girl, STAT_MANA) >= 20)	// she can use magic to get him
			{
				fuckMessage = girlName + " uses magic to get the customer to choose her.\n\n";
				g_Girls.UpdateStat(girl, STAT_MANA, -20);
				acceptsGirl = true;
			}
		}

		if (!acceptsGirl) continue;		// will the customer sleep with her?

		// Horizontal boogy
		g_Girls.GirlFucks(girl, Day0Night1, &Cust, group, fuckMessage, SexType);
		NumSleptWith++;
		if (!bStreetWork) brothel->m_Filthiness++;

		// update how happy the customers are on average
		brothel->m_Happiness += Cust.m_Stats[STAT_HAPPINESS];


		// Time for the customer to fork over some cash

		// WD:	Customer can not pay
		if (!bCustCanPay)
		{
			pay = 0;	// WD: maybe no money from this customer
			if (g_Dice.percent(Cust.m_Stats[STAT_CONFIDENCE] - 25))	// Runner
			{
				if (g_Gangs.GetGangOnMission(MISS_GUARDING))
				{
					if (g_Dice.percent(50))
						fuckMessage += " The customer couldn't pay and managed to elude your guards.";

					else
					{
						fuckMessage += " The customer couldn't pay and tried to run off. Your men caught him before he got out the door.";
						SetGameFlag(FLAG_CUSTNOPAY);
						pay = (int)Cust.m_Money;	// WD: Take what customer has
						Cust.m_Money = 0;	// WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???
					}
				}
				else
					fuckMessage += " The customer couldn't pay and ran off. There were no guards!";

			}
			else
			{
				// offers to pay the girl what he has
				if (g_Dice.percent(g_Girls.GetStat(girl, STAT_INTELLIGENCE)))
				{
					// she turns him over to the goons
					fuckMessage += " The customer couldn't pay the full amount, so your girl turned them over to your men.";
					SetGameFlag(FLAG_CUSTNOPAY);
				}
				else
					fuckMessage += " The customer couldn't pay the full amount.";

				pay = (int)Cust.m_Money;
				Cust.m_Money = 0;	// WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???
			}
		}


		// WD:	Unhappy Customer tries not to pay and does a runner
		else if (g_Dice.percent((40 - Cust.m_Stats[STAT_HAPPINESS]) / 2) && g_Dice.percent(Cust.m_Stats[STAT_CONFIDENCE] - 25))
		{
			if (g_Gangs.GetGangOnMission(MISS_GUARDING))
			{
				if (g_Dice.percent(50))
				{
					fuckMessage += " The customer refused to pay and managed to elude your guards.";
					pay = 0;
				}
				else
				{
					fuckMessage += " The customer refused to pay and tried to run off. Your men caught him before he got out the door and forced him to pay.";
					Cust.m_Money -= (unsigned)pay; // WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???
				}
			}
			else
			{
				fuckMessage += " The customer refused to pay and ran off. There were no guards!";
				pay = 0;
			}
		}

		else  // Customer has enough money
		{
			Cust.m_Money -= (unsigned)pay; // WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???
			if (g_Girls.HasTrait(girl, "Your Daughter") && Cust.m_Money >= 20 && g_Dice.percent(15))//may need to be moved to work right
			{
				if (g_Dice.percent(50))
				{
					message += "Learning that she was your daughter the customer tosses some extra gold down saying no dad should do this to their daughter.\n";
				}
				else
				{
					message += "A smile crossed the customer's face upon learning that " + girlName + " is your daughter and they threw some extra gold down. They seem to enjoy the thought of f*****g the boss's daughter.\n";
				}
				Cust.m_Money -= 20;
				girl->m_Tips += 20;
			}

			// if he is happy and has some extra gold he will give a tip
			if ((int)Cust.m_Money >= 20 && Cust.m_Stats[STAT_HAPPINESS] > 90)
			{
				tip = (int)Cust.m_Money;
				if (tip > 20)
				{
					Cust.m_Money -= 20;	// WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???
					tip = 20;
				}
				else
					Cust.m_Money = 0;	// WD: ??? not needed Cust record is not saved when this fn ends!  Leave for now just in case ???

				fuckMessage += ("\nShe received a tip of " + intstring(tip) + " gold");

				girl->m_Tips += tip;

				fuckMessage += ".";

				// If the customer is a government official
				if (Cust.m_Official == 1)
				{
					g_Brothels.GetPlayer()->suspicion(-5);
					fuckMessage += " It turns out that the customer was a government official, which lowers your suspicion.";
				}
			}
		}


		// Match image type to the deed done
		int imageType = IMGTYPE_SEX;
		/* */if (SexType == SKILL_ANAL)			imageType = IMGTYPE_ANAL;
		else if (SexType == SKILL_BDSM)			imageType = IMGTYPE_BDSM;
		else if (SexType == SKILL_NORMALSEX)	imageType = IMGTYPE_SEX;
		else if (SexType == SKILL_BEASTIALITY)	imageType = IMGTYPE_BEAST;
		else if (SexType == SKILL_GROUP)		imageType = IMGTYPE_GROUP;
		else if (SexType == SKILL_LESBIAN)		imageType = IMGTYPE_LESBIAN;
		else if (SexType == SKILL_ORALSEX)		imageType = IMGTYPE_ORAL;
		else if (SexType == SKILL_TITTYSEX)		imageType = IMGTYPE_TITTY;
		else if (SexType == SKILL_HANDJOB)		imageType = IMGTYPE_HAND;
		else if (SexType == SKILL_FOOTJOB)		imageType = IMGTYPE_FOOT;
		else if (SexType == SKILL_STRIP)		imageType = IMGTYPE_STRIP;

		// chance of customer beating or attempting to beat girl
		if (work_related_violence(girl, Day0Night1, bStreetWork))
			pay = 0;		// WD TRACE WorkRelatedViloence {girl->m_Name} earns nothing

		// WD:	Save gold earned
		girl->m_Pay += pay;		// WD TRACE Save Pay {girl->m_Name} earns {pay} totaling {girl->m_Pay}
		girl->m_Events.AddMessage(fuckMessage, imageType, Day0Night1);
	}


	// WD:	Reduce number of availabe customers for next w***e
	if (!bStreetWork)								// WD:	only brothel workers
	{
		iNum = g_Customers.GetNumCustomers();		// WD: Should not happen but lets make sure
		if (iNum < NumSleptWith)	g_Customers.AdjustNumCustomers(-iNum);
		else						g_Customers.AdjustNumCustomers(-NumSleptWith);
	}
	else brothel->m_MiscCustomers += NumSleptWith;	// WD:	 Count number of customers from Street Work

	// WD:	End of shift messages
	// doc: adding braces - gcc warns of ambiguous if nesting
	if (!bStreetWork)
	{
		if (g_Customers.GetNumCustomers() == 0)	{ girl->m_Events.AddMessage("No more customers.", IMGTYPE_PROFILE, Day0Night1); }
		else if (NumSleptWith < NumCusts)		{ girl->m_Events.AddMessage(girlName + " ran out of customers who like her.", IMGTYPE_PROFILE, Day0Night1); }
	}

	// WD:	Summary messages
	ss.str("");
	ss << girlName << (bStreetWork ? " worked the streets and" : "") << " saw " << NumSleptWith << " customers this shift.";
	summary += ss.str();

	girl->m_Events.AddMessage(summary, IMGTYPE_PROFILE, Day0Night1);

	//gain
	g_Girls.PossiblyGainNewTrait(girl, "Good Kisser", 50, actiontype, girlName + " has had a lot of practice kissing and as such as become a Good Kisser.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Nymphomaniac", 70, actiontype, girlName + " has been having so much sex she is now wanting sex all the time.", Day0Night1);

	//SIN: use a few of the new traits
	if (g_Dice.percent(1) && g_Dice.percent(girl->oralsex()) && (g_Girls.HasTrait(girl, "Nymphomaniac")))
		g_Girls.PossiblyGainNewTrait(girl, "Cum Addict", 90, actiontype, girlName + " has tasted so much cum she now craves it at all times.", Day0Night1);

	if (g_Dice.percent(min(50, girl->oralsex() - 30)))
		g_Girls.AdjustTraitGroupGagReflex(girl, +1, true, Day0Night1);

	return false;
}
Example #30
0
// `J` Job Clinic - Staff
bool cJobManager::WorkMechanic(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKMECHANIC;
	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, actiontype, 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 as a mechanic.\n\n";

	
	g_Girls.UnequipCombat(girl);	// put that shit away, you'll scare off the customers!
	double wages = 25, tips = 0;
	int enjoy = 0, fame = 0;
	int imagetype = IMGTYPE_PROFILE;
	int msgtype = Day0Night1;

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

	double jobperformance = JP_Mechanic(girl, false);


	if (jobperformance >= 245)
	{
		wages += 155;
		ss << "She must be the perfect mechanic patients go on and on about her and always come to see her when she works.\n\n";
	}
	else if (jobperformance >= 185)
	{
		wages += 95;
		ss << "She's unbelievable at this and is always getting praised by the patients for her work.\n\n";
	}
	else if (jobperformance >= 135)
	{
		wages += 55;
		ss << "She's good at this job and gets praised by the patients often.\n\n";
	}
	else if (jobperformance >= 85)
	{
		wages += 15;
		ss << "She made a few mistakes but overall she is okay at this.\n\n";
	}
	else if (jobperformance >= 65)
	{
		wages -= 5;
		ss << "She was nervous and made a few mistakes. She isn't that good at this.\n\n";
	}
	else
	{
		wages -= 15;
		ss << "She was nervous and constantly making mistakes. She really isn't very good at this job.\n\n";
	}


	//try and add randomness here
	if (g_Girls.GetStat(girl, STAT_BEAUTY) > 85 && g_Dice.percent(20))
	{
		wages += 25;
		ss << " Stunned by her beauty a patient left her a great tip.\n\n";
	}
	if (g_Girls.HasTrait(girl, "Construct") && g_Dice.percent(15))
	{
		wages += 15;
		ss << " Seeing a kindred spirit, the mechanical patient left her a great tip.\n";
	}
	if (g_Girls.HasTrait(girl, "Half-Construct") && g_Dice.percent(15))
	{
		wages += 15;
		ss << " Seeing a kindred spirit, the mechanical patient left her a great tip.\n";
	}
	if (g_Girls.HasTrait(girl, "Clumsy") && g_Dice.percent(15))
	{
		wages -= 15;
		ss << " Her clumsy nature caused her to drop parts everywhere.\n";
	}
	if (g_Girls.HasTrait(girl, "Pessimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			wages -= 10;
			ss << " Her pessimistic mood depressed the patients making them tip less.\n";
		}
		else
		{
			wages += 10;
			ss << girlName << " was in a poor mood so the patients gave her a bigger tip to try and cheer her up.\n";
		}
	}
	if (g_Girls.HasTrait(girl, "Optimist") && g_Dice.percent(5))
	{
		if (jobperformance < 125)
		{
			wages -= 10;
			ss << girlName << " was in a cheerful mood but the patients thought she needed to work more on her services.\n";
		}
		else
		{
			wages += 10;
			ss << " Her optimistic mood made patients cheer up increasing the amount they tip.\n";
		}
	}


#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;
	}


#pragma endregion
#pragma region	//	Money					//


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


	girl->m_Events.AddMessage(ss.str(), imagetype, Day0Night1);
	int roll_max = (g_Girls.GetStat(girl, STAT_INTELLIGENCE) + g_Girls.GetSkill(girl, SKILL_SERVICE));
	roll_max /= 4;
	wages += 10 + g_Dice%roll_max;
	wages += 5 * g_Clinic.GetNumGirlsOnJob(0, JOB_GETREPAIRS, Day0Night1);	// `J` pay her 5 for each patient you send to her		
	// Money
	if (wages < 0)	wages = 0;	girl->m_Pay = (int)wages;
	if (tips < 0)	tips = 0;	girl->m_Tips = (int)tips;


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

	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);
	g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, g_Dice%skill + 1);
	g_Girls.UpdateSkill(girl, SKILL_MEDICINE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_SERVICE, g_Dice%skill);
	g_Girls.UpdateStatTemp(girl, STAT_LIBIDO, libido);

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);

	//gain traits
	g_Girls.PossiblyGainNewTrait(girl, "Charismatic", 60, actiontype, "Dealing with patients and talking with them about their problems has made " + girl->m_Realname + " more Charismatic.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "Strong", 60, actiontype, "Handling heavy parts and working with heavy tools has made " + girl->m_Realname + " much Stronger.", Day0Night1);

	//lose traits
	g_Girls.PossiblyLoseExistingTrait(girl, "Nervous", 20, actiontype, girl->m_Realname + " seems to finally be getting over her shyness. She's not always so Nervous anymore.", Day0Night1);
	g_Girls.PossiblyLoseExistingTrait(girl, "Elegant", 40, actiontype, " Working with dirty, greasy equipment has damaged " + girl->m_Realname + "'s hair, skin and nails making her less Elegant.", Day0Night1);

#pragma endregion
	return false;
}