Merged player-ic-market into master

This commit is contained in:
Lorenc Pekaj 2018-09-28 07:43:41 +10:00
commit d58fe044ba
6 changed files with 319 additions and 10 deletions

View File

@ -15,7 +15,9 @@
#include "irresistible\cnr\spawn.pwn" #include "irresistible\cnr\spawn.pwn"
#include "irresistible\cnr\dialog_ids.pwn" #include "irresistible\cnr\dialog_ids.pwn"
#include "irresistible\cnr\checkpoints.pwn" #include "irresistible\cnr\checkpoints.pwn"
#include "irresistible\cnr\vip.pwn"
// reliant on core definitions
#include "irresistible\cnr\vip\_vip.pwn"
#include "irresistible\cnr\ammunation.pwn" #include "irresistible\cnr\ammunation.pwn"
#include "irresistible\cnr\irresistibleguard.pwn" #include "irresistible\cnr\irresistibleguard.pwn"
#include "irresistible\cnr\player_settings.pwn" #include "irresistible\cnr\player_settings.pwn"

View File

@ -125,3 +125,6 @@ hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
} }
/* ** Functions ** */ /* ** Functions ** */
stock IsPlayerSecurityVerified( playerid ) {
return ! ( p_accountSecurityData[ playerid ] [ E_ID ] && ! p_accountSecurityData[ playerid ] [ E_VERIFIED ] && p_accountSecurityData[ playerid ] [ E_MODE ] != SECURITY_MODE_DISABLED );
}

View File

@ -0,0 +1,10 @@
/*
* Irresistible Gaming (c) 2018
* Developed by Lorenc Pekaj
* Module: cnr\vip\_vip.pwn
* Purpose: encloses all vip modules & components (cnr)
*/
/* ** Includes ** */
#include "irresistible\cnr\vip\vip.pwn"
#include "irresistible\cnr\vip\player_market.pwn"

View File

