104 lines
No EOL
3 KiB
PL/PgSQL
104 lines
No EOL
3 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 DOUBLE PRECISION;
|
|
abs_ch DOUBLE PRECISION;
|
|
g_fact DOUBLE PRECISION;
|
|
gf_inc DOUBLE PRECISION;
|
|
n_happ DOUBLE PRECISION;
|
|
t_happ DOUBLE PRECISION;
|
|
temp DOUBLE PRECISION;
|
|
growth DOUBLE PRECISION;
|
|
workers DOUBLE PRECISION;
|
|
str_thr DOUBLE PRECISION;
|
|
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 AS current
|
|
FROM sys.updates su
|
|
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
|
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
|
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
|
|
AND su.gu_type = 'PLANET_POPULATION'
|
|
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; |