Extracted quantities update as soon as possible
* The quantities of resources extracted from mines will now be updated as soon as they have a reason to. This includes planet assignment, abandonment, ownership changes, and updates to mining priorities. * The mining update will now remove the current resource income from the providers, and only then re-compute all extracted quantities. This is more logical and corresponds to the way the other game updates work. * Fixed bug in extraction computation where the size of the planet's happy population was used instead of the happy/total ratio when adjusting the mining production for riots. * The following SQL scripts must be re-executed to upgrade a database: -> 040-functions/040-empire.sql -> 040-functions/145-resource-providers.sql -> 040-functions/147-empire-mining.sql -> 050-updates/120-planet-mining.sql
This commit is contained in:
parent
f3aa563758
commit
bf6bea5a79
35 changed files with 863 additions and 372 deletions
legacyworlds-server-data/db-structure/parts/050-updates
|
@ -7,87 +7,6 @@
|
|||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* Mining computation weights view
|
||||
* --------------------------------
|
||||
*
|
||||
* This view computes the actual values used in the mining computations for
|
||||
* each resource provider on all empire-owned planets.
|
||||
*
|
||||
* Columns:
|
||||
* planet_id The planet's identifier
|
||||
* resource_name_id The resource type's identifier
|
||||
* pmc_weight The computed weight
|
||||
*/
|
||||
DROP VIEW IF EXISTS sys.gu_pmc_weights_view CASCADE;
|
||||
CREATE VIEW sys.gu_pmc_weights_view
|
||||
AS SELECT planet_id , resource_name_id ,
|
||||
POW( sys.get_constant( 'game.resources.weightBase' ) ,
|
||||
mset_weight ) AS pmc_weight
|
||||
FROM emp.mining_settings_view;
|
||||
|
||||
|
||||
/*
|
||||
* Mining computation - total weights view
|
||||
* ----------------------------------------
|
||||
*
|
||||
* This view computes per-planet totals for actual mining weights.
|
||||
*
|
||||
* Columns:
|
||||
* planet_id The planet's identifier
|
||||
* pmc_total The sum of all mining weights on the planet.
|
||||
*/
|
||||
DROP VIEW IF EXISTS sys.gu_pmc_totals_view CASCADE;
|
||||
CREATE VIEW sys.gu_pmc_totals_view
|
||||
AS SELECT planet_id , SUM( pmc_weight ) AS pmc_total
|
||||
FROM sys.gu_pmc_weights_view
|
||||
GROUP BY planet_id;
|
||||
|
||||
|
||||
/*
|
||||
* Planet mining update data
|
||||
* --------------------------
|
||||
*
|
||||
* This type is used by the records used by planet mining updates to compute a
|
||||
* planet's mining output.
|
||||
*/
|
||||
DROP TYPE IF EXISTS sys.gu_pmc_data_type CASCADE;
|
||||
CREATE TYPE sys.gu_pmc_data_type AS (
|
||||
/* The planet's identifier */
|
||||
planet INT ,
|
||||
|
||||
/* The resource's identifier */
|
||||
resource INT ,
|
||||
|
||||
/* The provider's quantity of resources */
|
||||
quantity DOUBLE PRECISION ,
|
||||
|
||||
/* The provider's maximal quantity of resources */
|
||||
quantity_max DOUBLE PRECISION ,
|
||||
|
||||
/* The provider's extraction difficulty */
|
||||
difficulty DOUBLE PRECISION ,
|
||||
|
||||
/* The empire who owns the planet, or NULL if the planet is neutral */
|
||||
empire INT ,
|
||||
|
||||
/* The planet's happiness, or NULL if the planet is neutral */
|
||||
happiness REAL ,
|
||||
|
||||
/* The weight computed from the resource's extraction priority as
|
||||
* set by either the empire in general or the planet-specific settings,
|
||||
* or NULL if the planet is neutral.
|
||||
*/
|
||||
weight DOUBLE PRECISION ,
|
||||
|
||||
/* The total weight computed from either the empire-wide or the
|
||||
* planet-specific mining settings, or NULL if the planet is neutral.
|
||||
*/
|
||||
total_weight DOUBLE PRECISION
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Lock the rows and access the data used by the mining update
|
||||
*
|
||||
|
@ -105,14 +24,14 @@ CREATE TYPE sys.gu_pmc_data_type AS (
|
|||
* planet-specific settings for one of the planets we're inspecting,
|
||||
* are locked for share.
|
||||
*
|
||||
* The data itself is returned as a set of rows using sys.gu_pmc_data_type
|
||||
* The data itself is returned as a set of rows using emp.planet_mining_type
|
||||
*
|
||||
* Parameters:
|
||||
* _tick The identifier of the current game update
|
||||
*/
|
||||
DROP FUNCTION IF EXISTS sys.gu_pmc_get_data( BIGINT );
|
||||
CREATE FUNCTION sys.gu_pmc_get_data( _tick BIGINT )
|
||||
RETURNS SETOF sys.gu_pmc_data_type
|
||||
RETURNS SETOF emp.planet_mining_type
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $gu_pmc_get_data$
|
||||
|
@ -122,7 +41,7 @@ AS $gu_pmc_get_data$
|
|||
resprov_quantity_max AS quantity_max ,
|
||||
resprov_difficulty AS difficulty ,
|
||||
empire_id AS empire ,
|
||||
happiness ,
|
||||
( happy_pop / _planet.population ) AS happiness ,
|
||||
pmc_weight AS weight ,
|
||||
pmc_total AS total_weight
|
||||
|
||||
|
@ -137,8 +56,8 @@ AS $gu_pmc_get_data$
|
|||
USING ( planet_id , resource_name_id )
|
||||
LEFT OUTER JOIN (
|
||||
SELECT _emp_planet.empire_id , _emp_planet.planet_id ,
|
||||
_emset.resource_name_id , pmc_weight ,
|
||||
pmc_total , _happ.current AS happiness
|
||||
_emset.resource_name_id , pmc_weight , pmc_total ,
|
||||
_happ.current AS happy_pop
|
||||
|
||||
FROM sys.updates _upd_sys
|
||||
INNER JOIN verse.planets_updates _upd_verse
|
||||
|
@ -151,9 +70,9 @@ AS $gu_pmc_get_data$
|
|||
USING ( empire_id )
|
||||
INNER JOIN verse.planet_happiness _happ
|
||||
USING ( planet_id )
|
||||
INNER JOIN sys.gu_pmc_weights_view
|
||||
INNER JOIN emp.scaled_mining_weights_view
|
||||
USING ( planet_id , resource_name_id)
|
||||
INNER JOIN sys.gu_pmc_totals_view
|
||||
INNER JOIN emp.total_mining_weights_view
|
||||
USING ( planet_id )
|
||||
LEFT OUTER JOIN (
|
||||
SELECT * FROM emp.planet_mining_settings
|
||||
|
@ -182,69 +101,14 @@ REVOKE EXECUTE
|
|||
|
||||
|
||||
|
||||
/*
|
||||
* Update a planet's resource provider and corresponding resource record
|
||||
*
|
||||
* This function will compute the amount of resources extracted from a
|
||||
* provider, and update both the provider itself and the corresponding
|
||||
* resource record (setting the income to whatever quantity was extracted).
|
||||
*
|
||||
* Parameters:
|
||||
* _input Data about the resource provider to update
|
||||
*/
|
||||
DROP FUNCTION IF EXISTS sys.gu_pmc_update_resource( sys.gu_pmc_data_type );
|
||||
CREATE FUNCTION sys.gu_pmc_update_resource( _input sys.gu_pmc_data_type )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $gu_pmc_update_resource$
|
||||
|
||||
DECLARE
|
||||
_extraction DOUBLE PRECISION;
|
||||
_allocation DOUBLE PRECISION;
|
||||
_production DOUBLE PRECISION;
|
||||
_quantity DOUBLE PRECISION;
|
||||
|
||||
BEGIN
|
||||
|
||||
_extraction := verse.get_extraction_factor(
|
||||
_input.quantity / _input.quantity_max ,
|
||||
_input.difficulty );
|
||||
_allocation := _input.weight / _input.total_weight;
|
||||
_production := verse.adjust_production(
|
||||
verse.get_raw_production( _input.planet , 'MINE' ) ,
|
||||
_input.happiness )
|
||||
* sys.get_constant( 'game.resources.extraction' )
|
||||
/ 1440.0; -- FIXME: hardcoded!
|
||||
|
||||
PERFORM sys.write_sql_log( 'MiningUpdate' , 'TRACE' , 'Resource #' || _input.resource
|
||||
|| ' @ planet #' || _input.planet || ': extraction ' || _extraction
|
||||
|| ', allocation ' || _allocation || ', production ' || _production );
|
||||
_quantity := _allocation * _production * _extraction;
|
||||
IF _quantity > _input.quantity THEN
|
||||
_quantity := _input.quantity;
|
||||
END IF;
|
||||
|
||||
UPDATE verse.resource_providers
|
||||
SET resprov_quantity = resprov_quantity - _quantity
|
||||
WHERE planet_id = _input.planet
|
||||
AND resource_name_id = _input.resource;
|
||||
UPDATE verse.planet_resources
|
||||
SET pres_income = _quantity
|
||||
WHERE planet_id = _input.planet
|
||||
AND resource_name_id = _input.resource;
|
||||
|
||||
END;
|
||||
$gu_pmc_update_resource$ LANGUAGE PLPGSQL;
|
||||
|
||||
REVOKE EXECUTE
|
||||
ON FUNCTION sys.gu_pmc_update_resource( sys.gu_pmc_data_type )
|
||||
FROM PUBLIC;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Planet mining game update
|
||||
* --------------------------
|
||||
*
|
||||
* Lock all records involved with the update, then update the quantity of
|
||||
* resources in resource providers depending on what was mined this turn.
|
||||
* Finally update all extraction quantities.
|
||||
*
|
||||
* Obtains all records to update for the current batch, then either set the
|
||||
* income to 0 without modifying the resource provider if the planet is
|
||||
|
@ -255,30 +119,35 @@ REVOKE EXECUTE
|
|||
*/
|
||||
DROP FUNCTION IF EXISTS sys.process_planet_mining_updates( BIGINT );
|
||||
CREATE FUNCTION sys.process_planet_mining_updates( _tick BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $process_planet_mining_updates$
|
||||
RETURNS VOID
|
||||
LANGUAGE SQL
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $process_planet_mining_updates$
|
||||
-- Lock all rows
|
||||
SELECT 1 FROM sys.gu_pmc_get_data( $1 );
|
||||
|
||||
DECLARE
|
||||
_row sys.gu_pmc_data_type;
|
||||
-- Execute the actual mining
|
||||
UPDATE verse.resource_providers _resprov
|
||||
SET resprov_quantity = resprov_quantity - _pres.pres_income
|
||||
FROM sys.updates _upd_sys
|
||||
INNER JOIN verse.planets_updates _upd_verse
|
||||
USING ( update_id , updtype_id , updtgt_id )
|
||||
INNER JOIN verse.planet_resources _pres
|
||||
ON _pres.planet_id = _upd_verse.name_id
|
||||
WHERE _upd_sys.update_last = $1
|
||||
AND _upd_sys.update_state = 'PROCESSING'
|
||||
AND _pres.planet_id = _resprov.planet_id
|
||||
AND _pres.resource_name_id = _resprov.resource_name_id;
|
||||
|
||||
BEGIN
|
||||
FOR _row IN SELECT * FROM sys.gu_pmc_get_data( _tick )
|
||||
LOOP
|
||||
IF _row.empire IS NULL THEN
|
||||
-- Set resource income to 0 on neutrals
|
||||
UPDATE verse.planet_resources
|
||||
SET pres_income = 0
|
||||
WHERE planet_id = _row.planet
|
||||
AND resource_name_id = _row.resource;
|
||||
ELSE
|
||||
PERFORM sys.gu_pmc_update_resource( _row );
|
||||
END IF;
|
||||
-- Update extraction data
|
||||
UPDATE verse.planet_resources
|
||||
SET pres_income = emp.mining_compute_extraction( _update_row )
|
||||
FROM sys.gu_pmc_get_data( $1 ) _update_row
|
||||
WHERE planet_id = _update_row.planet
|
||||
AND resource_name_id = _update_row.resource;
|
||||
|
||||
END LOOP;
|
||||
END;
|
||||
$process_planet_mining_updates$ LANGUAGE PLPGSQL;
|
||||
$process_planet_mining_updates$;
|
||||
|
||||
|
||||
REVOKE EXECUTE
|
||||
|
|
Reference in a new issue