-- 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.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;