Esempio n. 1
0
static int game_over(lua_State *L)
{
	cScriptManager sm;

	g_MessageQue.AddToQue("GAME OVER", COLOR_RED);
	g_WinManager.PopToWindow(&g_BrothelManagement);
	g_WinManager.Pop();
	g_InitWin = true;
	sm.Release();
	return 0;
}
Esempio n. 2
0
static int queue_message(lua_State *L)
{
	CLog log;

	const char *msg = luaL_checkstring(L, 1);
	int color = luaL_checkint(L, 2);

	log.ss() << "adding to message queue: '" << msg << "\n";
	//log.ss() << "Before add: has = " << g_MessageQue.HasNext();
	log.ssend();

	g_MessageQue.AddToQue(msg, color);
	//log.ss() << "After add: has = " << g_MessageQue.HasNext();
	//log.ssend();
	return 0;
}
Esempio n. 3
0
/*
* ideally, we'd keep a queue of message strings and
* pop them out in order at the end
*/
cGirlTorture::~cGirlTorture()		// deconstructor
{
	int color = COLOR_BLUE;
	if (m_Girl->m_RunAway != 0)
	{
		color = COLOR_RED;
	}

	// Display any outstanding messages
	if (!m_Message.empty())
	{
		if (m_TorturedByPlayer)
		{
			g_MessageQue.AddToQue(m_Message, color);
			m_Girl->m_Events.AddMessage(m_Message, IMGTYPE_TORTURE, EVENT_SUMMARY);	// `J` added
		}
		else
		{
			if (m_Girl->health()>0)		// Make sure girl is alive
				m_Girl->m_Events.AddMessage(m_Message, IMGTYPE_TORTURE, EVENT_SUMMARY);
		}
	}
}
Esempio n. 4
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);
}
Esempio n. 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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
// `J` Job Movie Studio - Actress
bool cJobManager::WorkFilmBeast(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKMOVIE;
	// No film crew.. then go home	// `J` this will be taken care of in building flow, leaving it in for now
	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;
	}
	cConfig cfg;
	stringstream ss;
	string girlName = girl->m_Realname;
	int wages = 50;
	int enjoy = 0;
	int jobperformance = 0;

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

	ss << girlName << " worked as an actress filming scenes with beasts.\n\n";

	int roll = g_Dice.d100();
	if (roll <= 10 && g_Girls.DisobeyCheck(girl, ACTION_WORKMOVIE, brothel))
	{
		ss << "She refused to f**k any beasts on film today.\n";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	else if (roll <= 10) { enjoy -= g_Dice % 3 + 1;	ss << "She didn't enjoy letting the creature f**k her.\n\n"; }
	else if (roll >= 90) { enjoy += g_Dice % 3 + 1;	ss << "She loved the feel of the creature on top of her.\n\n"; }
	else /*            */{ enjoy += g_Dice % 2;		ss << "She didn't do much else today.\n\n"; }
	jobperformance = enjoy * 2;

	if (g_Girls.CheckVirginity(girl))
	{
		g_Girls.LoseVirginity(girl);	// `J` updated for trait/status
		jobperformance += 50;
		ss << "She is no longer a virgin.\n";
	}

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

	// mod: added check for number of beasts owned; otherwise, fake beasts could somehow inseminate the girl
	if (g_Brothels.GetNumBeasts() > 0)
	{
		if (!girl->calc_insemination(g_Brothels.GetPlayer(), false, 1.0))
			g_MessageQue.AddToQue(girl->m_Realname + " has gotten inseminated", 0);
	}

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_BEAST, 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_Pay = wages;

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

	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_BEASTIALITY, g_Dice%skill + 1);

	g_Girls.UpdateEnjoyment(girl, ACTION_SEX, enjoy);
	g_Girls.UpdateEnjoyment(girl, ACTION_WORKMOVIE, enjoy);
	g_Girls.PossiblyGainNewTrait(girl, "Fake O****m Expert", 50, ACTION_SEX, "She has become quite the faker.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "P**n Star", 80, ACTION_WORKMOVIE, "She has performed in enough sex scenes that she has become a well known P**n Star.", 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;
}
Esempio n. 9
0
// `J` Job Centre - General
bool cJobManager::WorkFeedPoor(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
#pragma region //	Job setup				//
	int actiontype = ACTION_WORKCENTRE;
	stringstream ss; string girlName = girl->m_Realname; ss << girlName;
	int roll_a = g_Dice.d100(), roll_b = g_Dice.d100(), roll_c = g_Dice.d100();
	if (g_Girls.DisobeyCheck(girl, ACTION_WORKCENTRE, brothel))			// they refuse to work 
	{
		ss << " refused to work during the " << (Day0Night1 ? "night" : "day") << " shift.";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	ss << " worked feeding the poor.";

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

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

	int imagetype = IMGTYPE_PROFILE;
	int msgtype = Day0Night1;

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

	double jobperformance = JP_FeedPoor(girl, false);


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


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


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

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



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




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

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


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

#pragma endregion
#pragma region	//	Money					//


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

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

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

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


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

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


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

	g_Girls.UpdateEnjoyment(girl, actiontype, enjoy);


	delete Cust;

#pragma endregion
	return false;
}
Esempio n. 10
0
// ----- Update & end of turn
void cCentreManager::UpdateCentre()	// Start_Building_Process_A
{
	cTariff tariff;
	stringstream ss;
	string girlName;

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

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

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

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

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

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

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

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

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

			cgirl = cgirl->m_Next;
		}
	}

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

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

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

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

	cgirl = current->m_Girls;
	while (cgirl)
	{
		g_Girls.updateTemp(cgirl);			// update temp stuff
		g_Girls.EndDayGirls(current, cgirl);
		cgirl = cgirl->m_Next;
	}
}
// `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;
}
// `J` Job Movie Studio - Actress
bool cJobManager::WorkFilmBondage(sGirl* girl, sBrothel* brothel, bool Day0Night1, string& summary)
{
	int actiontype = ACTION_WORKMOVIE;
	// No film crew.. then go home	// `J` this will be taken care of in building flow, leaving it in for now
	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 enjoy = 0;
	int jobperformance = 0;

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

	ss << girlName << " worked as an actress filming BDSM scenes.\n\n";

	int roll = g_Dice.d100();
	if (roll <= 10 && g_Girls.DisobeyCheck(girl, ACTION_WORKMOVIE, brothel))
	{
		ss << "She refused to get beaten on film today.\n";
		girl->m_Events.AddMessage(ss.str(), IMGTYPE_PROFILE, EVENT_NOWORK);
		return true;
	}
	else if (roll <= 10) { enjoy -= g_Dice % 3 + 1;	ss << "She did not enjoy getting tied up and hurt today.\n\n"; }
	else if (roll >= 90) { enjoy += g_Dice % 3 + 1;	ss << "She had a great time getting spanked and whipped.\n\n"; }
	else /*            */{ enjoy += g_Dice % 2;		ss << "She had just another day in the dungeon.\n\n"; }
	jobperformance = enjoy * 2;

	if (g_Girls.CheckVirginity(girl))
	{
		g_Girls.LoseVirginity(girl);	// `J` updated for trait/status
		jobperformance += 50;
		ss << "She is no longer a virgin.\n";
	}
	sCustomer* Cust = new sCustomer; g_Customers.GetCustomer(Cust, brothel); Cust->m_Amount = 1;
	if (Cust->m_IsWoman)	// FemDom
	{
		jobperformance += 20;
		/* */if (girl->has_trait("Lesbian"))	jobperformance += 20;
		else if (girl->has_trait("Straight"))	jobperformance -= 20;
	}
	else
	{
		if (!girl->calc_pregnancy(Cust, false, 0.75))
			g_MessageQue.AddToQue(girl->m_Realname + " has gotten pregnant", 0);
		/* */if (girl->has_trait("Lesbian"))	jobperformance -= 10;
		else if (girl->has_trait("Straight"))	jobperformance += 10;
	}

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

	girl->m_Events.AddMessage(ss.str(), IMGTYPE_BDSM, 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_Pay = wages;

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

	g_Girls.UpdateStat(girl, STAT_EXP, xp);
	g_Girls.UpdateSkill(girl, SKILL_PERFORMANCE, g_Dice%skill);
	g_Girls.UpdateSkill(girl, SKILL_BDSM, g_Dice%skill + 1);

	g_Girls.UpdateEnjoyment(girl, ACTION_SEX, enjoy);
	g_Girls.UpdateEnjoyment(girl, ACTION_WORKMOVIE, enjoy);
	//gain
	g_Girls.PossiblyGainNewTrait(girl, "Fake O****m Expert", 50, ACTION_SEX, "She has become quite the faker.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "M*******t", 65, ACTION_SEX, girlName + " has turned into a M*******t from filming so many BDSM scenes.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "S**t", 80, ACTION_SEX, girlName + " has turned into quite a s**t.", Day0Night1);
	g_Girls.PossiblyGainNewTrait(girl, "P**n Star", 80, ACTION_WORKMOVIE, "She has performed in enough sex scenes that she has become a well known P**n Star.", Day0Night1);
	//lose

	delete Cust;
	return false;
}
Esempio n. 13
0
void cScreenBrothelManagement::check_events()
{
	if (g_InterfaceEvents.GetNumEvents() != 0)
	{
		if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_girls))
		{
			g_InitWin = true;
			g_WinManager.push("Girl Management");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_staff))
		{
			g_InitWin = true;
			g_WinManager.push("Gangs");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_setup))
		{
			g_InitWin = true;
			g_WinManager.push("Building Setup");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_dungeon))
		{
			g_InitWin = true;
			g_WinManager.push("Dungeon");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_town))
		{
			g_InitWin = true;
			g_WinManager.push("Town");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_save))
		{
			SaveGame(g_CTRLDown);
			g_MessageQue.AddToQue("Game Saved", COLOR_GREEN);
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_week))
		{
			g_InitWin = true;
			if (!g_CTRLDown) { g_CTRLDown = false; AutoSaveGame(); }
			NextWeek();
			g_WinManager.push("TurnSummary");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_turn))
		{
			g_InitWin = true;
			g_CurrentScreen = SCREEN_TURNSUMMARY;
			g_WinManager.push("TurnSummary");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_quit))
		{
			g_InitWin = true;
			g_GetInput.ModeConfirmExit();
			g_WinManager.push("GetInput");
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_next))
		{
			g_CurrBrothel++;
			if (g_CurrBrothel >= g_Brothels.GetNumBrothels())
				g_CurrBrothel = 0;
			g_InitWin = true;
			return;
		}
		else if (g_InterfaceEvents.CheckEvent(EVENT_BUTTONCLICKED, id_prev))
		{
			g_CurrBrothel--;
			if (g_CurrBrothel < 0)
				g_CurrBrothel = g_Brothels.GetNumBrothels() - 1;
			g_InitWin = true;
			return;
		}
	}
}
// `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;
}
Esempio n. 15
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;
	}
}
Esempio n. 16
0
void cDungeon::Update()
{
	/*
	*	WD: GetNumGirlsOnJob() not testing if the girl worked
	*
	*/
	sGirl* TorturerGirlref = 0;
	string girlName;
	stringstream msg;
	stringstream ss;

	// Reser counters
	m_NumGirlsTort = m_NumCustsTort = 0;

	// WD:	Did we torture the girls
	bool tort = g_Brothels.TortureDone();
	// WD: If so, who is the Torturer
	if (tort) { TorturerGirlref = g_Brothels.WhoHasTorturerJob(); }

	/*********************************
	*	DO ALL DUNGEON GIRLS
	*********************************/
	if (m_Girls)
	{

		sDungeonGirl* current = m_Girls;
		while (current)
		{
			sGirl* girl = current->m_Girl;

			//			girl->m_Tort = false;// WD: Move till after Girls have been tortured so that we dont torture twice week
			girlName = girl->m_Realname;
			ss.str("");
			msg.str("");

			// Check for dead girls
			if (girl->health() <= 0)
			{
				// remove dead bodies from last week
				if (current->m_Reason == DUNGEON_DEAD)
				{
					sDungeonGirl* temp = current;
					current = current->m_Next;
					msg << girlName << "'s body has been removed from the dungeon since she was dead.";
					g_MessageQue.AddToQue(msg.str(), COLOR_RED);
					delete RemoveGirl(temp);
					continue;
				}
				// Mark as dead
				else
				{
					m_NumberDied++;
					current->m_Reason = DUNGEON_DEAD;
					SetGameFlag(FLAG_DUNGEONGIRLDIE);
					continue;
				}
			}
			/*
			*			DAILY Processing
			*/
			string summary = "";

			current->m_Weeks++;						// the number of weeks they have been in the dungeon
			g_Girls.CalculateGirlType(girl);		// update the fetish traits
			g_Girls.updateGirlAge(girl, true);		// update birthday counter and age the girl
			g_Girls.updateTemp(girl);			// update temp stuff
			g_Girls.EndDayGirls(g_Brothels.GetBrothel(0), girl);
			g_Girls.HandleChildren(girl, summary);	// handle pregnancy and children growing up
			g_Girls.updateSTD(girl);				// health loss to STD's - NOTE: Girl can die
			g_Girls.updateHappyTraits(girl);		// Update happiness due to Traits - NOTE: Girl can die
			updateGirlTurnDungeonStats(current);	// Update stats
			g_Girls.updateGirlTurnStats(girl);		// Stat Code common to Dugeon and Brothel

			// Check again for dead girls
			if (g_Girls.GetStat(girl, STAT_HEALTH) <= 0)
			{
				m_NumberDied++;
				current->m_Reason = DUNGEON_DEAD;
				SetGameFlag(FLAG_DUNGEONGIRLDIE);

				msg.str(""); ss.str("");
				msg << girlName << gettext(" has died in the dungeon.");
				girl->m_Events.AddMessage(msg.str(), IMGTYPE_DEATH, EVENT_DANGER);
				ss << girlName << gettext(" has died.  Her body will be removed by the end of the week.\n");
				girl->m_Events.AddMessage(ss.str(), IMGTYPE_DEATH, EVENT_SUMMARY);

				// if there is a torturer send her a message
				if (tort)
				{
					msg.str("");
					msg << girlName << gettext(" has died in the dungeon under her care!");
					TorturerGirlref->m_Events.AddMessage(msg.str(), IMGTYPE_PROFILE, EVENT_DUNGEON);
				}

				current = current->m_Next;
				continue;
			}

			// Have dungeon girls tortured by the Torturer
			if (tort)
			{
				cGirlTorture gt(current, TorturerGirlref);
			}

			/*		`J` merged WARNING MESSAGES and SUMMARY MESSAGES
			*			Allow girl sorting in turn summary
			*/
			//	`J` set the basics
			msg.str(""); ss.str("");
			msg << girlName << gettext(" is languish in the dungeon.\n\n");
			int msgtype = EVENT_DUNGEON;
			int imgtype = IMGTYPE_PROFILE;
			int	nHealth = girl->health();
			int	nTired = girl->tiredness();

			//	`J` check them for dangers or warnings
			if (nHealth < 20 || nTired > 80)
			{
				msg << gettext("DANGER: ") << girlName;
				msgtype = EVENT_DANGER;
			}
			else if (nHealth < 40 || nTired > 60)
			{
				msg << gettext("WARNING: ") << girlName;
				msgtype = EVENT_WARNING;
			}

			//	`J` did msgtype change?
			if (msgtype != EVENT_DUNGEON)
			{
				if (girl->m_Tort)
				{
					msg << gettext(" was tortured this week.");
					imgtype = IMGTYPE_TORTURE;
					if (nHealth < 40 || nTired > 60)	{ msg << gettext("\nShe"); }
				}
				if (nHealth < 20)						{ msg << gettext(" is severely injured"); }
				else if (nHealth < 40)					{ msg << gettext(" is injured"); }
				if (nHealth < 40 && nTired > 60)		{ msg << gettext(" and"); }
				else if (nTired > 60)					{ msg << gettext(" is"); }
				else									{ msg << gettext("."); }
				if (nTired > 80)						{ msg << gettext(" exhausted, it may effect her health."); }
				else if (nTired > 60)					{ msg << gettext(" tired."); }
				msg << gettext("\n\nHer health is ") << nHealth << gettext(".\nHer tiredness is ") << nTired << ".";
			}
			girl->m_Events.AddMessage(msg.str(), imgtype, msgtype);

			girl->m_Tort = false;

			// loop next dungeon girl	
			current = current->m_Next;
		}

		/*
		*			WD:  Torturer Girl summary
		*				Processed after all dGirls
		*/
		if (tort)
		{
			msg.str("");
			msg << TorturerGirlref->m_Realname << gettext(" has tortured ") << m_NumGirlsTort << gettext(" girls in the Dungeon.");
			TorturerGirlref->m_Events.AddMessage(msg.str(), IMGTYPE_PROFILE, EVENT_DUNGEON);

		}
	}


	/*********************************
	*	DO ALL CUSTOMERS
	*********************************/
	if (m_Custs)
	{
		sDungeonCust* current = m_Custs;
		while (current)
		{
			current->m_Tort = false;
			if (current->m_Health <= 0)
			{
				m_NumberDied++;
				current->m_Reason = DUNGEON_DEAD;
				SetGameFlag(FLAG_DUNGEONCUSTDIE);
			}
			if (current->m_Reason == DUNGEON_DEAD)
			{
				sDungeonCust* temp = current;
				current = current->m_Next;
				RemoveCust(temp);
				continue;
			}

			/*
			*			lose health if not feeding
			*
			*			Mod: removed "no-effect" branch to silence
			*			compiler
			*/
			if (!current->m_Feeding) current->m_Health -= 5;

			current->m_Weeks++;
			if (current->m_Health <= 0)
			{
				m_NumberDied++;
				current->m_Reason = DUNGEON_DEAD;
				SetGameFlag(FLAG_DUNGEONCUSTDIE);
			}
			current = current->m_Next;
		}
	}
}
Esempio n. 17
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 - 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;
}
Esempio n. 19
0
// `J` Job Farm - Laborers
bool cJobManager::WorkShepherd(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))
	{
		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 shepherd in 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_Shepherd(girl, false);

	// brings in food and rarely beasts
	double beasts = jobperformance / 100;
	double food = jobperformance;

	if (jobperformance >= 245)
	{
		ss << "The animals come to " << girlName << " when they are ready for market.";
		beasts *= 2.0; food *= 2.0; roll_a += 10; roll_b += 25;
	}
	else if (jobperformance >= 185)
	{
		ss << girlName << " seems to know just when to choose the best animals to send to market.";
		beasts *= 1.6; food *= 1.6; roll_a += 5; roll_b += 18;
	}
	else if (jobperformance >= 145)
	{
		ss << girlName << " has little trouble finding animals to send to market.";
		beasts *= 1.2; food *= 1.2; roll_a += 2; roll_b += 10;
	}
	else if (jobperformance >= 100)
	{
		ss << girlName << " usually sends the right animals to market.";
	}
	else if (jobperformance >= 70)
	{
		ss << girlName << " doesn't know what animals to send to the market so she just guesses.";
		beasts *= 0.8; food *= 0.8; roll_a -= 2; roll_b -= 5;
	}
	else
	{
		ss << girlName << " has no idea what she is doing.";
		beasts *= 0.5; food *= 0.5; wages -= 10; 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";
		if (g_Dice.percent(20))
		{
			enjoy--;
			ss << "Several animals got out and " << girlName << " had to chase them down.\n";
			girl->happiness(-(1 + g_Dice % 5));
			girl->tiredness(1 + g_Dice % 15);
			beasts *= 0.8;
			food *= 0.9;
		}
		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";
			beasts *= 0.9;
			food *= 0.8;
		}
	}
	else if (roll_a >= 90)
	{
		enjoy += g_Dice % 3 + 1;
		ss << "The animals were pleasant and cooperative today.\n";
		beasts *= 1.1;
		food *= 1.1;
	}
	else
	{
		enjoy += g_Dice % 2;
		ss << "She had an uneventful day tending the animals.\n";
	}

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




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
















