"use strict";
this.name = "GalCopBB_CoreMissionValues";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "End points for most mission value settings";
this.license = "CC BY-NC-SA 4.0";

/*
returned object must return:
	quantity
	price
	expiry
can optionally return (if required for the mission)
	locationType
	penalty
	commodity
	clientName
*/

this._maxLocations = 0;
this._commodityAverage = {
	"food": 5.0,
	"textiles": 7.2,
	"radioactives": 23.2,
	"slaves": 15.2,
	"liquor_wines": 29.2,
	"luxuries": 90.2,
	"narcotics": 51.0,
	"computers": 81.8,
	"machinery": 56.6,
	"alloys": 38.8,
	"firearms": 69.2,
	"furs": 70.5,
	"minerals": 12.0,
	"gold": 38.8,
	"platinum": 71.8,
	"gem_stones": 19.6,
	"alien_items": 43.6
};

//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
	var missionTypes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
	var cargoMissions = [8, 9, 10, 11, 12, 14, 15, 17];

	var gcm = worldScripts.GalCopBB_Missions;
	// position 7 is not used in any of these mission types, so limit the possibilities 
	this._maxLocations = gcm._positions.length - 1;

	// add our mission types into the main control
	gcm._availableMissionTypes = gcm._availableMissionTypes.concat(missionTypes);
	gcm._cargoMissionTypes = gcm._cargoMissionTypes.concat(cargoMissions);
	gcm._interstellarMissionTypes = gcm._interstellarMissionTypes.concat([5, 13]);
}

//-------------------------------------------------------------------------------------------------------------
// 1 - asteroid hunt
this.$missionType1_Values = function $missionType1_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 10) + 15);
	// make sure we're not asking for more asteroids that are currently in the system
	var avail = system.countShipsWithRole("asteroid");
	if (result > avail) result = parseInt(avail / 2);

	// price is a straight (quantity * 5)
	result["price"] = (result.quantity * 5) +
		this.$calcPlayerBonus(200); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + workTime + (result.quantity * 600); // 1 hour + 10 minutes per asteroid to complete.
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 2 - pirate hunt
this.$missionType2_Values = function $missionType2_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 8) + 6);
	// base the reward rate on danger level in the target system
	var amt = parseInt((result.quantity * (parseInt(Math.random() * ((4 - destSysInfo.government) * 50)) + 50)) / 10) * 10 +
		this.$calcPlayerBonus(500); // plus a possible bonus price, based on player score 
	// occasionally double the price
	if (Math.random() > 0.95 && destSysInfo.government < 2) amt *= 2;
	result["price"] = amt;
	result["expiry"] = clock.adjustedSeconds + routeTime + (result.quantity * 1800) + workTime; // transit time + 30 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 3 - trader hunt (local gov)
this.$missionType3_Values = function $missionType3_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 10) + 7);
	// base the reward rate on the danger level in the target system
	// danger in this case is the likelyhood of being caught by police
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * (7 - destSysInfo.government) * 50) + 50)) / 10) * 10 +
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + routeTime + (result.quantity * 600) + workTime; // transit time + 10 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 4 - trader hunt (pirate)
this.$missionType4_Values = function $missionType4_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 10) + 7);
	// base the reward rate on the danger level in the target system
	// danger in this case is the likelyhood of being caught by police
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * (7 - destSysInfo.government) * 100) + 50)) / 10) * 10 +
		this.$calcPlayerBonus(800); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + routeTime + (result.quantity * 500) + workTime; // transit time + 8 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 5 - thargoid hunt
this.$missionType5_Values = function $missionType5_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 7) + 3);
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 100) + 150)) / 10) * 10 +
		this.$calcPlayerBonus(1000); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + routeTime + (result.quantity * 600) + workTime; // transit time + 10 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 6 - recover cargo (local gov)
