This repository has been archived on 2025-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
lwb6/legacyworlds-server-data/db-structure/parts/050-updates/100-planet-population.sql
Emmanuel BENOîT 56eddcc4f0 Game updates improvements
* Added a set of tables which define game updates and their targets.
These definitions replace the old enumerate type. Added a set of
triggers which automatically create specific update tables, insert
missing entries, etc... when game update types are being manipulated.

* Removed manual insertion of game updates from empire creation
function and universe generator.

* Added registration of core update targets (i.e. planets and empires),
updated all existing game update processing functions and added type
registrations

* Created Maven project for game updates control components, moved
existing components from the -simple project, rewritten most of what
they contained, added new components for server-side update batch
processing
2012-02-03 16:25:03 +01:00

110 lines
No EOL
3.1 KiB
PL/PgSQL

-- LegacyWorlds Beta 6
-- PostgreSQL database scripts
--
-- Game updates - population growth and happiness
--
-- Copyright(C) 2004-2010, DeepClone Development
-- --------------------------------------------------------
CREATE OR REPLACE FUNCTION sys.process_planet_population_updates( c_tick BIGINT )
RETURNS VOID
STRICT VOLATILE
SECURITY INVOKER
AS $$
DECLARE
rec RECORD;
rel_ch REAL;
abs_ch REAL;
g_fact REAL;
gf_inc REAL;
n_happ REAL;
t_happ REAL;
temp REAL;
growth REAL;
workers REAL;
str_thr REAL;
BEGIN
-- Get constants
rel_ch := sys.get_constant( 'game.happiness.relativeChange' );
abs_ch := sys.get_constant( 'game.happiness.maxAbsoluteChange' );
g_fact := sys.get_constant( 'game.growthFactor' );
gf_inc := sys.get_constant( 'game.growthFactor.rCentre' );
str_thr := sys.get_constant( 'game.happiness.strike' );
-- Process planets
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
ph.target AS target , ph.current AS happy_pop ,
( ph.current / p.population )::REAL AS current
FROM sys.updates su
INNER JOIN verse.planets_updates vu
USING ( update_id , updtype_id , updtgt_id )
INNER JOIN verse.planets p
USING ( name_id )
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
WHERE su.update_last = c_tick AND su.update_state = 'PROCESSING'
FOR UPDATE OF p, ph
LOOP
IF round( rec.target / rel_ch ) = round( rec.current / rel_ch ) THEN
-- Happiness does not change
n_happ := rec.current;
ELSE
-- Compute new happiness
temp := rec.pop * rel_ch;
IF temp > abs_ch THEN
temp := abs_ch;
ELSEIF temp < 1 THEN
temp := 1;
END IF;
IF rec.target < rec.current THEN
temp := - temp;
END IF;
n_happ := ( rec.happy_pop + temp ) / rec.pop;
END IF;
-- Compute population growth
temp := verse.adjust_production( verse.get_raw_production( rec.id , 'POP' ) , n_happ );
growth := ( g_fact + temp * gf_inc ) * n_happ / 1440.0;
-- Get workers
SELECT INTO workers SUM( b.amount * d.workers )
FROM verse.planet_buildings b
INNER JOIN tech.buildings d
ON d.buildable_id = b.building_id
WHERE b.planet_id = rec.id;
IF workers IS NULL THEN
workers := 0;
END IF;
-- Compute new target happiness
t_happ := verse.compute_happiness( rec.pop + growth , workers ,
verse.adjust_production( verse.get_raw_production( rec.id , 'DEF' ) , n_happ ) ,
emp.get_size( rec.id )
);
-- Update planet and happiness records
UPDATE verse.planet_happiness
SET current = ( rec.pop + growth ) * n_happ , target = t_happ
WHERE planet_id = rec.id;
UPDATE verse.planets
SET population = rec.pop + growth
WHERE name_id = rec.id;
-- Send strike begin/end messages
IF n_happ < str_thr AND rec.current >= str_thr
THEN
PERFORM events.strike_event( rec.id , TRUE );
ELSEIF n_happ >= str_thr AND rec.current < str_thr
THEN
PERFORM events.strike_event( rec.id , FALSE );
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
SELECT sys.register_update_type( 'Planets' , 'PlanetPopulation' ,
'Planet populations are being updated.' ,
'process_planet_population_updates'
);