// ==UserScript==
// @name Harem Heroes++
// @namespace haremheroes.com
// @description Adding things here and there in Harem Heroes game.
// @version 0.02.1
// @match http://nutaku.haremheroes.com/*
// @match https://www.hentaiheroes.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 + ' | ' + 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, ",");
}