This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb6/legacyworlds-server/legacyworlds-server-data/db-structure/parts/functions/050-computation-functions.sql

233 lines
5.2 KiB
MySQL
Raw Normal View History

2018-10-23 09:38:02 +02:00
-- 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 REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
SELECT ( CASE
WHEN $1 < -100 THEN 0
WHEN $1 > 100 THEN 1
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )::REAL
END );
$$ LANGUAGE SQL;
--
-- poly( x , a , b , c ) = ( a * x + b ) * x + c
--
CREATE OR REPLACE FUNCTION verse.poly( x REAL , a REAL , b REAL , c REAL )
RETURNS REAL
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 REAL , ymax REAL , xlimit REAL , ylimit REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) )::REAL;
$$ LANGUAGE SQL;
--
-- Happiness curve, K2 constant
--
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit REAL , yasymptote REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
SELECT ( 2 * ( $1 - $2 ) )::REAL;
$$ LANGUAGE SQL;
--
-- Happiness curve, K3 constant
--
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) ) ::REAL;
$$ LANGUAGE SQL;
--
-- Happiness curve, first part
--
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x REAL , ymin REAL , ymax REAL , xmax REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
DECLARE
v REAL;
BEGIN
v := ( ymin - ymax ) / xmax;
RETURN verse.poly( x , ( v / xmax )::REAL , ( -2 * v )::REAL , ymin );
END;
$$ LANGUAGE plpgsql;
--
-- Happiness curve, second part
--
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
DECLARE
k1 REAL;
BEGIN
k1 := verse.hcc_const_k1( xmax , ymax , xlimit , ylimit );
RETURN verse.poly( x , k1 , ( -2 * xmax * k1 )::REAL , ( ymax + k1 * xmax * xmax )::REAL );
END;
$$ LANGUAGE plpgsql;
--
-- Happiness curve, third part
--
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
RETURNS REAL
STRICT IMMUTABLE SECURITY INVOKER
AS $$
DECLARE
k2 REAL;
k3 REAL;
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 ) ) )::REAL );
END;
$$ LANGUAGE plpgsql;
--
-- Happiness curve
--
CREATE OR REPLACE FUNCTION verse.happiness_curve( x REAL , ymin REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
RETURNS REAL
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 REAL , workers REAL , defence REAL , empsize INT )
RETURNS REAL
STRICT STABLE SECURITY INVOKER
AS $$
DECLARE
whappiness REAL;
dhappiness REAL;
shappiness REAL;
BEGIN
-- Work-related happiness
whappiness := verse.happiness_curve(
( workers / population )::REAL ,
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 )::REAL ,
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::REAL / sys.get_constant( 'game.happiness.idealEmpireSize' ) )::REAL ,
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 )::REAL;
END;
$$ LANGUAGE plpgsql;
--
-- Production adjustment
--
CREATE OR REPLACE FUNCTION verse.adjust_production( prod REAL , happiness REAL )
RETURNS REAL
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' ) ) ) )::REAL
ELSE
$1
END );
$$ LANGUAGE SQL;
--
-- Income computation
--
CREATE OR REPLACE FUNCTION verse.compute_income( population REAL , happiness REAL , cashprod REAL )
RETURNS REAL
STRICT STABLE
SECURITY INVOKER
AS $$
DECLARE
base REAL;
badj REAL;
cprod REAL;
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;