-- LegacyWorlds Beta 6
-- PostgreSQL database scripts
--
-- Resource providers functions
--
-- Copyright(C) 2004-2012, DeepClone Development
-- --------------------------------------------------------


/*
 * Compute resource provider regeneration
 * 
 * This function computes the quantity in a resource provider after it has
 * been regenerated.
 * 
 * Parameters:
 *		_quantity		The current quantity of resources in the provider
 *		_max			The maximal amount of resources supported by the
 *							provider
 *		_recovery_rate	The provider's recovery rate
 *
 * Returns:
 *		?				The new quantity of resources.
 */
CREATE OR REPLACE FUNCTION verse.compute_provider_regeneration(
				_quantity		DOUBLE PRECISION ,
				_max			DOUBLE PRECISION ,
				_recovery_rate	DOUBLE PRECISION )
		RETURNS DOUBLE PRECISION
		STRICT IMMUTABLE
		SECURITY INVOKER
	AS $compute_provider_regeneration$

DECLARE
	_uc_recovery	DOUBLE PRECISION;
	_uc_dampening	DOUBLE PRECISION;
	_uc_ticks		DOUBLE PRECISION;
	_result			DOUBLE PRECISION;

BEGIN
	_uc_recovery := sys.get_constant( 'game.resources.recovery' );
	_uc_dampening := sys.get_constant( 'game.resources.recoveryDampening' );
	_uc_ticks := 1440; -- FIXME: this should be a constant
	
	_result := ( 1 - _quantity / _max ) ^ _uc_dampening;
	_result := _quantity + _result * _recovery_rate * _uc_recovery / _uc_ticks;

	IF _result > _max THEN
		_result := _max;
	END IF;

	RETURN _result;
END;
$compute_provider_regeneration$ LANGUAGE PLPGSQL;


REVOKE EXECUTE
	ON FUNCTION verse.compute_provider_regeneration(
		DOUBLE PRECISION , DOUBLE PRECISION ,
		DOUBLE PRECISION )
	FROM PUBLIC;



/*
 * Mining settings view
 * ---------------------
 *
 * This view lists mining settings being used on planets owned by empires
 * for each resource providers. The settings are taken from planet-specific
 * settings if they are available, or from empire-wide settings.
 * 
 * Columns:
 *
 *		planet_id			The planet's identifier
 *		resource_name_id	The type of resources
 *		mset_weight			The setting to use for mining priorities
 *		mset_specific		True if the settings are specific for this planet,
 *								false if empire-wise settings are in use. 
 */
DROP VIEW IF EXISTS emp.mining_settings_view CASCADE;
CREATE VIEW emp.mining_settings_view
	AS SELECT planet_id , resource_name_id ,
				( CASE
					WHEN _pl_settings.planet_id IS NULL THEN
						_emp_settings.empmset_weight
					ELSE
						_pl_settings.emppmset_weight
				END ) AS mset_weight ,
				( _pl_settings.planet_id IS NOT NULL ) AS mset_specific
			FROM verse.resource_providers
				INNER JOIN emp.planets
					USING ( planet_id )
				INNER JOIN emp.mining_settings _emp_settings
					USING ( empire_id , resource_name_id )
				LEFT OUTER JOIN emp.planet_mining_settings _pl_settings
					USING ( planet_id , empire_id , resource_name_id );

GRANT SELECT
	ON emp.mining_settings_view
	TO :dbuser;



/*
 * Compute a resource provider's extraction factor
 * 
 * This function computes the extraction factor - a multiplier which makes
 * mining more costly if the difficulty is high or if a provider is almost
 * empty - based on a provider's fill ratio and difficulty.
 * 
 * The complete formula can be read on the Wiki:
 *		https://wiki.legacyworlds.com/wiki/Mining#Resource_provider_extraction
 *
 * Parameters:
 * 		_fill_ratio		The ratio between the provider's current and maximal
 *							quantities
 *		_difficulty		The provider's extraction difficulty.
 *
 * Returns:
 *		?				The provider's extraction factor
 */
DROP FUNCTION IF EXISTS verse.get_extraction_factor( 
	DOUBLE PRECISION , DOUBLE PRECISION );
CREATE FUNCTION verse.get_extraction_factor(
		_fill_ratio DOUBLE PRECISION ,
		_difficulty	DOUBLE PRECISION )
	RETURNS DOUBLE PRECISION
	STRICT IMMUTABLE
	SECURITY INVOKER
AS $get_extraction_factor$

	SELECT ( 1 - $2 * 0.5 ) * POW( $1 , 1.5 + 2 * $2 );

$get_extraction_factor$ LANGUAGE SQL;

REVOKE EXECUTE
	ON FUNCTION verse.get_extraction_factor( 
		DOUBLE PRECISION , DOUBLE PRECISION )
	FROM PUBLIC;