this.$missionType6_Values = function $missionType6_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	// pick a location
	var ast = worldScripts.GalCopBB_AsteroidFields.$systemHasAsteroidField(destSysInfo.ID);
	if (ast == null) {
		result["locationType"] = Math.floor(Math.random() * this._maxLocations);
	} else {
		result["locationType"] = ast.locationType;
	}

	// don't make missions greater than the player's cargo capacity
	var max = (player.ship.cargoSpaceCapacity > 20 ? 20 : player.ship.cargoSpaceCapacity);

	result["quantity"] = parseInt((Math.random() * max) + 1);
	// don't add this mission if the quantity is 5 or less
	if (result.quantity <= 5) return null;

	// pick a valuable commodity (higher chances for gold/platinum/gems)
	var p_metals = ["gold", "platinum", "gem_stones", "luxuries", "computers", "gold", "platinum", "gem_stones"];
	result["commodity"] = p_metals[Math.floor(Math.random() * p_metals.length)];
	var c_price = system.mainStation.market[result.commodity].price / 10;
	var base_price = result.quantity * (c_price * 1.05);
	//(result.quantity * (parseInt(Math.random() * 40) + 20))
	// price is now based on the market value for the commodity
	// so player won't be (well, shouldn't be) tempted to sell cargo for a better profit
	result["price"] = parseInt(base_price / 10) * 10 + (7 - destSysInfo.government) * 50 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(200); // plus a possible bonus price, based on player score 

	result["expiry"] = clock.adjustedSeconds + routeTime + workTime; // transit time + 1 hour to complete
	result["penalty"] = parseInt(result.price / 5);
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 7 - recover cargo (pirate)
this.$missionType7_Values = function $missionType7_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	// pick a location
	result["locationType"] = Math.floor(Math.random() * this._maxLocations);
	// don't make missions greater than the player's cargo capacity
	var max = (player.ship.cargoSpaceCapacity > 20 ? 20 : player.ship.cargoSpaceCapacity);

	result["quantity"] = parseInt((Math.random() * max) + 1);
	// don't add this mission if the quantity is 5 or less
	if (result.quantity <= 5) return null;

	// pick a valuable commodity (higher chances for gold/platinum/gems)
	var p_metals = ["gold", "platinum", "gem_stones", "luxuries", "computers", "gold", "platinum", "gem_stones"];
	result["commodity"] = p_metals[Math.floor(Math.random() * p_metals.length)];
	var c_price = system.mainStation.market[result.commodity].price / 10;
	var base_price = result.quantity * (c_price * 1.2);
	//(result.quantity * (parseInt(Math.random() * 80) + 20))
	// price is now based on the market value for the commodity
	// so player won't be (well, shouldn't be) tempted to sell cargo for a better profit
	result["price"] = parseInt(base_price / 10) * 10 + (7 - destSysInfo.government) * 50 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 

	result["expiry"] = clock.adjustedSeconds + routeTime + workTime; // transit time + 1 hour to complete
	result["penalty"] = parseInt(result.price / 5);
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 8 - piracy for any cargo (local gov)
this.$missionType8_Values = function $missionType8_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 30; //player.ship.cargoSpaceCapacity;
	//if (max > 30) max = 30;
	var min = 5;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 50) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 60 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + workTime; // transit time + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 9 - piracy for any cargo (pirate)
this.$missionType9_Values = function $missionType9_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 30; //player.ship.cargoSpaceCapacity;
	//if (max > 30) max = 30;
	var min = 5;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 80) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 70 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(800); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + workTime; // transit time + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 10 - piracy for specific cargo (local gov)
