use float for prices, reduce data redundancy
This commit is contained in:
parent
b1847fffdf
commit
8d8fdc1392
@ -11,7 +11,7 @@
|
|||||||
/* ** Definitions ** */
|
/* ** Definitions ** */
|
||||||
#define MAX_STOCKS ( 32 )
|
#define MAX_STOCKS ( 32 )
|
||||||
|
|
||||||
#define STOCK_REPORTING_PERIOD ( 86400 ) // 1 day
|
#define STOCK_REPORTING_PERIOD ( 500 ) // 1 day
|
||||||
|
|
||||||
#define STOCK_REPORTING_PERIODS ( 30 ) // last 30 periods (days)
|
#define STOCK_REPORTING_PERIODS ( 30 ) // last 30 periods (days)
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ enum E_STOCK_MARKET_DATA
|
|||||||
|
|
||||||
enum E_STOCK_MARKET_PRICE_DATA
|
enum E_STOCK_MARKET_PRICE_DATA
|
||||||
{
|
{
|
||||||
E_CURRENT_PRICE,
|
E_SQL_ID, Float: E_PRICE,
|
||||||
E_CURRENT_EARNINGS, E_PREVIOUS_EARNINGS
|
Float: E_EARNINGS
|
||||||
};
|
};
|
||||||
|
|
||||||
static stock
|
static stock
|
||||||
@ -41,7 +41,33 @@ static stock
|
|||||||
/* ** Hooks ** */
|
/* ** Hooks ** */
|
||||||
hook OnScriptInit( )
|
hook OnScriptInit( )
|
||||||
{
|
{
|
||||||
CreateStockMarket( 0, "The Mining Company", "MC", 10000000, 100 );
|
// server variables
|
||||||
|
AddServerVariable( "stock_report_time", "0", GLOBAL_VARTYPE_INT );
|
||||||
|
|
||||||
|
// create markets
|
||||||
|
CreateStockMarket( 0, "The Mining Company", "MC", 50000000, 100 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook OnServerUpdate( )
|
||||||
|
{
|
||||||
|
new current_time = GetServerTime( );
|
||||||
|
new last_reporting = GetServerVariableInt( "stock_report_time" );
|
||||||
|
|
||||||
|
// check if its reporting time
|
||||||
|
if ( current_time > last_reporting )
|
||||||
|
{
|
||||||
|
// reporting period
|
||||||
|
UpdateServerVariableInt( "stock_report_time", current_time + STOCK_REPORTING_PERIOD );
|
||||||
|
|
||||||
|
// create a new reporting period for every stock there
|
||||||
|
foreach ( new s : stockmarkets )
|
||||||
|
{
|
||||||
|
StockMarket_CreateReport( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
print( "Successfully created new reporting period for all online companies" );
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,17 +81,23 @@ thread Stock_UpdateReportingPeriods( stockid )
|
|||||||
{
|
{
|
||||||
for ( new row = 0; row < rows; row ++ )
|
for ( new row = 0; row < rows; row ++ )
|
||||||
{
|
{
|
||||||
g_stockMarketPriceData[ stockid ] [ row ] [ E_CURRENT_PRICE ] = cache_get_field_content_int( row, "CURRENT_PRICE" );
|
g_stockMarketPriceData[ stockid ] [ row ] [ E_SQL_ID ] = cache_get_field_content_int( row, "ID" );
|
||||||
g_stockMarketPriceData[ stockid ] [ row ] [ E_CURRENT_EARNINGS ] = cache_get_field_content_int( row, "CURRENT_EARNINGS" );
|
g_stockMarketPriceData[ stockid ] [ row ] [ E_PRICE ] = cache_get_field_content_float( row, "CURRENT_PRICE" );
|
||||||
g_stockMarketPriceData[ stockid ] [ row ] [ E_PREVIOUS_EARNINGS ] = cache_get_field_content_int( row, "PREVIOUS_EARNINGS" );
|
g_stockMarketPriceData[ stockid ] [ row ] [ E_EARNINGS ] = cache_get_field_content_float( row, "CURRENT_EARNINGS" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread StockMarket_InsertReport( stockid )
|
||||||
|
{
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_SQL_ID ] = cache_insert_id( );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ** Command ** */
|
/* ** Command ** */
|
||||||
CMD:increase( playerid, params[ ] ) {
|
CMD:increase( playerid, params[ ] ) {
|
||||||
g_stockMarketPriceData[ 0 ] [ 0 ] [ E_CURRENT_EARNINGS ] += strval( params );
|
StockMarket_UpdateEarnings( 0, strval( params ) );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,28 +112,23 @@ CMD:stockmarkets( playerid, params[ ] )
|
|||||||
|
|
||||||
foreach ( new s : stockmarkets )
|
foreach ( new s : stockmarkets )
|
||||||
{
|
{
|
||||||
printf("%d %d\n", g_stockMarketPriceData[ s ] [ 0 ] [ E_CURRENT_EARNINGS ], g_stockMarketPriceData[ s ] [ 1 ] [ E_CURRENT_EARNINGS ]);
|
printf("%f %f\n", g_stockMarketPriceData[ s ] [ 0 ] [ E_EARNINGS ], g_stockMarketPriceData[ s ] [ 1 ] [ E_EARNINGS ]);
|
||||||
new Float: price_difference = ( ( float( g_stockMarketPriceData[ s ] [ 0 ] [ E_CURRENT_EARNINGS ] ) / float( g_stockMarketPriceData[ s ] [ 1 ] [ E_CURRENT_EARNINGS ] ) ) - 1.0 ) * 100.0;
|
new Float: price_difference = ( g_stockMarketPriceData[ s ] [ 1 ] [ E_EARNINGS ] / g_stockMarketPriceData[ s ] [ 2 ] [ E_EARNINGS ] - 1.0 ) * 100.0;
|
||||||
new current_price = g_stockMarketPriceData[ s ] [ 0 ] [ E_CURRENT_PRICE ];
|
new Float: current_price = g_stockMarketPriceData[ s ] [ 1 ] [ E_PRICE ];
|
||||||
|
|
||||||
// prevent integer overflow (over 2.6B)
|
|
||||||
new Float: market_cap_millions = ( float( g_stockMarketData[ s ] [ E_MAX_SHARES ] ) / 1000000.0 ) * ( float( current_price ) / 1000000.0 );
|
|
||||||
new Float: market_cap_billions = market_cap_millions / 1000.0;
|
|
||||||
|
|
||||||
format(
|
format(
|
||||||
szLargeString, sizeof( szLargeString ),
|
szLargeString, sizeof( szLargeString ),
|
||||||
"%s%s (%s)\t"COL_GREEN"%s\t$%s%s\t%s%s%%\n",
|
"%s%s (%s)\t"COL_GREEN"%s\t%s%s%%\n",
|
||||||
szLargeString,
|
szLargeString,
|
||||||
g_stockMarketData[ s ] [ E_NAME ],
|
g_stockMarketData[ s ] [ E_NAME ],
|
||||||
g_stockMarketData[ s ] [ E_SYMBOL ],
|
g_stockMarketData[ s ] [ E_SYMBOL ],
|
||||||
cash_format( current_price ),
|
cash_format( current_price, .decimals = 0 ),
|
||||||
market_cap_billions > 1.0 ? number_format( market_cap_billions, .decimals = 2 ) : number_format( market_cap_millions, .decimals = 2 ),
|
|
||||||
market_cap_billions > 1.0 ? ( "B" ) : ( "M" ),
|
|
||||||
price_difference >= 0.0 ? ( COL_GREEN ) : ( COL_RED ),
|
price_difference >= 0.0 ? ( COL_GREEN ) : ( COL_RED ),
|
||||||
number_format( price_difference, .decimals = 2 )
|
number_format( price_difference, .decimals = 2 )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SendServerMessage( playerid, "The stock market will close in %s.", secondstotime( GetServerVariableInt( "stock_report_time" ) - GetServerTime( ) ) );
|
||||||
return ShowPlayerDialog( playerid, DIALOG_STOCK_MARKET, DIALOG_STYLE_TABLIST_HEADERS, ""COL_WHITE"Stock Market", szLargeString, "Select", "Close" );
|
return ShowPlayerDialog( playerid, DIALOG_STOCK_MARKET, DIALOG_STYLE_TABLIST_HEADERS, ""COL_WHITE"Stock Market", szLargeString, "Select", "Close" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +145,8 @@ stock CreateStockMarket( stockid, const name[ 64 ], const symbol[ 4 ], max_share
|
|||||||
|
|
||||||
// reset stock price information
|
// reset stock price information
|
||||||
for ( new r = 0; r < sizeof( g_stockMarketPriceData[ ] ); r ++ ) {
|
for ( new r = 0; r < sizeof( g_stockMarketPriceData[ ] ); r ++ ) {
|
||||||
g_stockMarketPriceData[ stockid ] [ r ] [ E_CURRENT_PRICE ] = 0;
|
g_stockMarketPriceData[ stockid ] [ r ] [ E_PRICE ] = 0.0;
|
||||||
g_stockMarketPriceData[ stockid ] [ r ] [ E_CURRENT_EARNINGS ] = 0;
|
g_stockMarketPriceData[ stockid ] [ r ] [ E_EARNINGS ] = 0.0;
|
||||||
g_stockMarketPriceData[ stockid ] [ r ] [ E_PREVIOUS_EARNINGS ] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load price information if there is
|
// load price information if there is
|
||||||
@ -134,8 +160,20 @@ stock CreateStockMarket( stockid, const name[ 64 ], const symbol[ 4 ], max_share
|
|||||||
|
|
||||||
stock StockMarket_CreateReport( stockid )
|
stock StockMarket_CreateReport( stockid )
|
||||||
{
|
{
|
||||||
new old_earnings = g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_EARNINGS ];
|
// limit a 20% loss for players
|
||||||
new old_price = g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_PRICE ];
|
new Float: circuit_breaker = g_stockMarketPriceData[ stockid ] [ 1 ] [ E_EARNINGS ] * 0.8;
|
||||||
|
|
||||||
|
if ( g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ] < circuit_breaker ) {
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ] = circuit_breaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
// change stock price proportional to earnings increase/decrease
|
||||||
|
new Float: price_difference = g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ] / g_stockMarketPriceData[ stockid ] [ 1 ] [ E_EARNINGS ];
|
||||||
|
printf("Earnings %f\n", price_difference );
|
||||||
|
|
||||||
|
if ( ( g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PRICE ] = g_stockMarketPriceData[ stockid ] [ 1 ] [ E_PRICE ] * price_difference ) < 1.0 ) {
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PRICE ] = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
// store temporary stock info
|
// store temporary stock info
|
||||||
new temp_stock_price_data[ MAX_STOCKS ] [ STOCK_REPORTING_PERIODS ] [ E_STOCK_MARKET_PRICE_DATA ];
|
new temp_stock_price_data[ MAX_STOCKS ] [ STOCK_REPORTING_PERIODS ] [ E_STOCK_MARKET_PRICE_DATA ];
|
||||||
@ -143,58 +181,77 @@ stock StockMarket_CreateReport( stockid )
|
|||||||
|
|
||||||
// shift all earnings by one
|
// shift all earnings by one
|
||||||
for ( new r = 0; r < sizeof( g_stockMarketPriceData[ ] ) - 2; r ++ ) {
|
for ( new r = 0; r < sizeof( g_stockMarketPriceData[ ] ) - 2; r ++ ) {
|
||||||
|
g_stockMarketPriceData[ stockid ] [ r + 1 ] [ E_PRICE ] = temp_stock_price_data[ stockid ] [ r ] [ E_PRICE ];
|
||||||
g_stockMarketPriceData[ stockid ] [ r + 1 ] [ E_CURRENT_PRICE ] = temp_stock_price_data[ stockid ] [ r ] [ E_CURRENT_PRICE ];
|
g_stockMarketPriceData[ stockid ] [ r + 1 ] [ E_EARNINGS ] = temp_stock_price_data[ stockid ] [ r ] [ E_EARNINGS ];
|
||||||
g_stockMarketPriceData[ stockid ] [ r + 1 ] [ E_CURRENT_EARNINGS ] = temp_stock_price_data[ stockid ] [ r ] [ E_CURRENT_EARNINGS ];
|
|
||||||
g_stockMarketPriceData[ stockid ] [ r + 1 ] [ E_PREVIOUS_EARNINGS ] = temp_stock_price_data[ stockid ] [ r ] [ E_PREVIOUS_EARNINGS ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// price difference
|
// set current price to previous reporting period price
|
||||||
new Float: price_change = float( g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_EARNINGS ] ) / float( old_earnings );
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PRICE ] = g_stockMarketPriceData[ stockid ] [ 1 ] [ E_PRICE ];
|
||||||
|
|
||||||
// circuit breaker ... max 20% loss
|
// reset earnings
|
||||||
if ( price_change < 0.8 ) {
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ] = 0.0; // set to 0
|
||||||
price_change = 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
new new_price = floatround( float( old_price ) * price_change );
|
// insert to database the old information
|
||||||
|
mysql_format(
|
||||||
|
dbHandle, szBigString, sizeof ( szBigString ),
|
||||||
|
"INSERT INTO `STOCK_REPORTS` (`STOCK_ID`, `CURRENT_PRICE`, `CURRENT_EARNINGS`) VALUES (%d, %f, %f)",
|
||||||
|
stockid,
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PRICE ],
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ]
|
||||||
|
);
|
||||||
|
|
||||||
// minimum stock price should be $10
|
mysql_tquery( dbHandle, szBigString, "StockMarket_InsertReport", "d", stockid );
|
||||||
if ( new_price < 1 ) {
|
|
||||||
new_price = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set information
|
|
||||||
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_PRICE ] = new_price;
|
|
||||||
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_EARNINGS ] = 0; // set to 0
|
|
||||||
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PREVIOUS_EARNINGS ] = old_earnings;
|
|
||||||
|
|
||||||
// insert to database
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
erase(szLargeString);
|
|
||||||
// shift all earnings by one
|
|
||||||
for ( new r = 0; r < sizeof( g_stockMarketPriceData[ ] ); r ++ ) {
|
|
||||||
format( szLargeString, 1024, "%s{%d,%d,%d}, ", szLargeString, g_stockMarketPriceData[ stockid ] [ r ] [ E_CURRENT_PRICE ], g_stockMarketPriceData[ stockid ] [ r ] [ E_CURRENT_EARNINGS ], g_stockMarketPriceData[ stockid ] [ r ] [ E_PREVIOUS_EARNINGS ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n",szLargeString);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stock StockMarket_GetCurrentPrice( stockid ) {
|
stock StockMarket_UpdateEarnings( stockid, amount )
|
||||||
return g_stockMarketPriceData[ stockid ] [ 0 ] [ E_CURRENT_PRICE ];
|
{
|
||||||
|
if ( ! Iter_Contains( stockmarkets, stockid ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
printf( "Current Earnings: %f, Prior Earnings: %f", g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ], g_stockMarketPriceData[ stockid ] [ 1 ] [ E_EARNINGS ] );
|
||||||
|
g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ] += amount;
|
||||||
|
mysql_single_query( sprintf( "UPDATE `STOCK_REPORTS` SET `CURRENT_EARNINGS` = `CURRENT_EARNINGS` + %d WHERE `ID` = %d", g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ], g_stockMarketPriceData[ stockid ] [ 0 ] [ E_SQL_ID ] ) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stock Float: StockMarket_GetEarnings( stockid ) {
|
||||||
|
return g_stockMarketPriceData[ stockid ] [ 0 ] [ E_EARNINGS ];
|
||||||
|
}
|
||||||
|
|
||||||
|
stock Float: StockMarket_GetCurrentPrice( stockid ) {
|
||||||
|
return g_stockMarketPriceData[ stockid ] [ 0 ] [ E_PRICE ];
|
||||||
|
}
|
||||||
|
|
||||||
|
stock StockMarket_MakeSellOrder( stockid, accountid, Float: shares, Float: price )
|
||||||
|
{
|
||||||
|
//INSERT INTO `STOCK_ORDERS` (`USER_ID`, `STOCK_ID`, ``)
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `STOCK_REPORTS` (
|
CREATE TABLE IF NOT EXISTS `STOCK_REPORTS` (
|
||||||
|
`ID` int(11) primary key auto_increment,
|
||||||
`STOCK_ID` int(11),
|
`STOCK_ID` int(11),
|
||||||
`CURRENT_PRICE` int(11),
|
`CURRENT_PRICE` float,
|
||||||
`CURRENT_EARNINGS` int(11),
|
`CURRENT_EARNINGS` float,
|
||||||
`PREVIOUS_EARNINGS` int(11),
|
|
||||||
`REPORTING_TIME` TIMESTAMP default CURRENT_TIMESTAMP
|
`REPORTING_TIME` TIMESTAMP default CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `STOCK_OWNERS` (
|
||||||
|
`ID` int(11) primary key auto_increment,
|
||||||
|
`USER_ID` int(11),
|
||||||
|
`STOCK_ID` int(11),
|
||||||
|
`SHARES` float,
|
||||||
|
`PRICE` float
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `STOCK_ORDERS` (
|
||||||
|
`ID` int(11) primary key auto_increment,
|
||||||
|
`USER_ID` int(11),
|
||||||
|
`STOCK_ID` int(11),
|
||||||
|
`SHARES` float,
|
||||||
|
`PRICE` float,
|
||||||
|
);
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,15 @@
|
|||||||
/* ** Includes ** */
|
/* ** Includes ** */
|
||||||
#include < YSI\y_hooks >
|
#include < YSI\y_hooks >
|
||||||
|
|
||||||
|
/* ** Macros ** */
|
||||||
|
#define GetServerVariableInt GetGVarInt
|
||||||
|
|
||||||
|
#define UpdateServerVariableString(%0,%1) \
|
||||||
|
(UpdateServerVariable(%0, 0, 0, %1, GLOBAL_VARTYPE_STRING))
|
||||||
|
|
||||||
|
#define UpdateServerVariableInt(%0,%1) \
|
||||||
|
(UpdateServerVariable(%0, %1, 0, "", GLOBAL_VARTYPE_INT))
|
||||||
|
|
||||||
/* ** Hooks ** */
|
/* ** Hooks ** */
|
||||||
hook OnGameModeInit( )
|
hook OnGameModeInit( )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user