mirror of
https://github.com/Jusctsch5/ironsphererpg.git
synced 2026-01-19 19:44:45 +00:00
434 lines
12 KiB
C#
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);
|
|
}
|
|
}
|