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/tests/admin/040-functions/145-resource-providers
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Test emp.scaled_mining_weights_view
|
||||
*/
|
||||
BEGIN;
|
||||
/* Create a table which will server as an alternate source for
|
||||
* emp.mining_settings_view ; the table is not temporary (PostgreSQL
|
||||
* won't allow replacing the view otherwise), but will be dropped
|
||||
* on rollback anyway.
|
||||
*/
|
||||
CREATE TABLE fake_mining_settings(
|
||||
planet_id INT ,
|
||||
resource_name_id INT ,
|
||||
mset_weight INT ,
|
||||
mset_specific BOOLEAN
|
||||
);
|
||||
|
||||
CREATE OR REPLACE VIEW emp.mining_settings_view
|
||||
AS SELECT * FROM fake_mining_settings;
|
||||
|
||||
/* Insert fake records for each possible mining setting */
|
||||
INSERT INTO fake_mining_settings VALUES
|
||||
( 1 , 0 , 0 , FALSE ) ,
|
||||
( 1 , 1 , 1 , FALSE ) ,
|
||||
( 1 , 2 , 2 , FALSE ) ,
|
||||
( 1 , 3 , 3 , FALSE ) ,
|
||||
( 1 , 4 , 4 , FALSE );
|
||||
|
||||
/***** TESTS BEGIN HERE *****/
|
||||
SELECT plan( 2 );
|
||||
|
||||
SELECT diag_test_name( 'emp.scaled_mining_weights_view - Rows present' );
|
||||
SELECT isnt( COUNT(*)::INT , 0 )
|
||||
FROM emp.scaled_mining_weights_view;
|
||||
|
||||
SELECT diag_test_name( 'emp.scaled_mining_weights_view - weight = game.resources.weightBase ^ setting' );
|
||||
SELECT sys.uoc_constant( 'game.resources.weightBase' , '(test)' , 'Resources' , 10.0 );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM emp.scaled_mining_weights_view
|
||||
WHERE pmc_weight IS NULL
|
||||
OR pmc_weight <> POW( 10 , resource_name_id )
|
||||
$$ );
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Test emp.total_mining_weights_view
|
||||
*/
|
||||
BEGIN;
|
||||
/* Create a table which will server as an alternate source for
|
||||
* emp.scaled_mining_weights_view ; the table is not temporary (PostgreSQL
|
||||
* won't allow replacing the view otherwise), but will be dropped
|
||||
* on rollback anyway.
|
||||
*/
|
||||
CREATE TABLE fake_mining_weights(
|
||||
planet_id INT ,
|
||||
resource_name_id INT ,
|
||||
pmc_weight DOUBLE PRECISION
|
||||
);
|
||||
|
||||
CREATE OR REPLACE VIEW emp.scaled_mining_weights_view
|
||||
AS SELECT * FROM fake_mining_weights;
|
||||
|
||||
/* Insert fake records for two different planets */
|
||||
INSERT INTO fake_mining_weights VALUES
|
||||
( 1 , 0 , 1 ) ,
|
||||
( 1 , 1 , 2 ) ,
|
||||
( 2 , 0 , 4 ) ,
|
||||
( 2 , 1 , 5 );
|
||||
|
||||
/***** TESTS BEGIN HERE *****/
|
||||
SELECT plan( 1 );
|
||||
|
||||
SELECT set_eq(
|
||||
$$ SELECT * FROM emp.total_mining_weights_view $$ ,
|
||||
$$ VALUES ( 1 , 3.0 ) , ( 2 , 9.0 ) $$
|
||||
);
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Test the emp.mining_compute_extraction() function
|
||||
*/
|
||||
BEGIN;
|
||||
|
||||
/* Define the necessary constant */
|
||||
SELECT sys.uoc_constant( 'game.resources.extraction' , '(test)' , 'Resources' , 10 );
|
||||
SELECT sys.uoc_constant( 'game.happiness.strike' , '(test)' , 'Resources' , 0.5 );
|
||||
|
||||
/* Make sure the functions are not immutable during the tests */
|
||||
ALTER FUNCTION sys.get_constant( TEXT ) VOLATILE;
|
||||
ALTER FUNCTION emp.mining_compute_extraction( emp.planet_mining_type ) VOLATILE;
|
||||
|
||||
/* Replace verse.get_raw_production() with a function that returns a
|
||||
* value from a "temporary" table.
|
||||
*/
|
||||
CREATE TABLE fake_mining_production( production REAL );
|
||||
CREATE OR REPLACE FUNCTION verse.get_raw_production( pid INT , pt building_output_type )
|
||||
RETURNS REAL LANGUAGE SQL VOLATILE AS 'SELECT production FROM fake_mining_production';
|
||||
INSERT INTO fake_mining_production VALUES ( 100 );
|
||||
|
||||
/* Create a table that is used as the input for tests */
|
||||
CREATE TABLE tests_input OF emp.planet_mining_type;
|
||||
|
||||
-- ***** TESTS BEGIN HERE *****
|
||||
SELECT plan( 9 );
|
||||
|
||||
INSERT INTO tests_input VALUES
|
||||
( 0 , 0 , 1000 , 1000 , 0 , NULL , NULL , NULL , NULL ) ,
|
||||
( 1 , 1 , 10000 , 10000 , 0 , NULL , NULL , NULL , NULL ) ,
|
||||
( 2 , 2 , 100000 , 100000 , 0 , NULL , NULL , NULL , NULL );
|
||||
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - No empire -> no extraction' );
|
||||
SELECT is_empty( $$
|
||||
SELECT *
|
||||
FROM tests_input
|
||||
WHERE emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) )
|
||||
<> 0 $$ );
|
||||
|
||||
DELETE FROM tests_input;
|
||||
INSERT INTO tests_input VALUES
|
||||
( 0 , 0 , 1000 , 1000 , 0 , 1 , 1 , 1 , 1 ) ,
|
||||
( 1 , 1 , 10000 , 10000 , 0 , 1 , 1 , 1 , 1 ) ,
|
||||
( 2 , 2 , 100000 , 100000 , 0 , 1 , 1 , 1 , 1 );
|
||||
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Extracted quantity > 0 if empire and resources are present' );
|
||||
SELECT is_empty( $$
|
||||
SELECT *
|
||||
FROM tests_input
|
||||
WHERE emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) )
|
||||
= 0 $$ );
|
||||
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Extracted quantity does not change for same initial ratio' );
|
||||
SELECT is( COUNT( DISTINCT emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) )
|
||||
)::INT , 1 ) FROM tests_input;
|
||||
|
||||
UPDATE tests_input SET weight = 1 + planet , total_weight = 3;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Result increases when weight/total weight ratio increases' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT rank() OVER ( ORDER BY weight ) AS r1 ,
|
||||
rank() OVER( ORDER BY emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) ) ) AS r2
|
||||
FROM tests_input $$ ,
|
||||
$$ VALUES ( 1 , 1 ) , ( 2 , 2 ) , ( 3 , 3 ) $$
|
||||
);
|
||||
|
||||
UPDATE tests_input SET weight = total_weight , happiness = 0.5 + 0.25 * planet;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Happiness does not affect result when greater than strike level' );
|
||||
SELECT is( COUNT( DISTINCT emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) )
|
||||
)::INT , 1 ) FROM tests_input;
|
||||
|
||||
UPDATE tests_input SET weight = total_weight , happiness = 0.2 * planet;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Result increases with happiness when lower than strike level' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT rank() OVER ( ORDER BY happiness ) AS r1 ,
|
||||
rank() OVER( ORDER BY emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) ) ) AS r2
|
||||
FROM tests_input $$ ,
|
||||
$$ VALUES ( 1 , 1 ) , ( 2 , 2 ) , ( 3 , 3 ) $$
|
||||
);
|
||||
|
||||
UPDATE fake_mining_production SET production = 10000;
|
||||
UPDATE tests_input SET quantity = 1 , quantity_max = 1 , happiness = 1;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Result <= quantity' );
|
||||
SELECT is_empty(
|
||||
$$ SELECT * FROM tests_input
|
||||
WHERE quantity < emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) ) $$
|
||||
);
|
||||
|
||||
UPDATE fake_mining_production SET production = 1;
|
||||
UPDATE tests_input SET quantity = 100 * planet , quantity_max = 200;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Result decreases when quantity/capacity ratio decreases' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT rank() OVER ( ORDER BY quantity ) AS r1 ,
|
||||
rank() OVER( ORDER BY emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) ) ) AS r2
|
||||
FROM tests_input $$ ,
|
||||
$$ VALUES ( 1 , 1 ) , ( 2 , 2 ) , ( 3 , 3 ) $$
|
||||
);
|
||||
|
||||
UPDATE tests_input SET quantity = quantity_max , difficulty = 0.33 * planet;
|
||||
SELECT diag_test_name( 'emp.mining_compute_extraction() - Result decreases when difficulty increases' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT rank() OVER ( ORDER BY difficulty DESC ) AS r1 ,
|
||||
rank() OVER( ORDER BY emp.mining_compute_extraction( ROW(
|
||||
planet , resource , quantity , quantity_max ,
|
||||
difficulty , empire , happiness , weight ,
|
||||
total_weight ) ) ) AS r2
|
||||
FROM tests_input $$ ,
|
||||
$$ VALUES ( 1 , 1 ) , ( 2 , 2 ) , ( 3 , 3 ) $$
|
||||
);
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Tests for the verse.mining_get_input() function
|
||||
*/
|
||||
BEGIN;
|
||||
\i utils/common-setup/setup-gu-pmc-get-data-test.sql
|
||||
|
||||
SELECT plan( 9 );
|
||||
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Neutral planet without resource providers -> no rows' );
|
||||
SELECT is_empty( $$ SELECT * FROM verse.mining_get_input( _get_map_name( 'planet1' ) ) $$ );
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM verse.mining_get_input( _get_map_name( 'planet2' ) );
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Neutral planet with resource providers - Rows included' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet2' )
|
||||
AND difficulty = 0.2 AND empire IS NULL
|
||||
AND happiness IS NULL AND weight IS NULL
|
||||
AND total_weight IS NULL;
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Neutral planet with resource providers - No extra rows' );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM test_results
|
||||
WHERE NOT ( planet = _get_map_name ( 'planet2' )
|
||||
AND difficulty = 0.2 AND empire IS NULL
|
||||
AND happiness IS NULL AND weight IS NULL
|
||||
AND total_weight IS NULL );
|
||||
$$ );
|
||||
DROP TABLE test_results;
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM verse.mining_get_input( _get_map_name( 'planet3' ) );
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Planet using empire settings - Rows included' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet3' ) AND difficulty = 0.3
|
||||
AND empire = _get_emp_name( 'empire1' )
|
||||
AND happiness IS NOT NULL AND weight = 100
|
||||
AND total_weight = 200;
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Planet using empire settings - No extra rows' );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM test_results
|
||||
WHERE NOT ( planet = _get_map_name ( 'planet3' )
|
||||
AND difficulty = 0.3
|
||||
AND empire = _get_emp_name( 'empire1' )
|
||||
AND happiness IS NOT NULL
|
||||
AND weight = 100 AND total_weight = 200 );
|
||||
$$ );
|
||||
DROP TABLE test_results;
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM verse.mining_get_input( _get_map_name( 'planet4' ) );
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Planet using specific settings - Rows included' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet4' ) AND difficulty = 0.4
|
||||
AND empire = _get_emp_name( 'empire2' )
|
||||
AND happiness IS NOT NULL AND (
|
||||
( resource = _get_string( 'resource1' ) AND weight = 10 )
|
||||
OR ( resource = _get_string( 'resource2' ) AND weight = 1000 ) )
|
||||
AND total_weight = 1010;
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Planet using specific settings - No extra rows' );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM test_results
|
||||
WHERE NOT ( planet = _get_map_name ( 'planet4' )
|
||||
AND difficulty = 0.4 AND empire = _get_emp_name( 'empire2' )
|
||||
AND happiness IS NOT NULL AND total_weight = 1010
|
||||
AND ( ( resource = _get_string( 'resource1' ) AND weight = 10 )
|
||||
OR ( resource = _get_string( 'resource2' ) AND weight = 1000 ) ) );
|
||||
$$ );
|
||||
DROP TABLE test_results;
|
||||
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Owned planet without resource providers -> no rows' );
|
||||
SELECT is_empty( $$ SELECT * FROM verse.mining_get_input( _get_map_name( 'planet5' ) ) $$ );
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM verse.mining_get_input( _get_map_name( 'planet6' ) );
|
||||
SELECT diag_test_name( 'verse.mining_get_input() - Selects planets independently of update state' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet6' ) AND difficulty = 0.6
|
||||
AND empire = _get_emp_name( 'empire4' )
|
||||
AND happiness IS NOT NULL AND weight = 100
|
||||
AND total_weight = 200;
|
||||
DROP TABLE test_results;
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Tests for the emp.mining_get_input() function
|
||||
*/
|
||||
BEGIN;
|
||||
\i utils/common-setup/setup-gu-pmc-get-data-test.sql
|
||||
|
||||
SELECT plan( 7 );
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM emp.mining_get_input( _get_emp_name( 'empire1' ) );
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Empire with a planet using empire settings - Rows included' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet3' ) AND difficulty = 0.3
|
||||
AND empire = _get_emp_name( 'empire1' )
|
||||
AND happiness IS NOT NULL AND weight = 100
|
||||
AND total_weight = 200;
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Empire with a planet using empire settings - No extra rows' );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM test_results
|
||||
WHERE NOT ( planet = _get_map_name ( 'planet3' )
|
||||
AND difficulty = 0.3
|
||||
AND empire = _get_emp_name( 'empire1' )
|
||||
AND happiness IS NOT NULL
|
||||
AND weight = 100 AND total_weight = 200 );
|
||||
$$ );
|
||||
DROP TABLE test_results;
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM emp.mining_get_input( _get_emp_name( 'empire2' ) );
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Empire with a planet using specific settings - Rows included' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet4' ) AND difficulty = 0.4
|
||||
AND empire = _get_emp_name( 'empire2' )
|
||||
AND happiness IS NOT NULL AND (
|
||||
( resource = _get_string( 'resource1' ) AND weight = 10 )
|
||||
OR ( resource = _get_string( 'resource2' ) AND weight = 1000 ) )
|
||||
AND total_weight = 1010;
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Empire with a planet using specific settings - No extra rows' );
|
||||
SELECT is_empty( $$
|
||||
SELECT * FROM test_results
|
||||
WHERE NOT ( planet = _get_map_name ( 'planet4' )
|
||||
AND difficulty = 0.4 AND empire = _get_emp_name( 'empire2' )
|
||||
AND happiness IS NOT NULL AND total_weight = 1010
|
||||
AND ( ( resource = _get_string( 'resource1' ) AND weight = 10 )
|
||||
OR ( resource = _get_string( 'resource2' ) AND weight = 1000 ) ) );
|
||||
$$ );
|
||||
DROP TABLE test_results;
|
||||
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Owned planet without resource providers -> no rows' );
|
||||
SELECT is_empty( $$ SELECT * FROM emp.mining_get_input( _get_emp_name( 'empire3' ) ) $$ );
|
||||
|
||||
CREATE TEMPORARY TABLE test_results
|
||||
AS SELECT * FROM emp.mining_get_input( _get_emp_name( 'empire4' ) );
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Selects planets independently of update state' );
|
||||
SELECT is( COUNT(*)::INT , 2)
|
||||
FROM test_results
|
||||
WHERE planet = _get_map_name ( 'planet6' ) AND difficulty = 0.6
|
||||
AND empire = _get_emp_name( 'empire4' )
|
||||
AND happiness IS NOT NULL AND weight = 100
|
||||
AND total_weight = 200;
|
||||
DROP TABLE test_results;
|
||||
|
||||
SELECT diag_test_name( 'emp.mining_get_input() - Empire with no planets -> no rows' );
|
||||
SELECT is_empty( $$ SELECT * FROM emp.mining_get_input( _get_emp_name( 'empire5' ) ) $$ );
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
Reference in a new issue