Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   Bank System (https://forums.graalonline.com/forums/showthread.php?t=68873)

Twinny 09-22-2006 04:52 AM

Bank System
 
Bank system I made using dbnpc.

DBNPC Script (Name is BankDB):
PHP Code:

function onCreated()
{
  
this.interest 0.01;
  
this.hour 0;
  
Interest();
  
setTimer(3600);
}
public function 
CreateAccount(pl,ammount)
{
  if (
this.accounts.index(pl) = -1)
  {
    
this.accounts.add(pl);
    
this.("acc"@pl) = ammount;
    
findplayer(pl).rupees -= ammount;
    return 
true
  
}
  else return 
false;
}

public function 
CheckBalance(pl)
{
  if (
this.accounts.index(pl) => 0)
  {
    return 
this.("acc"@pl);
  }
  else return 
false;
}  

public function 
AddMoney(pl,ammount)
{
  if (
this.accounts.index(pl) => 0)
  {
    
findplayer(pl).rupees -= ammount;
    
this.("acc"@pl) += ammount;
    return 
this.("acc"@pl);
  }
  else return 
false;
}  

public function 
RemoveMoney(pl,ammount)
{
  if (
this.accounts.index(pl) => 0)
  {
    if (
this.("acc"@pl) => ammount)
    {
      
this.("acc"@pl) -= ammount;
      
findplayer(pl).rupees += ammount;
      return 
true;
    }
    else return 
"nm";
  }
  else return 
"na";
}

function 
onTimeout() 
{
/* Cheers to Kuji for this.hour idea */
  
this.hour ++;
  if (
this.hour => 24)
  {
    echo(
"Interest Added");
    
Interest();
    
this.hour 0;
  }
setTimer(3600);


public function 
Interest()
{
  for (
int this.accounts)
  {
    
this.("acc"@int) = int(this.("acc"@int) * 1.01);
  }


Manual interest for RC - add this to your Control-NPC
PHP Code:

 function onRCChat()
{
  if (
params[0] == "interest")
  {
    if (
player.account == "Whoever")
    {
      echo(
"Manual Interest Added!");
      
BankDB.Interest();
    }
  }


And finally some examples on how to use this system in a bank
PHP Code:

/* Do not clientside this script */
function onPlayerChats()
{
  
/*Create Account*/
  
if (player.chat.starts("/createaccount"))
  {
    
temp.result BankDB.CreateAccount(player.account,player.chat.substring(15,-1));
    if (
temp.result == true)
      
say2("Account Opened");

    else 
say2("You already have an account");
   }

  else if (
player.chat == "/balance")
  {
    
temp.result BankDB.CheckBalance(player.account);
    if(
temp.result != false)
      
say2("Current Balance" SPC temp.result);
    else 
say2("You do not have an account");
   }

   else if (
player.chat.starts("/withdraw"))
   {
     
temp.result BankDB.RemoveMoney(player.account,player.chat.substring(10,-1));
     if (
temp.result == "na")
       
say2("Open an account?");
     else if (
temp.result == "nm")
       
say2("Not enough money");
     else if (
temp.result ==  true)
       
say2("Withdrawn");
    }
   else if (
player.chat.starts("/deposit"))
   {
        if (
player.rupees player.chat.substring(9,-1))
        {
          
temp.result BankDB.AddMoney(player.account,player.chat.substring(9,-1));
          if (
temp.result != false)
            
say2("Money Deposited. Balance: " temp.result);
          else
            
say2("Open an account first");
        }
    }


This system can work on a global scale. One BankDB can serve any ammount of banks. I used a BankDB for a couple of reasons. First off - incredibly easy to add interest now. Secondly - I can use functions to determine who has the most money, total ammount of money etc. (Not included).

Skyld 09-22-2006 09:04 AM

Slightly different approach to how I would do it, but good none the less.

KuJi 09-22-2006 01:12 PM

Quote:

Originally Posted by Twinny (Post 1220510)
public function CreateAccount(pl,ammount)

Take a look at the bolded twinny ;)

Twinny 09-23-2006 01:21 AM

So I can't spell for peanuts. Does this really matter? No? Good :) .

xAndrewx 09-23-2006 09:18 AM

Quote:

Originally Posted by Skyld (Post 1220547)
Slightly different approach to how I would do it, but good none the less.

I agree :S
Good though :)

Twinny 09-23-2006 10:25 AM

Ok: How would you two do it?

xAndrewx 09-23-2006 10:30 AM

Personally, I'd merge the Create account and Deposit into one. If the string inside the database doesn't exist, I'd then instantly create the bank account. I wouldn't use so many public functions, remember that they're public. I'd also convert your playerchats.

KuJi 09-23-2006 11:07 AM

Clientside -> Trigger to Server -> Use ChatBar -> Ftw =O?

Skyld 09-23-2006 11:32 AM

Quote:

Originally Posted by Twinny (Post 1221016)
Ok: How would you two do it?

Well, the way that my system works is that I have a collection of public functions in a class which is joined to the player.
PHP Code:

public function bankCreate();
public function 
bankDeposit();
public function 
bankWithdraw(); 

I also have other functions for checking if they have an account, checking the balance, etc.

I also have a DB NPC for storing the bank data, i.e.
PHP Code:

DB_Bank.("bank_" this.account) = ...; 

However, but it doesn't do any functioning itself.

Then, instead of having to pass the account name, I can just use the this. object to access the player so that you can just do this to deposit 30g:
PHP Code:

player.bankDeposit(30); 

It makes it:
  • Easier to type, and remember.
  • Easier for other people to pick up and use.
  • So that you don't have to pass the account name.

KuJi 09-23-2006 11:49 AM

Hmm.. my atms a bit diff =o.

acc_123456=KuJi,PASSWORD,BALANCE

I should probally MD5 the password, maybe I will redo the ATM sometime soon.. is kinda old.

Anyway, when you use your ATM Card it has the ATM # in it automatically... so yeah.

Twinny 09-23-2006 02:32 PM

Quote:

Originally Posted by xAndrewx (Post 1221018)
I'd also convert your playerchats.

The playerchat stuff was just an example to show how to do it. Hopefully people will use something better eg a GUI.

That's a pretty good idea Skyld. May edit the code with a more user friendly version later ^^. I'm still pretty sucky at scripting but anything that seems half decent to me i'll share in the hope of receiving advice :)

xAndrewx 09-23-2006 03:57 PM

Skyld's idea is good :]

k0rupt_ed 09-23-2006 08:30 PM

you people inspire me.

Twinny 09-23-2006 09:46 PM

To do what? ^^

Twinny 09-28-2006 09:04 AM

Update!
Bank System v 1.1
After receving advice from Skyld I have made a improved bank system using classes.

DBNPC named BankDB
PHP Code:

function onCreated()
{
  
this.interest 0.01;
  
this.hour 0;
  
Interest();
  
setTimer(3600);
}

function 
onTimeout()
{
  
this.hour ++;
  if (
this.hour => 24)
  {
    echo(
"Interest Added");
    
Interest();
    
this.hour 0;
  }
setTimer(3600);


public function 
Interest()
{
  for (
int this.accounts)
  {
    
this.("acc"@int) = int(this.("acc"@int) * 1.01);
  }


Class with bank functions
PHP Code:

public function bankCreate(amount)
{
  if (
BankDB.accounts.index(player.account) = -1)
  {
    if (
player.rupees => amount)
    {
      
BankDB.accounts.add(player.account);
      
BankDB.("acc"@player.account) = amount;
      
player.rupees -= amount;
      return 
True;
    }
    else return 
"nem";  
  }
  else return 
false;
}

public function 
bankDeposit(amount)
{
  if (
BankDB.accounts.index(player.account) => 0)
  {
    if (
player.rupees => amount)
    {
      
BankDB.("acc"@player.account) += amount;
      
player.rupees -= amount;
      return 
true;
    }
    else return 
"nem"//Not enough money
  
}
  else return 
"nba"//No bank account  
}

public function 
bankWithdraw(amount)
{
  if (
BankDB.accounts.index(player.account) => 0)
  {
    if (
BankDB.("acc"@player.account) => amount)
    {
      
BankDB.("acc"@player.account) -= amount;
      
player.rupees += amount;
      return 
true;
    }
    else return 
"nem";
  }
  else return 
"nba";   
}

public function 
bankBalance()
{
  if (
BankDB.accounts.index(player.account) => 0)
  {
    return 
BankDB.("acc"@player.account);
  }
  else return 
"nba";
}

public function 
bankTransfer(amount,pl)
{
/* Lot's of Tests */
  
if (BankDB.accounts.index(player.account) => 0)
  {
    if(
BankDB.accounts.index(pl) => 0)
    {
      if (
BankDB.("acc"@player.account) => amount)
      {
        
BankDB.("acc"@pl) += amount;
        
BankDB.("acc"@player.account) -= amount;
        return 
true;
      }
      else return 
"nem";
    }
    else return 
"pdne"//Player does not exist
  
}
  else return 
"nba";


Finally add in your Control-NPC
PHP Code:

function onActionPlayeronline()
{
  
player.join("classname");
}

function 
onRCChat()
{
  if (
params[0] == "interest")
  {
    if (
player.account == "Whoever")
    {
      echo(
"Manual Interest Added!");
      
BankDB.Interest();
    }
  }


Commands Available
PHP Code:

player.bankCreate(amount);
player.bankDeposit(amount);
player.bankWithdraw(amount);
player.bankBalance();
player.bankTransfer(amount,account); 

Simple enough to use. Call the commands serverside eg. player.bankDeposit(400);

May add a GUI script to use the Bank system next.

xAndrewx 09-28-2006 06:26 PM

You're using return quite alot, but you're not really giving reason why? Explain why you've used
'return "w/e";'
as some people may not get it.

Twinny 09-28-2006 11:46 PM

Return tells whatever script accessed the commands the results of those commands. Eg. A NPC tries to withdraw 501 when you only have 500. It will receive "nem" and display the error message appropriately.

This in turn allows for customisation. Eg. a human banker may be polite about this while a rock troll banker will proceed to club you to death for not having enough money.

KuJi 09-29-2006 02:39 AM

Quote:

Originally Posted by Twinny (Post 1223414)
Return tells whatever script accessed the commands the results of those commands. Eg. A NPC tries to withdraw 501 when you only have 500. It will receive "nem" and display the error message appropriately.

This in turn allows for customisation. Eg. a human banker may be polite about this while a rock troll banker will proceed to club you to death for not having enough money.

I am pretty sure snk knows... (if that was directed to me).. he tells me to use it more =(

xAndrewx 09-29-2006 08:31 AM

I know how it works, but you didn't seem to use any return error feature in your script. That's why I asked you about it :)

Twinny 09-29-2006 11:10 AM

Well - the error feature basically is the 'nem' for instance. The script checks the return. If it is 'nem' then it displays it's own custom error message. What error feature would you be expecting? =o

[Edit]: For those who don't know to use RC commands simply type /npc <command> into RC. eg. /npc interest. If your account matches the test i've added then it will do the command.

xAndrewx 09-29-2006 06:32 PM

Quote:

Originally Posted by Twinny (Post 1223609)
Well - the error feature basically is the 'nem' for instance. The script checks the return. If it is 'nem' then it displays it's own custom error message. What error feature would you be expecting? =o

You don't use this feature in your script, this is what I am saying...

JkWhoSaysNi 09-29-2006 07:08 PM

I use return on almost every function. I'm used to programming in OO languages and I learned OO in Eiffel where "deign by contract" is a major philosopy. Basically means making sure the function can go ahead with the data it's been given (preconditions) and then making sure it's completed successfully (postconditions) the only real way to implement this in GS is return codes on functions. (Check my associative array class for example)

In GS it's best to use numbers imho for the following reasons:

1) You can use if (function()) {} for functions that return 1 or 0.
2) You can use if (function() > 3) {} and make error checks in a sensible order. E.g. in this case the first 3 errors are acceptable.
3) Comparing strings is more CPU intensive than comparing integers.

xAndrewx 09-29-2006 10:04 PM

Quote:

Originally Posted by JkWhoSaysNi (Post 1223767)
I use return on almost every function. I'm used to programming in OO languages and I learned OO in Eiffel where "deign by contract" is a major philosopy. Basically means making sure the function can go ahead with the data it's been given (preconditions) and then making sure it's completed successfully (postconditions) the only real way to implement this in GS is return codes on functions. (Check my associative array class for example)

In GS it's best to use numbers imho for the following reasons:

1) You can use if (function()) {} for functions that return 1 or 0.
2) You can use if (function() > 3) {} and make error checks in a sensible order. E.g. in this case the first 3 errors are acceptable.
3) Comparing strings is more CPU intensive than comparing integers.

Everyone to their own. I prefer Skyld's methods!

Twinny 09-30-2006 06:54 AM

If i post a gui bank client - it will make use of the new returns.

xAndrewx 09-30-2006 08:24 AM

That's an If :p
I'm only questioning it, because you've used it yet not explained how it works. Other than that, cool :)

Crono 09-30-2006 03:29 PM

man i rock you all at scripting

nice bank system, + rep

Twinny 10-01-2006 04:09 AM

Woo thanks Gerami <3. Good to be acknowledged by the master >_<


All times are GMT +2. The time now is 03:40 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.