232 lines
5.9 KiB
PL/PgSQL
232 lines
5.9 KiB
PL/PgSQL
-- LegacyWorlds Beta 6
|
|
-- PostgreSQL database scripts
|
|
--
|
|
-- Various functions for in-game computations
|
|
--
|
|
-- Copyright(C) 2004-2010, DeepClone Development
|
|
-- --------------------------------------------------------
|
|
|
|
|
|
--
|
|
-- sigma( x ) = exp( x ) / ( 1 + exp( x ) )
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.sigma( x DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( CASE
|
|
WHEN $1 < -100 THEN 0
|
|
WHEN $1 > 100 THEN 1
|
|
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )
|
|
END );
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- poly( x , a , b , c ) = ( a * x + b ) * x + c
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.poly( x DOUBLE PRECISION , a DOUBLE PRECISION , b DOUBLE PRECISION , c DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( $2 * $1 + $3 ) * $1 + $4;
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, K1 constant
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k1( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) );
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, K2 constant
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( 2 * ( $1 - $2 ) );
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, K3 constant
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) );
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, first part
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x DOUBLE PRECISION , ymin DOUBLE PRECISION , ymax DOUBLE PRECISION , xmax DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
DECLARE
|
|
v DOUBLE PRECISION;
|
|
BEGIN
|
|
v := ( ymin - ymax ) / xmax;
|
|
RETURN verse.poly( x , v / xmax , -2 * v , ymin );
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, second part
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
DECLARE
|
|
k1 DOUBLE PRECISION;
|
|
BEGIN
|
|
k1 := verse.hcc_const_k1( xmax , ymax , xlimit , ylimit );
|
|
RETURN verse.poly( x , k1 , -2 * xmax * k1 , ymax + k1 * xmax * xmax );
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve, third part
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
DECLARE
|
|
k2 DOUBLE PRECISION;
|
|
k3 DOUBLE PRECISION;
|
|
BEGIN
|
|
k2 := verse.hcc_const_k2( ylimit , yasymptote );
|
|
k3 := verse.hcc_const_k3( xmax , ymax , xlimit , ylimit , yasymptote );
|
|
RETURN yasymptote + k2 * ( 1 - verse.sigma( ( k3 * ( x - xlimit ) ) ) );
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness curve
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.happiness_curve( x DOUBLE PRECISION , ymin DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE SECURITY INVOKER
|
|
AS $$
|
|
SELECT (CASE
|
|
WHEN $1 < $3 THEN
|
|
verse.hcc_part_1( $1 , $2 , $4 , $3 )
|
|
WHEN $1 < $5 THEN
|
|
verse.hcc_part_2( $1 , $3 , $4 , $5 , $6 )
|
|
ELSE
|
|
verse.hcc_part_3( $1 , $3 , $4 , $5 , $6 , $7 )
|
|
END)
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
|
|
--
|
|
-- Happiness computation
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.compute_happiness( population DOUBLE PRECISION , workers DOUBLE PRECISION , defence DOUBLE PRECISION , empsize INT )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT STABLE SECURITY INVOKER
|
|
AS $$
|
|
DECLARE
|
|
whappiness DOUBLE PRECISION;
|
|
dhappiness DOUBLE PRECISION;
|
|
shappiness DOUBLE PRECISION;
|
|
BEGIN
|
|
-- Work-related happiness
|
|
whappiness := verse.happiness_curve(
|
|
workers / population ,
|
|
sys.get_constant( 'game.happiness.noEmployment' ) , 1.0 , 1.0 ,
|
|
sys.get_constant( 'game.happiness.employmentLimit' ) , 0.5 , 0
|
|
);
|
|
|
|
-- Defence-related happiness
|
|
dhappiness := verse.happiness_curve(
|
|
sys.get_constant( 'game.happiness.popPerDefencePoint' ) * defence / population ,
|
|
sys.get_constant( 'game.happiness.noDefence' ) , 1.0 , 1.0 ,
|
|
sys.get_constant( 'game.happiness.defenceLimit' ) , 0.5 , 0
|
|
);
|
|
|
|
-- Influence of empire size
|
|
shappiness := verse.happiness_curve(
|
|
empsize / sys.get_constant( 'game.happiness.idealEmpireSize' ) ,
|
|
sys.get_constant( 'game.happiness.smallEmpire' ) , 1.0 , 1.0 ,
|
|
sys.get_constant( 'game.happiness.eSizeLimit' ) , 0.5 , 0
|
|
);
|
|
|
|
RETURN shappiness * ( whappiness + dhappiness ) / 2.0;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
--
|
|
-- Production adjustment
|
|
--
|
|
CREATE OR REPLACE FUNCTION verse.adjust_production( prod DOUBLE PRECISION , happiness DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT IMMUTABLE
|
|
SECURITY INVOKER
|
|
AS $$
|
|
SELECT ( CASE
|
|
WHEN $2 < sys.get_constant( 'game.happiness.strike' ) THEN
|
|
$1 * ( 1 - ( $2 / sys.get_constant( 'game.happiness.strike' ) ) )
|
|
ELSE
|
|
$1
|
|
END );
|
|
$$ LANGUAGE SQL;
|
|
|
|
|
|
--
|
|
-- Income computation
|
|
--
|
|
|
|
CREATE OR REPLACE FUNCTION verse.compute_income( population DOUBLE PRECISION , happiness DOUBLE PRECISION , cashprod DOUBLE PRECISION )
|
|
RETURNS DOUBLE PRECISION
|
|
STRICT STABLE
|
|
SECURITY INVOKER
|
|
AS $$
|
|
DECLARE
|
|
base DOUBLE PRECISION;
|
|
badj DOUBLE PRECISION;
|
|
cprod DOUBLE PRECISION;
|
|
BEGIN
|
|
badj := ( 1 - verse.adjust_production( 1.0 , happiness ) ) * sys.get_constant( 'game.work.strikeEffect' );
|
|
base := floor( population ) * sys.get_constant( 'game.work.population' ) * ( 1 - badj );
|
|
cprod := verse.adjust_production( cashprod , happiness ) * sys.get_constant( 'game.work.factory' );
|
|
RETURN cprod + base;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|