@ -0,0 +1,293 @@
/*
* Irresistible Gaming (c) 2018
* Developed by Lorenc Pekaj
* Module:
* Purpose:
*/
/* ** Includes ** */
#include < YSI\y_hooks >
/* ** Definitions ** */
#define DIALOG_IC_SELLORDERS ( 5921 )
#define DIALOG_IC_BUY ( 5922 )
/* ** Variables ** */
static const
p_PlayerMarket_SellOrders [ MAX_PLAYERS ] [ 50 ];
/* ** Hooks ** */
hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
{
if ( dialogid == DIALOG_IC_SELLORDERS && response )
{
for ( new i = 0, x = 0; i < sizeof ( p_PlayerMarket_SellOrders ); i ++ ) if ( p_PlayerMarket_SellOrders[ playerid ] [ i ] != -1 )
{
if ( x == listitem )
{
PlayerMarket_ShowSellOrder( playerid, p_PlayerMarket_SellOrders[ playerid ] [ i ] );
break;
}
x ++;
}
}
else if ( dialogid == DIALOG_IC_BUY )
{
if ( ! response ) {
return ShowPlayerCoinSellOrders( playerid );
}
new sellorderid = GetPVarInt( playerid, "playermarket_sellorder" );
new Float: purchase_amount;
if ( sscanf( inputtext, "f", purchase_amount ) )
{
return SendError( playerid, "Please specify a valid amount." ), PlayerMarket_ShowSellOrder( playerid, sellorderid ), 1;
}
else if ( ! ( 0.5 <= purchase_amount <= 10000.0 ) )
{
return SendError( playerid, "Please specify an amount between 0.5 and 10,000 IC." ), PlayerMarket_ShowSellOrder( playerid, sellorderid ), 1;
}
else
{
mysql_tquery( dbHandle, sprintf( "SELECT * FROM `IC_SELL_ORDERS` WHERE `ID` = %d", sellorderid ), "PlayerMarket_OnPurchaseOrder", "ddf", playerid, sellorderid, purchase_amount );
return 1;
}
}
return 1;
}
/* ** Commands ** */
CMD:sellcoins( playerid, params[ ] )
{
if ( ! IsPlayerSecurityVerified( playerid ) )
return SendError( playerid, "You must be verified in order to use this feature. "COL_YELLOW"(use /verify)" );
new
Float: quantity, price;
if ( GetPlayerVIPLevel( playerid ) < VIP_BRONZE ) return SendError( playerid, "You are not a Bronze V.I.P, to become one visit "COL_GREY"donate.sfcnr.com" );
else if ( sscanf( params, "df", price, quantity ) ) return SendUsage( playerid, "/sellcoins [PRICE_PER_COIN] [COINS]" );
else if ( quantity < 10.0 ) return SendError( playerid, "The minimum amount you can sell is 10.0 Irresistible Coins." );
else if ( quantity > GetPlayerIrresistibleCoins( playerid ) ) return SendError( playerid, "You do not have this many Irresistible Coins." );
else if ( ! ( 1000 <= price <= 125000 )) return SendError( playerid, "Selling price must be between $1,000 and $125,000 per coin." );
else
{
new
Float: sell_volume = float( price ) * quantity;
if ( ! ( 1000.0 <= sell_volume <= 2000000000.0 ) ) {
return SendError( playerid, "The maximum amount of volume per order is $2,000,000,000." ); // prevent bugs
}
// insert into database
mysql_format( dbHandle, szBigString, sizeof( szBigString ), "INSERT INTO IC_SELL_ORDERS (USER_ID, ASK_PRICE, AVAILABLE_IC, TOTAL_IC) VALUES (%d, %d, %f, %f)", GetPlayerAccountID( playerid ), price, quantity, quantity );
mysql_single_query( szBigString );
// deduct the coins
SendServerMessage( playerid, "Sell order for %s Irresistible Coins (at %s/IC) has been placed. Cancel via /cancelorders.", number_format( quantity, .decimals = 3 ), cash_format( price ) );
GivePlayerIrresistibleCoins( playerid, -quantity );
}
return 1;
}
CMD:buycoins( playerid, params[ ] )
{
if ( ! IsPlayerSecurityVerified( playerid ) )
return SendError( playerid, "You must be verified in order to use this feature. "COL_YELLOW"(use /verify)" );
ShowPlayerCoinSellOrders( playerid );
return 1;
}
CMD:cancelorders( playerid, params[ ] )
{
if ( ! IsPlayerSecurityVerified( playerid ) )
return SendError( playerid, "You must be verified in order to use this feature. "COL_YELLOW"(use /verify)" );
mysql_tquery( dbHandle, sprintf( "SELECT * FROM `IC_SELL_ORDERS` WHERE `USER_ID` = %d", GetPlayerAccountID( playerid ) ), "PlayerMarket_OnCancelOrders", "d", playerid );
return 1;
}
/* ** SQL Threads ** */
thread PlayerMarket_OnShowSellOrders( playerid )
{
new
rows = cache_get_row_count( );
if ( rows )
{
static
seller[ 24 ];
// set headers
szHugeString = ""COL_GREY"Player\t"COL_GREY"Quantity Available\t"COL_GREY"Price Per Coin\n";
for ( new row = 0; row < sizeof ( p_PlayerMarket_SellOrders[ ] ); row ++ )
{
if ( row < rows )
{
// store all the listing ids to the player
p_PlayerMarket_SellOrders[ playerid ] [ row ] = cache_get_field_content_int( row, "ID" );
cache_get_field_content( row, "NAME", seller );
new Float: quantity = cache_get_field_content_float( row, "AVAILABLE_IC" );
new ask_price = cache_get_field_content_int( row, "ASK_PRICE" );
format( szHugeString, sizeof( szHugeString ), "%s%s\t%s IC\t"COL_GREEN"%s\n", szHugeString, seller, number_format( quantity, .decimals = 3 ), cash_format( ask_price ) );
}
else
{
p_PlayerMarket_SellOrders[ playerid ] [ row ] = -1;
}
}
return ShowPlayerDialog( playerid, DIALOG_IC_SELLORDERS, DIALOG_STYLE_TABLIST_HEADERS, ""COL_GOLD"Irresistible Coin - "COL_WHITE"Buy Coins", szHugeString, "Buy", "Close" );
}
else
{
return SendError( playerid, "There are no available coin sell orders at current." );
}
}
thread PlayerMarket_OnShowSellOrder( playerid, sellorderid )
{
new
rows = cache_get_row_count( );
if ( ! rows ) {
return SendError( playerid, "This sell order no longer exists. Please try again." );
}
new Float: quantity = cache_get_field_content_float( 0, "AVAILABLE_IC" );
new ask_price = cache_get_field_content_int( 0, "ASK_PRICE" );
SetPVarInt( playerid, "playermarket_sellorder", sellorderid );
format( szBigString, sizeof( szBigString ), ""COL_WHITE"This player has %s Irresistible Coins to sell at %s per coin.\n\nHow many Irresistible Coins would you like to buy?", number_format( quantity, .decimals = 3 ), cash_format( ask_price ) );
return ShowPlayerDialog( playerid, DIALOG_IC_BUY, DIALOG_STYLE_INPUT, ""COL_GOLD"Irresistible Coin - "COL_WHITE"Buy Coins", szBigString, "Buy", "Back" ), 1;
}
thread PlayerMarket_OnCancelOrders( playerid )
{
new
rows = cache_get_row_count( );
if ( ! rows ) {
return SendError( playerid, "You do not have any sell orders at the moment." );
}
new
Float: coins_accum = 0.0;
for ( new row = 0; row < rows; row ++ ) {
coins_accum += cache_get_field_content_float( row, "AVAILABLE_IC" );
}
// delete from db
mysql_single_query( sprintf( "DELETE FROM IC_SELL_ORDERS WHERE USER_ID = %d", GetPlayerAccountID( playerid ) ) );
// credit back user
GivePlayerIrresistibleCoins( playerid, coins_accum );
SendServerMessage( playerid, "You have canceled %d sell orders. You have been returned %s IC.", rows, number_format( coins_accum, .decimals = 3 ) );
return 1;
}
thread PlayerMarket_OnPurchaseOrder( playerid, sellorderid, Float: purchase_amount )
{
new
rows = cache_get_row_count( );
if ( ! rows ) {
return SendError( playerid, "This sell order no longer exists. Please try again." );
}
// check if the player has the money for the purchase
new ask_price = cache_get_field_content_int( 0, "ASK_PRICE" );
new purchase_cost = floatround( float( ask_price ) * purchase_amount );
if ( GetPlayerCash( playerid ) < purchase_cost ) {
return SendError( playerid, "You need at least %s to purchase this many coins.", cash_format( purchase_cost ) ), PlayerMarket_ShowSellOrder( playerid, sellorderid ), 1;
}
// check if quantity is valid
new Float: available_quantity = cache_get_field_content_float( 0, "AVAILABLE_IC" );
if ( purchase_amount > available_quantity ) {
return SendError( playerid, "This player does not have that many coins for sale." ), PlayerMarket_ShowSellOrder( playerid, sellorderid ), 1;
}
// check if seller is the buyer
new seller_account_id = cache_get_field_content_int( 0, "USER_ID" );
if ( GetPlayerAccountID( playerid ) == seller_account_id ) {
return SendError( playerid, "You cannot buy your own coins." ), PlayerMarket_ShowSellOrder( playerid, sellorderid ), 1;
}
// delete the sell order if theres little remaining else reduce
if ( available_quantity - purchase_amount < 0.5 ) {
mysql_single_query( sprintf( "DELETE FROM IC_SELL_ORDERS WHERE ID = %d", sellorderid ) );
} else {
mysql_single_query( sprintf( "UPDATE IC_SELL_ORDERS SET AVAILABLE_IC = AVAILABLE_IC - %f WHERE ID = %d", purchase_amount, sellorderid ) );
}
// check if the seller is online
new
sellerid;
foreach ( sellerid : Player ) if ( GetPlayerAccountID( sellerid ) == seller_account_id ) {
break;
}
new after_fee_amount = floatround( float( purchase_cost ) * 0.995, floatround_floor );
if ( 0 <= sellerid < MAX_PLAYERS && Iter_Contains( Player, sellerid ) ) {
GivePlayerCash( sellerid, after_fee_amount ), Beep( sellerid );
SendServerMessage( sellerid, "You have successfully sold %s IC to %s(%d) for "COL_GOLD"%s"COL_WHITE" (-0.5%s fee)!", number_format( purchase_amount, .decimals = 3 ), ReturnPlayerName( playerid ), playerid, cash_format( after_fee_amount ), "%%" );
} else {
mysql_single_query( sprintf( "UPDATE `USERS` SET `CASH` = `CASH` + %d WHERE `ID` = %d", after_fee_amount, seller_account_id ) );
}
// log the purchase
mysql_format( dbHandle, szBigString, sizeof( szBigString ), "INSERT INTO IC_MARKET_LOG (SELLER_ID, BUYER_ID, ASK_RATE, IC_AMOUNT) VALUES (%d, %d, %d, %f)", seller_account_id, GetPlayerAccountID( playerid ), ask_price, purchase_amount );
mysql_single_query( szBigString );
// credit the buyer
GivePlayerCash( playerid, -purchase_cost );
GivePlayerIrresistibleCoins( playerid, purchase_amount );
SendServerMessage( playerid, "You have successfully purchased %s IC (@ %s/IC) for %s.", number_format( purchase_amount, .decimals = 3 ), cash_format( ask_price ), cash_format( purchase_cost ) );
return 1;
}
/* ** Functions ** */
stock ShowPlayerCoinSellOrders( playerid ) {
mysql_tquery( dbHandle, "SELECT IC_SELL_ORDERS.*,USERS.NAME FROM IC_SELL_ORDERS INNER JOIN USERS ON USERS.ID = IC_SELL_ORDERS.USER_ID ORDER BY ASK_PRICE ASC", "PlayerMarket_OnShowSellOrders", "d", playerid );
return 1;
}
static stock PlayerMarket_ShowSellOrder( playerid, sellorderid ) {
mysql_tquery( dbHandle, sprintf( "SELECT * FROM `IC_SELL_ORDERS` WHERE `ID` = %d", sellorderid ), "PlayerMarket_OnShowSellOrder", "dd", playerid, sellorderid );
return 1;
}
/* ** Migrations ** */
/*
CREATE TABLE IF NOT EXISTS IC_SELL_ORDERS (
`ID` int(11) AUTO_INCREMENT PRIMARY KEY,
`USER_ID` int(11),
`ASK_PRICE` int(11),
`AVAILABLE_IC` float,
`TOTAL_IC` float,
`LISTING_DATE` TIMESTAMP default CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS IC_MARKET_LOG (
`ID` int(11) AUTO_INCREMENT PRIMARY KEY,
`SELLER_ID` int(11),
`BUYER_ID` int(11),
`ASK_RATE` int(11),
`IC_AMOUNT` float,
`DATE` TIMESTAMP default CURRENT_TIMESTAMP
);
*/