this.$missionType10_Values = function $missionType10_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 20; //player.ship.cargoSpaceCapacity;
	//if (max > 8) max = 8;
	var min = 3;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	var priceAdj = 1.15; // look for prices 15% higher than average
	var c_types = ["luxuries", "computers", "furs", "liquor_wines", "alloys", "radioactives", "minerals", "alien_items", "machinery"];
	var selcargo = "";
	var tries = 0; // we'll try a few times to find a commodity that ships will want to be bringing in
	do {
		selcargo = c_types[Math.floor(Math.random() * c_types.length)];
		tries += 1;
	} while ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj) && tries < 5);

	if ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj)) {
		if (this._debug) log(this.name, "commodity selection for destination has lower than average prices (" + selcargo + ")");
		return null;
	}
	result["commodity"] = selcargo;
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 50) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 80 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + (result.quantity * 1800) + 21600; // transit time + 30 mins per t + 6 hours to complete (cargo is sometimes hard to find...)
	result["penalty"] = parseInt(result.price / 4);

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 11 - piracy for specific cargo (pirate)
this.$missionType11_Values = function $missionType11_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 20; //player.ship.cargoSpaceCapacity;
	//if (max > 8) max = 8;
	var min = 3;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	var priceAdj = 1.15; // look for prices 15% higher than average
	var c_types = ["luxuries", "computers", "furs", "liquor_wines", "alloys", "radioactives", "minerals", "alien_items", "machinery"];
	var selcargo = "";
	var tries = 0; // we'll try a few times to find a commodity that ships will want to be bringing in
	do {
		selcargo = c_types[Math.floor(Math.random() * c_types.length)];
		tries += 1;
	} while ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj) && tries < 5);

	if ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj)) {
		if (this._debug) log(this.name, "commodity selection for destination has lower than average prices (" + selcargo + ")");
		return null;
	}
	result["commodity"] = selcargo;
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 80) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 100 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(800); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + (result.quantity * 1800) + 21600; // transit time + 30 mins per t + 6 hours to complete (cargo is sometimes hard to find...)
	result["penalty"] = parseInt(result.price / 3);

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 12 - free the slaves
this.$missionType12_Values = function $missionType12_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = player.ship.cargoSpaceCapacity;
	if (max > 8) max = 8;
	var min = 3;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	var priceAdj = 1.3 // look for prices 15% higher than average
	var selcargo = "slaves";
	if ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj)) {
		if (this._debug) log(this.name, "commodity selection for destination has lower than average prices (" + selcargo + ")");
		return null;
	}
	result["commodity"] = selcargo;
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 50) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 80 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + (result.quantity * 1800) + 21600; // transit time + 30 mins per t + 6 hours to complete (cargo is sometimes hard to find...)
	result["penalty"] = parseInt(result.price / 4);

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 13 - collect thargoid wreckage
this.$missionType13_Values = function $missionType13_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	// make sure we don't create missions where the quantity of cargo is more than the player ship
	var max = 20;
	player.ship.cargoSpaceCapacity;
	//if (max > 20) max = 20;
	var min = 5;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["commodity"] = "alloys";
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 100) + 150)) / 10) * 10 +
		this.$calcPlayerBonus(1000); // plus a possible bonus price, based on player score 
	// max time for longest jump is around 48 hours
	// changed to "no expiry" as it's hard enough just getting into and out of interstellar space, without adding a time limit on it
	result["expiry"] = -1; //clock.adjustedSeconds + (result.quantity * 1800) + 86400 + (workTime * 3); // 30 mins per wreckage item + 24 hrs transit time + some work time
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 14 - gun runner
this.$missionType14_Values = function $missionType14_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 20; //player.ship.cargoSpaceCapacity;
	//if (max > 8) max = 8;
	var min = 3;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	var priceAdj = 1.3 // look for prices 15% higher than average
	var selcargo = "firearms";

	if ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj)) {
		if (this._debug) log(this.name, "commodity selection for destination has lower than average prices (" + selcargo + ")");
		return null;
	}
	result["commodity"] = selcargo;
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 50) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 80 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + (result.quantity * 1800) + 21600; // transit time + 30 mins per t + 6 hours to complete (cargo is sometimes hard to find...)
	result["penalty"] = parseInt(result.price / 4);

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 15 - drug runner
this.$missionType15_Values = function $missionType15_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = 20; //player.ship.cargoSpaceCapacity;
	//if (max > 8) max = 8;
	var min = 3;
	if (min > player.ship.cargoSpaceCapacity) min = 1;
	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	var priceAdj = 1.3 // look for prices 15% higher than average
	var selcargo = "narcotics";

	if ((destSysInfo.samplePrice(selcargo) / 10) < (this._commodityAverage[selcargo] * priceAdj)) {
		if (this._debug) log(this.name, "commodity selection for destination has lower than average prices (" + selcargo + ")");
		return null;
	}
	result["commodity"] = selcargo;
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 50) + 50)) / 10) * 10 + (7 - destSysInfo.government) * 80 +
		this.$calcDistanceBonus(routeDistance, 10) // plus a distance bonus
		+
		this.$calcPlayerBonus(400); // plus a possible bonus price, based on player score 
	result["expiry"] = -1; //clock.adjustedSeconds + routeTime + (result.quantity * 1800) + 21600; // transit time + 30 mins per t + 6 hours to complete (cargo is sometimes hard to find...)
	result["penalty"] = parseInt(result.price / 4);

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 16 - civil unrest
this.$missionType16_Values = function $missionType16_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 7) + 3);
	result["price"] = parseInt((result.quantity * (parseInt(Math.random() * 500) + 550)) / 10) * 10 +
		this.$calcPlayerBonus(2000); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + (result.quantity * 600) + workTime; // 10 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 17 - garbage scow
