ironsphererpg/scripts/rpgstats.cs
Jusctsch5 de1a1c2204 T2RPG: Increase xp gain by 1.5x
For a faster game.
2015-01-18 21:36:40 -06:00

434 lines
12 KiB
C#

function fetchdata(%client, %type)
{
return game.fetchdata(%client, %type);
}
function RPGGame::fetchData(%game, %client, %type)
{
//param is optional.
if(%type $= "LVL")
{
%a = GetLevel(fetchData(%client, "EXP"), %client);
return %a;
}
else if(%type $= "DEF")
{
%a = AddPoints(%client, 7);
//%b = AddBonusStatePoints(%client, "DEF");
//%c = CombineRpgRolls(%a, %b, 0, "inf");
return %a;
}
else if(%type $= "MDEF")
{
%a = AddPoints(%client, 3);
//%b = AddBonusStatePoints(%client, "MDEF");
//%c = CombineRpgRolls(%a, %b, 0, "inf");
//%d = (fetchData(%client, "OverweightStep") * 7.0) / 100;
//%e = Cap(%c - (%c * %d), 0, "inf");
return %a;
}
else if(%type $= "ATK")
{
%a = AddPoints(%client, 6);
//%b = AddBonusStatePoints(%client, "ATK");
//%c = CombineRpgRolls(%a, %b, 0, "inf");
return %a;
%weapon = (%client.player.getMountedImage($WeaponSlot) == 0) ? "" : %client.player.getMountedImage($WeaponSlot).getName().item;
if(%weapon !$= "")
{
//%a = AddBonusStatePoints(%client, "ATK");
if(GetAccessoryVar(%weapon, $AccessoryType) $= $RangedAccessoryType)
%weapon = fetchData(%client, "LoadedProjectile " @ %weapon);
%b = GetRpgRoll(GetWord(GetAccessoryVar(%weapon, $SpecialVar), 1));
return %a + %b;
}
else
return 0;
}
else if(%type $= "MaxHP")
{
%a = $MinHP[fetchData(%client, "RACE")];
%b = AddPoints(%client, 4);
if(!%client.isaicontrolled())
%c = fetchData(%client, "LVL") * $HPPerLvl[fetchdata(%client, "class")];
//%d = $minHP[fetchdata(%client, "RACE")];
%e = %client.data.PlayerSkill[$SkillEndurance] * 0.5;
%total = mfloor(%a + %b + %c + %d + %e);
if(%total <= 1) %total = 1;
return %total;
}
else if(%type $= "HP")
{
%armor = %client.player.getDataBlock();
%c = %armor.maxDamage - %client.player.getDamageLevel();
%a = %c * fetchData(%client, "MaxHP");
%b = %a / %armor.maxDamage;
return round(%b);
}
else if(%type $= "MaxMANA")
{
%a = 8 + round( ((%client.data.PlayerSkill[$skill::OffensiveCasting] + %client.data.PlayerSkill[$skill::DefensiveCasting] + %client.data.PlayerSkill[$skill::NeutralCasting] )/2 + (%client.data.PlayerSkill[$skill::Focus] + %client.data.PlayerSkill[$skill::bashing] + %client.data.playerSkill[$skill::backstabbing] + %client.data.playerSkill[$skill::cleaving] )/12 ) * (1/3) );
%b = AddPoints(%client, 5);
//%c = AddBonusStatePoints(%client, "MaxMANA");
return %a + %b;
}
else if(%type $= "MANA")
{
%armor = %client.player.getDataBlock();
%a = %client.player.getEnergyLevel() * fetchData(%client, "MaxMANA");
%b = %a / %armor.maxEnergy;
return round(%b);
}
else if(%type $= "MaxWeight")
{
%a = 50 + %client.data.PlayerSkill[$SkillWeightCapacity];
//%b = AddPoints(%client, 9);
//%c = AddBonusStatePoints(%client, "MaxWeight");
return %a;
}
else if(%type $= "Weight")
{
return GetWeight(%client);
}
else if(%type $= "RankPoints")
{
return Cap(mfloor(%client.data.ClientData[%type]), 0, "inf");
}
else if(%type $= "OverweightStep")
{
return Cap(mfloor(%client.data.ClientData[%type]), 0, "inf");
}
else if(%type $= "inventory")
{
return %client.data.itemlist;
}
else
return %client.data.ClientData[%type];
return false;
}
function storedata(%client, %type, %amt, %special)
{
return Game.storedata(%client, %type, %amt, %special);
}
function RPGGame::storeData(%game, %client, %type, %amt, %special)
{
if(%type $= "HP")
{
setHP(%client, %amt);
}
else if(%type $= "MANA")
{
setMANA(%client, %amt);
}
else if(%type $= "MaxHP" || %type $= "MaxMANA" || %type $= "MaxWeight" || %type $= "Weight")
{
echo("Invalid call to storeData for " @ %type @ " : Can't manually set this variable.");
return false;
}
else
{
if(%special $= "inc")
%client.data.ClientData[%type] += %amt;
else if(%special $= "dec")
%client.data.ClientData[%type] -= %amt;
else if(%special $= "strinc")
%client.data.ClientData[%type] = %client.data.ClientData[%type] @ %amt;
else
%client.data.ClientData[%type] = %amt;
if(GetWord(%special, 1) $= "cap")
%client.data.ClientData[%type] = Cap(%client.data.ClientData[%type], GetWord(%special, 2), GetWord(%special, 3));
if(%type $= "Coins") commandToClient(%client, 'SetCoins', %client.data.ClientData["coins"]);
}
return true;
}
function Client::storedata(%client, %type, %amt, %special)
{
return storedata(%client, %type, %amt, %special);
}
function ServerCmdFetchData(%client, %type)
{
//max out the calls to 30 every min. This is to prevent people from accidentally lagging out the server.
%max = 30;
if(%client.fetchqueuee == 0)
{
%client.fetchqueuee = 1;
%client.fetchqueue = initqueue(%max);
for(%i = 0; %i<%max; %i++)
%client.fetchqueue.push(0);//zero it out
}//init the time queue
%time = getTime();
if(%time - %client.fetchqueue.get() <= 60)
return;
%client.fetchqueue.pop();//pop one out of the queue.
%client.fetchqueue.push(%time);//push another on.
commandToClient(%client, 'fetchdata', fetchdata(%client, %type));
}
//Due to problems with decimal precision, a mathematical way of calculating levels is not satisfactory.
//I came up with a geometric series of which I have not yet been able to find an algorithm for.
//The series is as follows:
//0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
//You will notice that any number can be determined by adding the two previous ones together. It seems
//an algorithm would be simple to find since there is a relation between the numbers, but it's still a
//tough one that I haven't been able to crack.
//I created a look-up table that used this series, but unfortunately the numbers grew too large at around
//level 40. I will be using the old method suggested by Rykoffe a few years ago in T1RPG (long before the
//TRPG AD&D days). This method is mathematical and uses the y = ax + ax^2 formula, but I will be using
//a look-up table nonetheless in order to conserve precision. I programmed the GetLevel function to
//hop around the table in an efficient enough way (always 1 hop, otherwise the table is looked at from the beginning).
//(later date) My dad (a research scientist) did some research on the initial series metionned in the first paragraph
//for me and it turns out it's a famous sequence that dates back to 1202 called the Fibonnaci sequence (quite
//appropriate considering this game is based around then). Only much later did anyone figure out the equation:
//a(k) = (1 / msqrt(5)) * [ mpow(((1 + msqrt(5)) / 2), k) - mpow(((1 - msqrt(5)) / 2), k) ]
//Unfortunately, Tribes2 math doesn't support numbers above or equal to one million, so I'll have to stick with the
//other formula (y = ax + ax^2)
//Generate look-up table:
$MaxLevel = 110;
//%exptablea = 100;
//for(%i = 1; %i <= $MaxLevel; %i++)
// $ExpTable[%i] = mfloor(%exptablea * (%i-1) + (%exptablea * mpow((%i-1), 2)));
function GetLevel(%ex, %client)
{
if(%ex < (100)*1000 || %client.isaicontrolled())
return mfloor(%ex/1000)+1;
else
{
%ex -= 99000;
%ex /= 1000;
%lvl = (msqrt(8*%ex+1)-1)/2;
return mfloor(%lvl)+100;
}
return mfloor(%ex/1000)+1;
}
function GetEXP(%level, %client)
{
if(%level <= 100 || %client.isaicontrolled())
return ((%level-1)*1000);
else
{
%l2 = %level - 100;
%totalexp = 99*1000;
%totalexp += (%l2*(%l2+1)/2)*1000;
return %totalexp;
}
}
function DistributeExpForKilling(%damagedClient)
{
%ai = %damagedClient.isAiControlled();
if(%damagedClient.despawning)
return;
%dname = %damagedClient.nameBase;
%dlvl = fetchData(%damagedClient, "LVL");
%dexp = fetchData(%damagedClient, "EXP");
if(!%ai)
return;
%count = 0;
//parse .damagedBy and create %finalDamagedBy
%nameCount = 0;
%listCount = 0;
%total = 0;
%tmpl = "";
for(%i = 1; %i <= $maxDamagedBy; %i++)
{
if(%damagedClient.damagedBy[%i] !$= "")
{
%listCount++;
%n = firstWord(%damagedClient.damagedBy[%i]);
%d = GetWord(%damagedClient.damagedBy[%i], 1);
%flag = 0;
for(%z = 1; %z <= %nameCount; %z++)
{
if(%finalDamagedBy[%z] $= %n)
{
%flag = 1;
%dCounter[%n] += %d;
}
}
if(%flag $= 0)
{
%nameCount++;
%finalDamagedBy[%nameCount] = %n;
%dCounter[%n] = %d;
%p = IsInWhichParty(%n);
if(%p != false)
{
%id = firstWord(%p);
//%inv = GetWord(%p, 1);
if(%id != false)
{
%tmppartylist[%id] = %tmppartylist[%id] @ %n @ " ";
if(strstr(%tmpl, %id @ " ") $= -1)
%tmpl = %tmpl @ %id @ " ";
}
}
}
%total += %d;
}
}
//clear .damagedBy
for(%i = 1; %i <= $maxDamagedBy; %i++)
%damagedClient.damagedBy[%i] = "";
//parse thru all tmppartylists and determine the number of same party members involved in exp split
for(%w = 0; (%a = GetWord(%tmpl, %w)) !$= ""; %w++)
{
%n = countWords(%tmppartylist[%a]);
for(%ww = 0; (%aa = GetWord(%tmppartylist[%a], %ww)) !$= ""; %ww++)
%partyFactor[%aa] = %n;
}
//distribute exp
for(%i = 1; %i <= %nameCount; %i++)
{
if(%finalDamagedBy[%i] !$= "")
{
%listClientId = %finalDamagedBy[%i];//should be this way, dont store the name in the damaged by list
%slvl = fetchData(%listClientId, "LVL");
if(%slvl > 0)
%sfactor = 4 / %slvl+1;
else
%sfactor = 5;
%value = 60 - (%slvl - %dlvl)*10;
%value *= 2;
%value *= %sfactor;
if(%value < 2) %value = 2;
//if it goes as planned, we will mutliply value by sfactor (which is a value always greater than one.)
%perc = %dCounter[%finalDamagedBy[%i]] / %total;
//if(!%listClientId.isAiControlled())
//echo(%damagedclient.rpgname SPC %sfactor SPC %sfactor*%value SPC %value SPC %perc SPC %value*%perc);
%final = round( %value * %perc );
//determine party exp
%pf = %partyFactor[%finalDamagedBy[%i]]-1;
if(%pf >= 1)
%pvalue = round(%final * (1.0 * (%pf * 0.1)));
else
%pvalue = 0;
%final = round(%final/1.5);
storeData(%listClientId, "EXP", %final, "inc");
if(%final > 0)
messageClient(%listClientId, 'DistributeExp', $MsgBlue @ %dname @ " has died and you gained " @ %final @ " experience!");
else if(%final < 0)
messageClient(%listClientId, 'DistributeExp', $MsgRed @ %dname @ " has died and you lost " @ -%final @ " experience.");
else if(%final $= 0)
messageClient(%listClientId, 'DistributeExp', $MsgLightGray @ %dname @ " has died.");
if(%pvalue > 0)
{
storeData(%listClientId, "EXP", %pvalue, "inc");
messageClient(%listClientId, 'DistributeExp', $MsgBlue @ "You have gained " @ %pvalue @ " party experience!");
}
RefreshExp(%listClientId);
}
}
RefreshExp(%damagedClient);
}
/// weight functions
function GetWeight(%client)
{
return %client.weight;
}
function WeightStep(%client, %skill)
{
if(!%client.player || %client.isaicontrolled() || !fetchdata(%client, "HasLoadedAndSpawned")) return;
%weightfactor = Game.fetchdata(%client, "Weight") / Game.fetchdata(%client, "MaxWeight");
if(%weightfactor < 1) %weightfactor = 1;
%penalty = (%weightfactor-1)*200; //1=1 1.5 = 0
%speedfactor = (100-%penalty)/100;
if(%speedfactor < 0) %speedfactor = 0;
%sf = round((1-%speedfactor)*50);
%sf += 50 - AddPoints(%client, 12);
if(fetchdata(%client, "surge"))
%sf -= 10;
if(%sf < 0) %sf = 0;
if(%sf > $maxarmor-1) %sf = $maxarmor-1;
//echo(%sf SPC %client.rpgname);
%client.cweight = %sf;
//echo(%sf SPC %client);
if(%client.lastweight != %sf)
{
%race = fetchdata(%client, "RACE");
%race = "MaleHuman";//until femalehuman is put in
%apm = "Armor";
%dbname = %race @ %apm @ %sf;
%e = %client.player.getEnergyLevel();
%d = %client.player.getDamageLevel();
%client.player.setdatablock(%dbname);
%client.player.setEnergyLevel(%e);
%client.player.setDamageLevel(%d);
}
%client.lastweight = %sf;
if(%skill)
{
UseSkill(%client, $Skill::WeightCapacity, true, true, 50, true);
}
}
function weightcall(%client)
{
if(!%client.isaicontrolled())
{
cancel(%client.weightstepcall);//incase of irriterations
WeightStep(%client, true);
%client.weightstepcall = schedule(25000, %client, "WeightCall", %client, 1);
}
}