-- 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; /* * Planet resources type * * This type is used to transmit a planet's resources information to the game * server. It contains the resource's description, the planet's economic data * and, if there is a resource provider on the planet, the provider's * information and mining priority. */ DROP TYPE IF EXISTS emp.planet_resources_type CASCADE; CREATE TYPE emp.planet_resources_type AS ( /* Text identifier of the resource */ resource_identifier TEXT , /* Internationalised name of the resource */ resource_name TEXT , /* Internationalised description of the resource */ resource_description TEXT , /* Internationalised name of the category the resource is a part of, or * NULL if the resource is not in any category. */ resource_category TEXT , /* The planet's income for this resource, over a period of 12h RT/ 1 month * GT. */ pres_income BIGINT , /* The planet's upkeep for this resource, over a period of 12h RT/ 1 month * GT. */ pres_upkeep BIGINT , /* The current quantity of this resource invested in the planet's build * queues. */ pres_invested BIGINT , /** The capacity of the resource provider, if there is one, or NULL if * there is no provider. */ resprov_capacity BIGINT , /** The quantity of resources in the resource provider, if there is one, * or NULL if there is no provider. */ resprov_quantity BIGINT , /** The extraction difficulty of the resource provider as a percentage, or * NULL if there is no provider. */ resprov_difficulty INT , /* The mining priority for the resource in question, or NULL if there is no * resource provider. */ mset_weight INT ); /* * Access all available information about a planet's resources * * This function retrieves resource information about an empire-owned planet, * and converts it to the format used in the game server (rounded quantities, * difficulty as percentage, internationalised strings). * * FIXME: * 1) pres_invested is always set to 0 in the output * 2) time-related computations use hardcoded values * * Parameters: * _planet The planet's identifier * * Returns: * N/A Resource information records, ordered using resource * weights. */ DROP FUNCTION IF EXISTS emp.get_planet_resources( INT ); CREATE FUNCTION emp.get_planet_resources( _planet INT ) RETURNS SETOF emp.planet_resources_type STRICT STABLE SECURITY DEFINER AS $get_planet_resources$ SELECT _name_str.name AS resource_identifier , _name_trans.translated_string AS resource_name , _desc_trans.translated_string AS resource_description , _cat_trans.translated_string AS resource_category , FLOOR( pres_income * 720.0 )::BIGINT AS pres_income , CEIL( pres_upkeep * 720.0 )::BIGINT AS pres_upkeep , 0::BIGINT AS pres_invested , ROUND( resprov_quantity_max )::BIGINT AS resprov_capacity , ROUND( resprov_quantity )::BIGINT AS resprov_quantity , ROUND( 100.0 * resprov_difficulty )::INT AS resprov_difficulty , mset_weight FROM defs.ordered_resources_view INNER JOIN verse.planet_resources USING ( resource_name_id ) INNER JOIN emp.planets USING ( planet_id ) INNER JOIN naming.empire_names _emp_name ON _emp_name.id = empire_id INNER JOIN users.credentials _user ON _emp_name.owner_id = _user.address_id INNER JOIN defs.strings _name_str ON _name_str.id = resource_name_id INNER JOIN defs.translations _name_trans ON _name_trans.string_id = resource_name_id AND _name_trans.lang_id = _user.language_id INNER JOIN defs.translations _desc_trans ON _desc_trans.string_id = resource_description_id AND _desc_trans.lang_id = _user.language_id LEFT OUTER JOIN defs.translations _cat_trans ON _cat_trans.string_id = resource_category_id AND _cat_trans.lang_id = _user.language_id LEFT OUTER JOIN verse.resource_providers USING ( planet_id , resource_name_id ) LEFT OUTER JOIN emp.mining_settings_view USING ( planet_id , resource_name_id ) WHERE planet_id = $1 ORDER BY resource_ordering; $get_planet_resources$ LANGUAGE SQL; REVOKE EXECUTE ON FUNCTION emp.get_planet_resources( INT ) FROM PUBLIC; GRANT EXECUTE ON FUNCTION emp.get_planet_resources( INT ) TO :dbuser;