Harem Heroes++

Adding things here and there in Harem Heroes game.

Verzia zo dňa 15.09.2017. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name			Harem Heroes++
// @namespace		haremheroes.com
// @description		Adding things here and there in Harem Heroes game.
// @version			0.01
// @match			http://nutaku.haremheroes.com/*
// @run-at			document-end
// @grant			none
// @author			Raphael
// ==/UserScript==

var CurrentPage = window.location.pathname;

// css define
var sheet = (function() {
	var style = document.createElement('style');
	// style.appendChild(document.createTextNode('')); // WebKit hack :(
	document.head.appendChild(style);
	return style.sheet;
})();

// Current page: Market
if (CurrentPage.indexOf('shop') != -1) {
	ModifyShop();
}
// Current page: Harem
else if (CurrentPage.indexOf('harem') != -1) {
	ModifyHarem();
}


/* ==========
	 Market
   ========== */

function ModifyShop() {

	// first load
	equipments_shop(0);
	boosters_shop(0);
	books_shop(0);
	gifts_shop(0);

	// catch click on Equip/Offer or Sell > update tooltip after 1.5s
	$('#inventory > button').click(function(e) {
		setTimeout( function() {
			var opened_shop = $('#inventory > .selected');
			if (opened_shop.hasClass('armor')) {
				equipments_shop(1);
			} else if (opened_shop.hasClass('booster')) {
				boosters_shop(1);
			} else if (opened_shop.hasClass('potion')) {
				books_shop(1);
			} else if (opened_shop.hasClass('gift')) {
				gifts_shop(1);
			}
		}, 1500 );
    });

	function equipments_shop(update) {
		tt_create(update, 'armor', 'EquipmentsTooltip', 'equipments', '');
	}
	function boosters_shop(update) {
		tt_create(update, 'booster', 'BoostersTooltip', 'boosters', '');
	}
	function books_shop(update) {
		tt_create(update, 'potion', 'BooksTooltip', 'books', 'Xp');
	}
	function gifts_shop(update) {
		tt_create(update, 'gift', 'GiftsTooltip', 'gifts', 'affection');
	}

	// create tooltip
	function tt_create(update, loc_class, tt_class, itemName, itemUnit) {
		// initialize
		var itemNb = 0,
			itemXp = (itemUnit == '' ? -1 : 0),
			itemSell = 0,
			loc = $('#inventory > div.' + loc_class);

		// get stats
		$.each( loc.find('div.slot'), function(){
			if ($(this).hasClass('empty')) return false;
			var item = $(this).data('d'),
				nb = 0;
			nb = parseInt(item.count);
			itemNb += nb;
			itemSell += parseInt(nb * item.price_sell);
			if (itemXp != -1) itemXp += parseInt(nb * item.value);
		});

		// remove old tooltip
		if (update == 1) {
			loc.children('.CustomTT').remove();
			loc.children('.' + tt_class).remove();
		}

		// add tooltip
		loc.prepend('<span class="CustomTT"></span><div class="' + tt_class + '">'
				  + 'You own <b>' + numberWithCommas(itemNb) + '</b> ' + itemName + '.<br />'
				  + ( itemXp == -1 ? '' : 'You can give a total of <b>' + numberWithCommas(itemXp) + '</b> ' + itemUnit + '.<br />' )
				  + 'You can sell everything for <b>' + numberWithCommas(itemSell) + '</b> <span class="imgMoney"></span>.'
				  + '</div>');
	}


	// -----------------
	//     CSS RULES
	// -----------------

	sheet.insertRule('#inventory .CustomTT {'
						+ 'float: right;'
						+ 'margin: 11px 1px 0 0;'
						+ 'background-image: url("http://i.harem-battle.club/images/2017/09/13/FPE.png");'
						+ 'background-size: 18px 18px;'
						+ 'width: 18px;'
						+ 'height: 18px; }');

	sheet.insertRule('#inventory .CustomTT:hover {'
						+ 'cursor: help; }');

	sheet.insertRule('#inventory .CustomTT:hover + div {'
						+ 'display: block; }');

	sheet.insertRule('#inventory .EquipmentsTooltip, #inventory .BoostersTooltip, #inventory .BooksTooltip, #inventory .GiftsTooltip {'
						+ 'position: absolute;'
						+ 'z-index: 99;'
						+ 'width: 240px;'
						+ 'border: 1px solid #B14;'
						+ 'border-radius: 8px;'
						+ 'padding: 3px 7px 4px 7px;'
						+ 'background-color: #F2F2F2;'
						+ 'font: normal 10px/17px Tahoma, Helvetica, Arial, sans-serif;'
						+ 'color: #057;'
						+ 'display: none; }');

	sheet.insertRule('#inventory .EquipmentsTooltip, #inventory .BoostersTooltip {'
						+ 'margin: -33px 0 0 210px;'
						+ 'height: 43px; }');

	sheet.insertRule('#inventory .BooksTooltip, #inventory .GiftsTooltip {'
						+ 'margin: -50px 0 0 210px;'
						+ 'height: 60px; }');

	sheet.insertRule('#inventory .EquipmentsTooltip b, #inventory .BoostersTooltip b, #inventory .BooksTooltip b, #inventory .GiftsTooltip b {'
						+ 'font-weight:bold; }');

	sheet.insertRule('#inventory .imgMoney {'
						+ 'background-size: 12px 12px;'
						+ 'background-repeat: no-repeat;'
						+ 'width: 12px;'
						+ 'height: 14px;'
						+ 'vertical-align: text-bottom;'
						+ 'background-image: url("http://i.harem-battle.club/images/2017/01/07/0Gsvn.png");'
						+ 'display: inline-block; }');
}