#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()))
	{
		beasts *= 0.9;
		food *= 0.9;
		wages = 0;
	}
	else	// `J` Pay her based on how much she brought in
	{
		if ((int)food > 0)		wages += food / 100;
		if ((int)beasts > 0)	wages += beasts;
	}

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

	ss << "\n" << girlName;
	if ((int)beasts > 0)
	{
		g_Brothels.add_to_beasts((int)beasts);
		ss << " brought " << (int)beasts << " beasts to work in the brothels";
	}
	if ((int)beasts > 0 && (int)food > 0)
	{
		ss << " and";
	}
	if ((int)food > 0)
	{
		g_Brothels.add_to_food((int)food);
		ss << " sent " << (int)food << " units of food worth of animals to slaughter";
	}
	if ((int)beasts <= 0 && (int)food <= 0)
	{
		ss << " did not bring in any animals";
	}
	ss << ".";

	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_ANIMALHANDLING, (g_Dice % skill) + 2);
	// secondary (-1 for one then -2 for others)
	g_Girls.UpdateStat(girl, STAT_CHARISMA, max(0, (g_Dice % skill) - 1));
	g_Girls.UpdateStat(girl, STAT_INTELLIGENCE, max(0, (g_Dice % skill) - 2));
	g_Girls.UpdateStat(girl, STAT_CONFIDENCE, max(0, (g_Dice % skill) - 2));

#pragma endregion
	return false;
}