View File

@ -55,7 +55,7 @@ new
{ VIP_BRONZE, "Bronze V.I.P", 1000.0 }, { VIP_BRONZE, "Bronze V.I.P", 1000.0 },
{ VIP_REGULAR, "Regular V.I.P", 500.0 } { VIP_REGULAR, "Regular V.I.P", 500.0 }
}, },
g_irreisistibleCashCards [ ] [ E_IC_MARKET_DATA ] = g_irresistibleCashCards [ ] [ E_IC_MARKET_DATA ] =
{ {
{ 1250000, "Tiger Shark", 225.0 }, { 1250000, "Tiger Shark", 225.0 },
{ 2750000, "Bull Shark", 450.0 }, { 2750000, "Bull Shark", 450.0 },
@ -156,7 +156,7 @@ hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
} }
// cash cards // cash cards
else if ( dialogid == DIALOG_IC_MARKET_3 ) { else if ( dialogid == DIALOG_IC_MARKET_3 ) {
iCoinRequirement *= g_irreisistibleCashCards[ listitem ] [ E_PRICE ]; iCoinRequirement *= g_irresistibleCashCards[ listitem ] [ E_PRICE ];
} }
p_CoinMarketPage{ playerid } = ( dialogid == DIALOG_IC_MARKET_3 ) ? ICM_PAGE_CASHCARD : ICM_PAGE_ASSETS; p_CoinMarketPage{ playerid } = ( dialogid == DIALOG_IC_MARKET_3 ) ? ICM_PAGE_CASHCARD : ICM_PAGE_ASSETS;
@ -250,19 +250,19 @@ hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
// buy cash cards // buy cash cards
else if ( p_CoinMarketPage{ playerid } == ICM_PAGE_CASHCARD ) else if ( p_CoinMarketPage{ playerid } == ICM_PAGE_CASHCARD )
{ {
new Float: iCoinRequirement = g_irreisistibleCashCards[ listitem ] [ E_PRICE ] * GetGVarFloat( "vip_discount" ); new Float: iCoinRequirement = g_irresistibleCashCards[ listitem ] [ E_PRICE ] * GetGVarFloat( "vip_discount" );
if ( player_coins < iCoinRequirement ) { if ( player_coins < iCoinRequirement ) {
SendError( playerid, "You need around %s coins before you can get this!", number_format( iCoinRequirement - player_coins, .decimals = 2 ) ); SendError( playerid, "You need around %s coins before you can get this!", number_format( iCoinRequirement - player_coins, .decimals = 2 ) );
return ShowPlayerCoinMarketDialog( playerid, p_CoinMarketPage{ playerid } ); return ShowPlayerCoinMarketDialog( playerid, p_CoinMarketPage{ playerid } );
} }
new cash_amount = g_irreisistibleCashCards[ listitem ] [ E_ID ]; new cash_amount = g_irresistibleCashCards[ listitem ] [ E_ID ];
GivePlayerCash( playerid, cash_amount ); GivePlayerCash( playerid, cash_amount );
GivePlayerIrresistibleCoins( playerid, -iCoinRequirement ); GivePlayerIrresistibleCoins( playerid, -iCoinRequirement );
SendServerMessage( playerid, "You have ordered a "COL_GREEN"%s Cash Card (%s)"COL_WHITE" for %s Irresistible Coins!", g_irreisistibleCashCards[ listitem ] [ E_NAME ], number_format( cash_amount ), number_format( iCoinRequirement, .decimals = 0 ) ); SendServerMessage( playerid, "You have ordered a "COL_GREEN"%s Cash Card (%s)"COL_WHITE" for %s Irresistible Coins!", g_irresistibleCashCards[ listitem ] [ E_NAME ], number_format( cash_amount ), number_format( iCoinRequirement, .decimals = 0 ) );
ShowPlayerHelpDialog( playerid, 10000, "You have bought a ~g~%s~w~ %s Cash Card!", number_format( cash_amount ), g_irreisistibleCashCards[ listitem ] [ E_NAME ] ); ShowPlayerHelpDialog( playerid, 10000, "You have bought a ~g~%s~w~ %s Cash Card!", number_format( cash_amount ), g_irresistibleCashCards[ listitem ] [ E_NAME ] );
} }
// all other market items // all other market items
@ -476,10 +476,10 @@ stock ShowPlayerCoinMarketDialog( playerid, page = ICM_PAGE_DEFAULT )
{ {
szMarket = ""COL_GREY"Cash Card\t"COL_GREY"Amount ($)\t"COL_GREY"Coins Needed\n"; szMarket = ""COL_GREY"Cash Card\t"COL_GREY"Amount ($)\t"COL_GREY"Coins Needed\n";
for( new i = 0; i < sizeof( g_irreisistibleCashCards ); i++ ) for( new i = 0; i < sizeof( g_irresistibleCashCards ); i++ )
{ {
new iCoinRequirement = floatround( g_irreisistibleCashCards[ i ] [ E_PRICE ] * discount ); new iCoinRequirement = floatround( g_irresistibleCashCards[ i ] [ E_PRICE ] * discount );
format( szMarket, sizeof( szMarket ), "%s%s\t"COL_GREEN"%s\t"COL_GOLD"%s\n", szMarket, g_irreisistibleCashCards[ i ] [ E_NAME ], number_format( g_irreisistibleCashCards[ i ] [ E_ID ] ), number_format( iCoinRequirement, .decimals = 0 ) ); format( szMarket, sizeof( szMarket ), "%s%s\t"COL_GREEN"%s\t"COL_GOLD"%s\n", szMarket, g_irresistibleCashCards[ i ] [ E_NAME ], number_format( g_irresistibleCashCards[ i ] [ E_ID ] ), number_format( iCoinRequirement, .decimals = 0 ) );
} }
return ShowPlayerDialog( playerid, DIALOG_IC_MARKET_3, DIALOG_STYLE_TABLIST_HEADERS, ""COL_GOLD"Irresistible Coin -{FFFFFF} Cash Cards", szMarket, "Select", "Back" ); return ShowPlayerDialog( playerid, DIALOG_IC_MARKET_3, DIALOG_STYLE_TABLIST_HEADERS, ""COL_GOLD"Irresistible Coin -{FFFFFF} Cash Cards", szMarket, "Select", "Back" );
} }

View File

@ -1,3 +1,4 @@
(+) Adds a system of buying (/buycoins) and selling (/sellcoins) Irresistible Coins.
(+) Adds a premium real estate listing system, use /estate to see if any homes are interesting. (+) Adds a premium real estate listing system, use /estate to see if any homes are interesting.
(+) Adds passive mode (togglable via /settings). Disables random death matching as an innocent player. (+) Adds passive mode (togglable via /settings). Disables random death matching as an innocent player.
(+) You can now disable automatic weapon pickup through /settings. (+) You can now disable automatic weapon pickup through /settings.