/* =========
	 Harem
   ========= */

function ModifyHarem() {
	var i = 0,
		Anchor = '',
		GirlId = '',
		GirlName = '',
		Specialty = [0, 0, 0], // [Hardcore, Charm, Know-how]
		AvailableScenes = 0,
		UnlockedScenes = 0,
		AllHourlyIncome = 0,
		AllSalary = 0,
		HaremArrayList = [],
		HaremStringQList = '<div id="HaremQListContainer">Quick List:<div class="CustomContainer">',
		HaremStringStats = '<div id="HaremStatsContainer">Harem Stats:<div class="CustomContainer">',
		HaremTop = '<a href="#Bunny">Top</a>',
		HaremBottom = '',
		Saffection = 0, // S= Stats requirements (left tooltip)
		Smoney = 0,
		Skobans = 0;

	var EvoRequire = [];
	EvoRequire.push({ affection: 15, money: 3150, kobans: 30 });
	EvoRequire.push({ affection: 50, money: 6750, kobans: 90 });
	EvoRequire.push({ affection: 150, money: 18000, kobans: 150 });
	EvoRequire.push({ affection: 700, money: 135000, kobans: 240 });
	EvoRequire.push({ affection: 1750, money: 968000, kobans: 300 });

	// parse haremettes list
	$.each($('#harem_left div[girl]'), function(){
		i++;

		GirlId = $(this).attr('girl');
		GirlName = $(this).find('h4').text();
		AllSalary += parseInt($(this).find('.sal').text());
		HaremArrayList.push({Id: GirlId, Order: i, Name: GirlName});

		// add anchor
		$(this).attr('id', GirlName);
		// display: haremette number
		$(this).find('h4').append('<div class="HaremetteNb">' + i + '</div>');

		// is opened girl?
		if ($(this).hasClass('opened')) {
			Anchor = GirlName;
		}
	});
	HaremBottom = '<a href="#' + GirlName + '">Bottom</a>';

	// auto-scroll to anchor
	location.hash = '#' + Anchor;

	// get haremettes stats & display wiki link
	i = 0;
	$('#harem_right div[girl]').each( function() {
		var Taffection = 0, // T= Total requirements (right tooltip)
			Tmoney = 0,
			Tkobans = 0,
			FirstLockedScene = 0;

		girl_quests = $(this).find('div.girl_quests');

		// display: wiki link
		$(this).append('<div class="WikiLink"><a href="http://harem-battle.club/wiki/Harem-Heroes/HH:' + HaremArrayList[i]['Name'] + '" target="_blank"> her wiki page </a></div>');
		i++;

		// get stats: specialty
		Spe = parseInt($(this).find('h3 span').attr('carac')) - 1;
		Specialty[Spe]++;

		// get stats: hourly income
		AllHourlyIncome += parseInt($(this).find('div.salary').text());

		var j = 0,
			AffectionTooltip = 'She is your <b>' + i + '</b>th haremette. Her evolution costs are:<br />';
		girl_quests.find('g').each( function() {
			// prepare affection tooltip
			var Raffection = EvoRequire[j]['affection']*i; // R= Required for this star (right tooltip)
			var Rmoney = EvoRequire[j]['money']*i;
			var Rkobans = EvoRequire[j]['kobans']*i;
			j++;
			Taffection += Raffection;
			Tmoney += Rmoney;
			Tkobans += Rkobans;
			AffectionTooltip += '<b>' + j + '</b><span class="imgStar"></span> : '
							  + numberWithCommas(Raffection) + ' affection, '
							  + numberWithCommas(Rmoney) + ' <span class="imgMoney"></span> or '
							  + numberWithCommas(Rkobans) + ' <span class="imgKobans"></span><br />';

			// get stats: scenes
			AvailableScenes++;
			if ($(this).hasClass('grey')) {
				if (FirstLockedScene == 1) {
					Saffection += Raffection;
				} else {
					FirstLockedScene = 1;
					var XpLeft = girl_quests.parent().children('div.girl_exp_left');
					if (XpLeft.length) Saffection += parseInt(XpLeft.text().match(/^Left: (.*)$/)[1].replace(',',''));
				}
				Smoney += Rmoney;
				Skobans += Rkobans;
			} else {
				UnlockedScenes++;
			}
		});
		AffectionTooltip += '<b>Total:</b> '
							  + numberWithCommas(Taffection) + ' affection, '
							  + numberWithCommas(Tmoney) + ' <span class="imgMoney"></span> or '
							  + numberWithCommas(Tkobans) + ' <span class="imgKobans"></span>';

		// display: Affection costs tooltip
		girl_quests.parent().children('h4').prepend('<span class="CustomTT"></span><div class="AffectionTooltip">' + AffectionTooltip + '</div>');
	});

	// ### TAB: Quick List ###

	// order haremettes alphabetically
	HaremArrayList.sort(function(a, b) {
		var textA = a.Name.toUpperCase(),
			textB = b.Name.toUpperCase();
		return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
	});
	// html quick list
	for( var i = 0, len = HaremArrayList.length; i < len; i++ ){
		HaremStringQList += '<a f="ql_girl" girl="' + HaremArrayList[i]['Id'] + '" href="#' + HaremArrayList[i]['Name'] + '">' + HaremArrayList[i]['Name'] + '</a> (#' + HaremArrayList[i]['Order'] + ')<br />';
	}
	HaremStringQList += '</div></div>';

	// ### TAB: Stats ###

	HaremStringStats += '<b>' + i + ' haremettes</b>'
					  + '<br />- ' + Specialty[0] + ' Hardcore'
					  + '<br />- ' + Specialty[1] + ' Charm'
					  + '<br />- ' + Specialty[2] + ' Know-how'
					  + '<br />' + UnlockedScenes + '/' + AvailableScenes + ' unlocked scenes'
					  + '<br />'
					  + '<br /><b>Required to unlock all locked scenes:</b>'
					  + '<br />- ' + numberWithCommas(Saffection) + ' affection'
					  + '<br />- ' + numberWithCommas(Smoney) + ' <img src="http://i.harem-battle.club/images/2017/01/07/0Gsvn.png">'
								   + ' or ' + numberWithCommas(Skobans) + ' <img src="http://i.harem-battle.club/images/2016/08/30/gNUo3XdY.png">'
					  + '<br />'
					  + '<br /><b>Money incomes:</b>'
					  + '<br />~' + numberWithCommas(AllHourlyIncome) + '$ per hour'
					  + '<br />' + numberWithCommas(AllSalary) + '$ when all collectable'
					  + '</div></div>';

	// add custom bar buttons/links
	$('#harem_left').append( '<div id="CustomBar">'
						   + '<img f="list" src="http://i.harem-battle.club/images/2017/09/10/FRW.png">'
						   + '<img f="stats" src="http://i.harem-battle.club/images/2017/09/11/FRh.png">'
						   + '<div class="TopBottomLinks">' + HaremTop + '&nbsp;&nbsp;|&nbsp;&nbsp;' + HaremBottom + '</div>'
						   + '</div>' );

	// add quick list div
	$('#CustomBar').append( HaremStringQList );

	// add stats div
	$('#CustomBar').append( HaremStringStats );

	// cache
	QList = $('#HaremQListContainer');
	Stats = $('#HaremStatsContainer');

	// catch clicks
	$('body').click(function(e) {
		var clickOn = e.target.getAttribute('f');
		switch (clickOn) {
			// on quick list button
			case 'list':
				QList.toggle();
				Stats.toggle(false);
				break;
			// on stats button
			case 'stats':
				Stats.toggle();
				QList.toggle(false);
				break;
			// on a girl in quick list
			case 'ql_girl':
				var clickedGirl = e.target.getAttribute('girl');
				$('#harem_left div[girl=' + clickedGirl + ']').triggerHandler('click');
				break;
			// somewhere else except custom containers
			default:
				var clickedContainer = $(e.target).closest('[id]').attr('id');
				if (clickedContainer == 'HaremQListContainer' || clickedContainer == 'HaremStatsContainer') return;
				QList.toggle(false);
				Stats.toggle(false);
				break;
		}
    });

	// -----------------
	//     CSS RULES
	// -----------------

	sheet.insertRule('#harem_left .HaremetteNb {'
						+ 'float: right;'
						+ 'line-height: 14px;'
						+ 'font-size: 12px; }');

	sheet.insertRule('#CustomBar {'
						+ 'position: absolute;'
						+ 'z-index: 99;'
						+ 'width: 100%;'
						+ 'padding: 3px 10px 0 3px;'
						+ 'font: bold 10px Tahoma, Helvetica, Arial, sans-serif; }');

	sheet.insertRule('#CustomBar img {'
						+ 'width: 20px;'
						+ 'height: 20px;'
						+ 'margin-right: 3px; }');

	sheet.insertRule('#CustomBar img:hover {'
						+ 'cursor: pointer; }');

	sheet.insertRule('#CustomBar .TopBottomLinks {'
						+ 'float: right;'
						+ 'margin-top: 2px; }');

	sheet.insertRule('#CustomBar a, #harem_right .WikiLink a {'
						+ 'color: #057;'
						+ 'text-decoration: none; }');

	sheet.insertRule('#CustomBar a:hover, #harem_right .WikiLink a:hover {'
						+ 'color: #B14;'
						+ 'text-decoration: underline; }');

	sheet.insertRule('#HaremQListContainer, #HaremStatsContainer {'
						+ 'position: absolute;'
						+ 'z-index: 99;'
						+ 'margin: -298px 0 0 -3px;'
						+ 'width: 220px;'
						+ 'height: 275px;'
						+ 'overflow-y: scroll;'
						+ 'padding: 2px 0 0 3px;'
						+ 'background-color: #ffffff;'
						+ 'font: bold 12px/18px Tahoma, Helvetica, Arial, sans-serif;'
						+ 'color: #B14;'
						+ 'display: none; }');

	sheet.insertRule('#harem_right .AffectionTooltip {'
						+ 'position: absolute;'
						+ 'z-index: 99;'
						+ 'margin-top: -130px;'
						+ 'width: 280px;'
						+ 'height: 127px;'
						+ 'border: 1px solid #B14;'
						+ 'border-radius: 8px;'
						+ 'padding: 3px 7px 4px 7px;'
						+ 'background-color: #F2F2F2;'
						+ 'font: normal 10px/17px Tahoma, Helvetica, Arial, sans-serif;;'
						+ 'text-align: left;'
						+ 'display: none; }');

	sheet.insertRule('#harem_left .CustomContainer b, #harem_right .AffectionTooltip b {'
						+ 'font-weight: bold; }');

	sheet.insertRule('#harem_left .CustomContainer {'
						+ 'padding: 3px 0 3px 6px;'
						+ 'font: normal 10px/16px Tahoma, Helvetica, Arial, sans-serif;;'
						+ 'color: #000000; }');

	sheet.insertRule('#harem_left .CustomContainer img {'
						+ 'width:14px;'
						+ 'height:14px;'
						+ 'vertical-align: text-bottom; }');

	sheet.insertRule('#harem_right .WikiLink {'
						+ 'float: right;'
						+ 'margin: -13px 7px 0 0;'
						+ 'font-size: 12px; }');

	sheet.insertRule('#harem_right .CustomTT {'
						+ 'float: right;'
						+ 'margin-left: -25px;'
						+ 'background-image: url("http://i.harem-battle.club/images/2017/09/13/FPE.png");'
						+ 'background-size: 18px 18px;'
						+ 'width: 18px;'
						+ 'height: 18px; }');

	sheet.insertRule('#harem_right .CustomTT:hover {'
						+ 'cursor: help; }');

	sheet.insertRule('#harem_right .CustomTT:hover + div {'
						+ 'display: block; }');

	sheet.insertRule('#harem_right .imgStar, #harem_right .imgMoney, #harem_right .imgKobans {'
						+ 'background-size: 10px 10px;'
						+ 'background-repeat: no-repeat;'
						+ 'width: 10px;'
						+ 'height: 14px;'
						+ 'display: inline-block; }');

	sheet.insertRule('#harem_right .imgStar {'
						+ 'background-image: url("http://i.harem-battle.club/images/2016/12/29/R9HWCKEtD.png"); }');

	sheet.insertRule('#harem_right .imgMoney {'
						+ 'background-image: url("http://i.harem-battle.club/images/2017/01/07/0Gsvn.png"); }');

	sheet.insertRule('#harem_right .imgKobans {'
						+ 'background-image: url("http://i.harem-battle.club/images/2016/08/30/gNUo3XdY.png"); }');
}

// adds thousands commas
function numberWithCommas(x) {
	return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}