this.$missionType17_Values = function $missionType17_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	var max = player.ship.cargoSpaceCapacity;
	if (max > 30) max = 30;
	if (max > system.mainStation.market["radioactives"].quantity) max = system.mainStation.market["radioactives"].quantity;
	var min = 5;
	if (min > player.ship.cargoSpaceCapacity) min = 1;

	result["quantity"] = parseInt(Math.random() * (max - min) + min);
	result["commodity"] = "radioactives";
	// price is related to main station's price for radioactives, plus a bit to make it worth the player's while (rather than just reselling the radioactives).
	result["price"] = (result.quantity * (system.mainStation.market[result.commodity].price / 10 + 5)) +
		this.$calcPlayerBonus(200); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + workTime + (result.quantity * 60); // 1 hour + 1 minutes per canister to complete.
	result["deposit"] = result.quantity * (system.mainStation.market[result.commodity].price / 10);
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 18 - pirate hunt (pirate authority)
this.$missionType18_Values = function $missionType18_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = parseInt((Math.random() * 10) + 8);
	// base the reward rate on danger level in the target system
	var amt = parseInt((result.quantity * (parseInt(Math.random() * ((4 - destSysInfo.government) * 75)) + 50)) / 10) * 10 +
		this.$calcPlayerBonus(500); // plus a possible bonus price, based on player score 
	// occasionally double the price
	if (Math.random() > 0.95 && destSysInfo.government < 2) amt *= 2;
	result["price"] = amt;
	result["expiry"] = clock.adjustedSeconds + routeTime + (result.quantity * 600) + workTime; // transit time + 10 mins per ship + 1 hour to complete
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// calculates a bonus price based on the players score
this.$calcPlayerBonus = function $calcPlayerBonus(maxVal) {
	var amt = 0;
	amt = ((player.score / 6000) > Math.random() ? parseInt((parseInt(Math.random() * (maxVal / 2)) + (maxVal / 2)) / 10) * 10 : 0);
	if (amt > maxVal) amt = maxVal;
	if (amt < 0) amt = 0;
	var hs = worldScripts.HomeSystem;
	if (hs) {
		// is this a home system
		if (hs.$isHomeSystem(system.ID) === true && hs.$checkLevel(system.ID, "missions") === true) {
			//var rep = parseInt(hs._dockCounts[galaxyNumber][system.ID]);
			if (amt === 0) amt = 100; // make sure we have some amount to work with;
			var pct = 1.1;
			if (hs.$checkLevel(system.ID, "missions_2") === true) pct = 1.2;
			amt = amt * pct;
		}
	}
	return Math.floor(amt);
}

//-------------------------------------------------------------------------------------------------------------
// calculates a bonus price based on the distance to the destination
// at the moment this is a very simple calc, but in future releases it may become more complex
this.$calcDistanceBonus = function $calcDistanceBonus(distance, factor) {
	var amt = parseInt(distance) * factor;
	return Math.floor(amt);
}