From 04e550709a1929a07877d609b50235dcdd939d73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@legacyworlds.com>
Date: Tue, 10 Jan 2012 13:29:56 +0100
Subject: [PATCH] Empire resources update

* Added a new update that computes the amount of resources possessed and
owed by empires. At the moment this computation ignores fleets, as their
upkeep does not use the resource system.
---
 .../parts/030-data/000-typedefs.sql           |  13 ++-
 .../050-updates/015-empire-resources.sql      |  63 +++++++++++
 .../010-process-empire-resources-updates.sql  | 101 ++++++++++++++++++
 .../010-process-empire-resources-updates.sql  |  11 ++
 4 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100644 legacyworlds-server-data/db-structure/parts/050-updates/015-empire-resources.sql
 create mode 100644 legacyworlds-server-data/db-structure/tests/admin/050-updates/015-empire-resources/010-process-empire-resources-updates.sql
 create mode 100644 legacyworlds-server-data/db-structure/tests/user/050-updates/015-empire-resources/010-process-empire-resources-updates.sql

diff --git a/legacyworlds-server-data/db-structure/parts/030-data/000-typedefs.sql b/legacyworlds-server-data/db-structure/parts/030-data/000-typedefs.sql
index edcef12..ea6934d 100644
--- a/legacyworlds-server-data/db-structure/parts/030-data/000-typedefs.sql
+++ b/legacyworlds-server-data/db-structure/parts/030-data/000-typedefs.sql
@@ -29,9 +29,18 @@ CREATE TYPE log_type
 -- Update types
 CREATE TYPE update_type	AS ENUM (
 
-	/* Empires' money is being updated using the previous update's results */
+	/* Empires' money is being updated using the previous update's results
+	 * 
+	 * FIXME: this update type should disappear, as everything it does will
+	 * be replaced by the resources update.
+	 */
 	'EMPIRE_MONEY' ,
-	
+
+	/* Empires' resources are being updated using the previous update's
+	 * results.
+	 */
+	'EMPIRE_RESOURCES' ,
+
 	/* Empire research points are being attributed to technologies */
 	'EMPIRE_RESEARCH' ,
 	
diff --git a/legacyworlds-server-data/db-structure/parts/050-updates/015-empire-resources.sql b/legacyworlds-server-data/db-structure/parts/050-updates/015-empire-resources.sql
new file mode 100644
index 0000000..89c40e2
--- /dev/null
+++ b/legacyworlds-server-data/db-structure/parts/050-updates/015-empire-resources.sql
@@ -0,0 +1,63 @@
+-- LegacyWorlds Beta 6
+-- PostgreSQL database scripts
+--
+-- Game updates - empire resources
+--
+-- Copyright(C) 2004-2012, DeepClone Development
+-- --------------------------------------------------------
+
+
+/*
+ * Empire resources update
+ * 
+ * For each empire in the update batch, compute the new amount of resources
+ * based on the upkeep and income from planets.
+ * 
+ * FIXME: this should also include fleet upkeeps. This situation will be
+ *        resolved once the system is modified to rely solely on resources.
+ * 
+ * Parameters:
+ *		_tick		The identifier of the game update
+ */
+DROP FUNCTION IF EXISTS sys.process_empire_resources_updates( BIGINT );
+CREATE FUNCTION sys.process_empire_resources_updates( _tick BIGINT )
+	RETURNS VOID
+	STRICT VOLATILE
+	SECURITY INVOKER
+AS $process_empire_resources_updates$
+
+	UPDATE emp.resources _emp_resources
+
+		SET empres_possessed = CASE
+				WHEN _emp_resources.empres_possessed + _pl_resources.pres_income - _pl_resources.pres_upkeep > 0 THEN
+					_emp_resources.empres_possessed + _pl_resources.pres_income - _pl_resources.pres_upkeep
+				ELSE
+					0
+				END ,
+			empres_owed = CASE
+				WHEN _emp_resources.empres_possessed + _pl_resources.pres_income - _pl_resources.pres_upkeep < 0 THEN
+					 _pl_resources.pres_upkeep - _emp_resources.empres_possessed - _pl_resources.pres_income 
+				ELSE
+					0
+				END
+
+		FROM sys.updates _upd_sys
+			INNER JOIN emp.updates _upd_emp
+				ON _upd_emp.update_id = _upd_sys.id
+			INNER JOIN emp.planets _emp_planets
+				USING ( empire_id )
+			INNER JOIN verse.planet_resources _pl_resources
+				USING ( planet_id )
+
+		WHERE _upd_sys.last_tick = $1
+			AND _upd_sys.status = 'PROCESSING'
+			AND _upd_sys.gu_type = 'EMPIRE_RESOURCES'
+			AND _emp_resources.empire_id = _upd_emp.empire_id
+			AND _emp_resources.resource_name_id = _pl_resources.resource_name_id;
+
+$process_empire_resources_updates$ LANGUAGE SQL;
+
+
+REVOKE EXECUTE
+	ON FUNCTION sys.process_empire_resources_updates( BIGINT )
+	FROM PUBLIC;
diff --git a/legacyworlds-server-data/db-structure/tests/admin/050-updates/015-empire-resources/010-process-empire-resources-updates.sql b/legacyworlds-server-data/db-structure/tests/admin/050-updates/015-empire-resources/010-process-empire-resources-updates.sql
new file mode 100644
index 0000000..2b4f57a
--- /dev/null
+++ b/legacyworlds-server-data/db-structure/tests/admin/050-updates/015-empire-resources/010-process-empire-resources-updates.sql
@@ -0,0 +1,101 @@
+/*
+ * Test the sys.process_empire_resources_updates() function
+ */
+BEGIN;
+	/* We need:
+	 *  - three types of resources,
+	 *  - two empire with resources records, and the corresponding update
+	 *    record,
+	 *  - two planets, set to belong to the aforementioned empires, with
+	 *    resources records attached. 
+	 */
+	\i utils/strings.sql
+	\i utils/resources.sql
+	\i utils/accounts.sql
+	\i utils/naming.sql
+	\i utils/universe.sql
+	SELECT _create_resources( 3 , 'testResource' );
+	SELECT _create_raw_planets( 2 , 'testPlanet' );
+	SELECT _create_emp_names( 2 , 'testEmp' );
+	SELECT emp.create_empire( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet1' ) , 1 );
+	INSERT INTO verse.planet_resources ( planet_id , resource_name_id )
+		SELECT _get_map_name( 'testPlanet1' ) , resource_name_id FROM defs.resources;
+	INSERT INTO verse.planet_resources ( planet_id , resource_name_id )
+		SELECT _get_map_name( 'testPlanet2' ) , resource_name_id FROM defs.resources;
+
+	/* Set up the planets' resource records so that:
+	 *	- income > upkeep for testResource1 ,
+	 *	- income < upkeep for testResource2 ,
+	 *	- income = upkeep = 0 for testResource3 ,
+	 */
+	UPDATE verse.planet_resources SET pres_income = 12
+		WHERE resource_name_id = _get_string( 'testResource1' );
+	UPDATE verse.planet_resources SET pres_upkeep = 34
+		WHERE resource_name_id = _get_string( 'testResource2' );
+
+	/* Make sure update 0 is set to be processed for testEmp1 */
+	UPDATE sys.updates
+		SET status = 'PROCESSING' , last_tick = 0;
+
+	/* Create testEmp2 empire, make sure it will not be processed */
+	SELECT emp.create_empire( _get_emp_name( 'testEmp2' ) , _get_map_name( 'testPlanet2' ) , 1 );
+	UPDATE sys.updates _su
+		SET status = 'PROCESSED' , last_tick = 0
+		FROM emp.updates _eu
+			WHERE _eu.update_id = _su.id AND _eu.empire_id = _get_emp_name( 'testEmp2' );
+
+	/****** TESTS BEGIN HERE ******/
+	SELECT plan( 19 );
+
+	SELECT sys.process_empire_resources_updates( 10 );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (1/6)' );
+	SELECT is( empres_possessed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (2/6)' );
+	SELECT is( empres_owed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (3/6)' );
+	SELECT is( empres_possessed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource2' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (4/6)' );
+	SELECT is( empres_owed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource2' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (5/6)' );
+	SELECT is( empres_possessed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource3' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Wrong update identifier (6/6)' );
+	SELECT is( empres_owed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource3' );
+
+	SELECT sys.process_empire_resources_updates( 0 );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 1 - Possessed quantity increased' );
+	SELECT is( empres_possessed , 12::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource1' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 1 - Owed quantity unchanged' );
+	SELECT is( empres_owed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource1' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 2 - Possessed quantity unchanged' );
+	SELECT is( empres_possessed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource2' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 2 - Owed quantity increased' );
+	SELECT is( empres_owed , 34::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource2' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 3 - Possessed quantity unchanged' );
+	SELECT is( empres_possessed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource3' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resource 3 - Owed quantity unchanged' );
+	SELECT is( empres_owed , 0::DOUBLE PRECISION ) FROM emp.resources
+		WHERE resource_name_id = _get_string( 'testResource3' )
+			AND empire_id = _get_emp_name( 'testEmp1' );
+	SELECT diag_test_name( 'EMPIRE_RESOURCES update - Resources unchanged for already processed empire' );
+	SELECT is( SUM( empres_owed + empres_possessed ) , 0::DOUBLE PRECISION )
+		FROM emp.resources
+		WHERE empire_id = _get_emp_name( 'testEmp2' );
+
+	SELECT * FROM finish( );
+ROLLBACK;
\ No newline at end of file
diff --git a/legacyworlds-server-data/db-structure/tests/user/050-updates/015-empire-resources/010-process-empire-resources-updates.sql b/legacyworlds-server-data/db-structure/tests/user/050-updates/015-empire-resources/010-process-empire-resources-updates.sql
new file mode 100644
index 0000000..80c7ff8
--- /dev/null
+++ b/legacyworlds-server-data/db-structure/tests/user/050-updates/015-empire-resources/010-process-empire-resources-updates.sql
@@ -0,0 +1,11 @@
+/*
+ * Test privileges on sys.process_empire_resources_updates()
+ */
+BEGIN;
+	SELECT plan( 1 );
+
+	SELECT diag_test_name( 'sys.process_empire_resources_updates() - Privileges' );
+	SELECT throws_ok( 'SELECT sys.process_empire_resources_updates( 1 )' , 42501 );
+	
+	SELECT * FROM finish( );
+ROLLBACK;
\ No newline at end of file