Update for PRC8 function updates
Update for PRC8 function updates. Full compile. Updated release archive.
This commit is contained in:
parent
34f69e3221
commit
09d0100931
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
*.mod
|
||||||
|
*.tlk
|
||||||
*.hak
|
*.hak
|
||||||
*.md5
|
*.md5
|
||||||
|
4
_content/Compiler - Top Hak.bat
Normal file
4
_content/Compiler - Top Hak.bat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
:loop
|
||||||
|
"C:\NWN Work\nwnsc.exe" -o -w -n "C:\Games\Steam\steamapps\common\Neverwinter Nights" -i "D:\NWN Repos\Battledale_PRC8\_content\prc8_battle_top";"D:\NWN Repos\PRC8\nwn\nwnprc\trunk\include" "D:\NWN Repos\Battledale_PRC8\_content\prc8_battle_top\*.nss"
|
||||||
|
if %errorLevel% == -1 goto :loop
|
||||||
|
pause
|
293
_content/prc8_battle_top/jw_exp_functions.nss
Normal file
293
_content/prc8_battle_top/jw_exp_functions.nss
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
#include "prc_inc_racial"
|
||||||
|
|
||||||
|
// returns TRUE if the PC qualifies for a multiclass penalty, FALSE if not
|
||||||
|
int Multipen(object oPC);
|
||||||
|
// Returns a float which can be more than 1 if the mob is higher level than the party, and less than
|
||||||
|
// 1 if it is lower level than the party. nDifference should be the difference between party level
|
||||||
|
// and mob CR
|
||||||
|
float getmodifier (int nDifference);
|
||||||
|
// Returns TRUE if the PC already has enough xp to take them to a level higher than they currently are
|
||||||
|
int PCHasExpToLevel(object oObject);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Multipen(object oPC)
|
||||||
|
{
|
||||||
|
int nClass1=GetClassByPosition(1,oPC);
|
||||||
|
int nClass2=GetClassByPosition(2,oPC);
|
||||||
|
int nClass3=GetClassByPosition(3,oPC);
|
||||||
|
int nClass4=GetClassByPosition(4,oPC);
|
||||||
|
int nClass5=GetClassByPosition(5,oPC);
|
||||||
|
int nClass6=GetClassByPosition(6,oPC);
|
||||||
|
int nClass7=GetClassByPosition(7,oPC);
|
||||||
|
int nClass8=GetClassByPosition(8,oPC);
|
||||||
|
|
||||||
|
|
||||||
|
//::: Yeah, not doing this bullshit -Jaysyn
|
||||||
|
/* if ((nClass1==CLASS_TYPE_ARCANE_ARCHER)||(nClass1==CLASS_TYPE_ASSASSIN)|| (nClass1==CLASS_TYPE_BLACKGUARD)||(nClass1==CLASS_TYPE_HARPER)||(nClass1==CLASS_TYPE_SHADOWDANCER)||(nClass1==CLASS_TYPE_ANIMAL)||(nClass1==CLASS_TYPE_DIVINECHAMPION)||(nClass1==CLASS_TYPE_DRAGONDISCIPLE)||(nClass1==CLASS_TYPE_DWARVENDEFENDER)||(nClass1==CLASS_TYPE_PALEMASTER)||(nClass1==CLASS_TYPE_SHIFTER)||(nClass1==CLASS_TYPE_WEAPON_MASTER))
|
||||||
|
{
|
||||||
|
nClass1=CLASS_TYPE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nClass2==CLASS_TYPE_ARCANE_ARCHER)||(nClass2==CLASS_TYPE_ASSASSIN)|| (nClass2==CLASS_TYPE_BLACKGUARD)||(nClass2==CLASS_TYPE_HARPER)||(nClass2==CLASS_TYPE_SHADOWDANCER)||(nClass2==CLASS_TYPE_ANIMAL)||(nClass2==CLASS_TYPE_DIVINECHAMPION)||(nClass2==CLASS_TYPE_DRAGONDISCIPLE)||(nClass2==CLASS_TYPE_DWARVENDEFENDER)||(nClass2==CLASS_TYPE_PALEMASTER)||(nClass2==CLASS_TYPE_SHIFTER)||(nClass2==CLASS_TYPE_WEAPON_MASTER))
|
||||||
|
{
|
||||||
|
nClass2=CLASS_TYPE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nClass3==CLASS_TYPE_ARCANE_ARCHER)||(nClass3==CLASS_TYPE_ASSASSIN)|| (nClass3==CLASS_TYPE_BLACKGUARD)||(nClass3==CLASS_TYPE_HARPER)||(nClass3==CLASS_TYPE_SHADOWDANCER)||(nClass3==CLASS_TYPE_ANIMAL)||(nClass3==CLASS_TYPE_DIVINECHAMPION)||(nClass3==CLASS_TYPE_DRAGONDISCIPLE)||(nClass3==CLASS_TYPE_DWARVENDEFENDER)||(nClass3==CLASS_TYPE_PALEMASTER)||(nClass3==CLASS_TYPE_SHIFTER)||(nClass3==CLASS_TYPE_WEAPON_MASTER))
|
||||||
|
{
|
||||||
|
nClass3=CLASS_TYPE_INVALID;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int nLevel1=GetLevelByClass(nClass1,oPC);
|
||||||
|
int nLevel2=GetLevelByClass(nClass2,oPC);
|
||||||
|
int nLevel3=GetLevelByClass(nClass3,oPC);
|
||||||
|
int nLevel4=GetLevelByClass(nClass4,oPC);
|
||||||
|
int nLevel5=GetLevelByClass(nClass5,oPC);
|
||||||
|
int nLevel6=GetLevelByClass(nClass6,oPC);
|
||||||
|
int nLevel7=GetLevelByClass(nClass7,oPC);
|
||||||
|
int nLevel8=GetLevelByClass(nClass8,oPC);
|
||||||
|
|
||||||
|
int nRace = GetRacialType(oPC);
|
||||||
|
|
||||||
|
int nFavoured;
|
||||||
|
|
||||||
|
// favoured == 99 means any
|
||||||
|
|
||||||
|
int nProblem1 = 0;
|
||||||
|
int nProblem2 = 0;
|
||||||
|
int nProblem3 = 0;
|
||||||
|
|
||||||
|
int nPenalty = 0;
|
||||||
|
|
||||||
|
if (nRace==RACIAL_TYPE_DWARF) //RACIAL_TYPE_DWARF
|
||||||
|
{nFavoured=CLASS_TYPE_FIGHTER;}
|
||||||
|
|
||||||
|
if (nRace==RACIAL_TYPE_ELF) //RACIAL_TYPE_elf
|
||||||
|
{nFavoured=CLASS_TYPE_WIZARD;}
|
||||||
|
|
||||||
|
if (nRace== RACIAL_TYPE_GNOME) //RACIAL_TYPE_gnome
|
||||||
|
{nFavoured=CLASS_TYPE_WIZARD;}
|
||||||
|
|
||||||
|
if (nRace==RACIAL_TYPE_HALFLING) //RACIAL_TYPE_halfling
|
||||||
|
{nFavoured=CLASS_TYPE_ROGUE;}
|
||||||
|
|
||||||
|
if (nRace== RACIAL_TYPE_HALFELF) //RACIAL_TYPE_halfelf
|
||||||
|
{nFavoured=99;}
|
||||||
|
|
||||||
|
if (nRace== RACIAL_TYPE_HALFORC) //RACIAL_TYPE_halforc
|
||||||
|
{nFavoured=CLASS_TYPE_BARBARIAN;}
|
||||||
|
|
||||||
|
if (nRace== RACIAL_TYPE_HUMAN) //RACIAL_TYPE_human
|
||||||
|
{nFavoured=99;}
|
||||||
|
|
||||||
|
if (nRace== RACIAL_TYPE_ANIMAL) //RACIAL_TYPE_animal
|
||||||
|
{nFavoured=99;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// first of all, check to see if the classes are roughly equal
|
||||||
|
int nEqual=0;
|
||||||
|
// as long as nEqual==0, they are roughly level.
|
||||||
|
|
||||||
|
|
||||||
|
if ((nClass1!=CLASS_TYPE_INVALID)&&(nClass2!=CLASS_TYPE_INVALID))
|
||||||
|
{
|
||||||
|
if ((nLevel1-nLevel2>1)||(nLevel2-nLevel1>1)) //the difference between class 1 and 2 is more than 1
|
||||||
|
|
||||||
|
{
|
||||||
|
nEqual=1;
|
||||||
|
nProblem1=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((nClass1!=CLASS_TYPE_INVALID)&&(nClass3!=CLASS_TYPE_INVALID))
|
||||||
|
{
|
||||||
|
if ((nLevel1-nLevel3>1)||(nLevel3-nLevel1>1)) //the difference between class 1 and 3 is more than 1
|
||||||
|
|
||||||
|
{
|
||||||
|
nEqual=1;
|
||||||
|
nProblem2=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((nClass2!=CLASS_TYPE_INVALID)&&(nClass3!=CLASS_TYPE_INVALID))
|
||||||
|
{
|
||||||
|
if ((nLevel2-nLevel3>1)||(nLevel3-nLevel2>1)) //the difference between class 1 and 2 is more than 1
|
||||||
|
|
||||||
|
{
|
||||||
|
nEqual=1;
|
||||||
|
nProblem3=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if there is no problem here, return zero
|
||||||
|
if (nEqual==0)
|
||||||
|
{
|
||||||
|
return nPenalty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// classes are unequal but are any of the unequal classes favoured?
|
||||||
|
// do humans and half elves first
|
||||||
|
if (nFavoured==99)
|
||||||
|
{
|
||||||
|
if ((nProblem1==1)&&(nProblem2==1)&&(nProblem3==1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// now do everyone else
|
||||||
|
|
||||||
|
if (nProblem1==1)
|
||||||
|
{
|
||||||
|
if ((nClass1!=nFavoured)&&(nClass2!=nFavoured))
|
||||||
|
{
|
||||||
|
nPenalty=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nProblem2==1)
|
||||||
|
{
|
||||||
|
if ((nClass1!=nFavoured)&&(nClass3!=nFavoured))
|
||||||
|
{
|
||||||
|
nPenalty=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nProblem3==1)
|
||||||
|
{
|
||||||
|
if ((nClass2!=nFavoured)&&(nClass3!=nFavoured))
|
||||||
|
{
|
||||||
|
nPenalty=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nPenalty;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float getmodifier (int nDifference)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// works out the modified for xp, based on the difference between the player or average party level and
|
||||||
|
// the cr of the mob.
|
||||||
|
|
||||||
|
float fModifier;
|
||||||
|
|
||||||
|
if (nDifference <= -7)
|
||||||
|
{
|
||||||
|
fModifier=1.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -6)
|
||||||
|
{
|
||||||
|
fModifier=1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -5)
|
||||||
|
{
|
||||||
|
fModifier=1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -4)
|
||||||
|
{
|
||||||
|
fModifier=1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -3)
|
||||||
|
{
|
||||||
|
fModifier=1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -2)
|
||||||
|
{
|
||||||
|
fModifier=1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == -1)
|
||||||
|
{
|
||||||
|
fModifier=1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (nDifference == 0)
|
||||||
|
{
|
||||||
|
fModifier=1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 1)
|
||||||
|
{
|
||||||
|
fModifier=1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 2)
|
||||||
|
{
|
||||||
|
fModifier=0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 3)
|
||||||
|
{
|
||||||
|
fModifier=0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 4)
|
||||||
|
{
|
||||||
|
fModifier=0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 5)
|
||||||
|
{
|
||||||
|
fModifier=0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 6)
|
||||||
|
{
|
||||||
|
fModifier=0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 7)
|
||||||
|
{
|
||||||
|
fModifier=0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 8)
|
||||||
|
{
|
||||||
|
fModifier=0.03;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference == 9)
|
||||||
|
{
|
||||||
|
fModifier=0.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDifference >= 10)
|
||||||
|
{
|
||||||
|
fModifier=0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PCHasExpToLevel(object oObject)
|
||||||
|
{
|
||||||
|
int nHD = GetHitDice(oObject)+1;
|
||||||
|
//xp needed to be level nHD
|
||||||
|
int nXPNeeded = ((nHD * (nHD - 1)) / 2) * 1000;
|
||||||
|
if (GetXP(oObject)>=nXPNeeded)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
339
_content/prc8_battle_top/jw_exp_giver.nss
Normal file
339
_content/prc8_battle_top/jw_exp_giver.nss
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
#include "jw_exp_functions"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void givexp(object oMob,object oPC)
|
||||||
|
{
|
||||||
|
|
||||||
|
//KillAndReplaceLootable(OBJECT_SELF, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
float fCR;
|
||||||
|
|
||||||
|
if (GetLocalInt(OBJECT_SELF,"is_clone")==TRUE)
|
||||||
|
{
|
||||||
|
fCR=IntToFloat(GetHitDice(oMob))-1;
|
||||||
|
if (fCR<1.0)
|
||||||
|
{
|
||||||
|
fCR=1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
{
|
||||||
|
fCR=GetChallengeRating(oMob);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nNumber gives you the number of players in the party. No penalty for using summoned mobs
|
||||||
|
// nHDcounter is the total HD of the party (players only)
|
||||||
|
// nHighlevel is the level of the highest person in the party;
|
||||||
|
|
||||||
|
int nNumber=0;
|
||||||
|
int nHDcounter=0;
|
||||||
|
int nHighlevel=1;
|
||||||
|
int nHD;
|
||||||
|
|
||||||
|
if (GetIsObjectValid(GetMaster(oPC)))
|
||||||
|
{
|
||||||
|
oPC=GetMaster(oPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetIsPC(oPC))
|
||||||
|
{
|
||||||
|
oPC=GetTrapCreator(oPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetIsPC(oPC))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
object oObject = GetFirstFactionMember(oPC, TRUE);
|
||||||
|
while (GetIsObjectValid(oObject) == TRUE)
|
||||||
|
{
|
||||||
|
nHD=GetHitDice(oObject);
|
||||||
|
nNumber++;
|
||||||
|
|
||||||
|
nHDcounter=nHDcounter+nHD;
|
||||||
|
if (nHD>nHighlevel)
|
||||||
|
{
|
||||||
|
nHighlevel=nHD;
|
||||||
|
}
|
||||||
|
oObject = GetNextFactionMember(oPC, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the party has no members for some reason, return;
|
||||||
|
if (nNumber==0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// the average level of the party is the total HD divided by the number of people
|
||||||
|
|
||||||
|
float fTotalHD=IntToFloat(nHDcounter);
|
||||||
|
float fAvlevel=fTotalHD/nNumber;
|
||||||
|
float fHighlevel=IntToFloat(nHighlevel);
|
||||||
|
float fLevel;
|
||||||
|
|
||||||
|
// the party level used to generate a level which xp is based on is fLevel.
|
||||||
|
// This is the avererage party level plus the highest level in the party divided by two.
|
||||||
|
// Eg if the average level is 5 but there is a level 10 in there, the party is
|
||||||
|
// treated as being level 7.5.
|
||||||
|
|
||||||
|
if (fHighlevel>fAvlevel)
|
||||||
|
{
|
||||||
|
fLevel=(fHighlevel+fAvlevel)/2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fLevel=fAvlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fDifference is the party level we are using minus the challenge rating of the creature.
|
||||||
|
// so a level 7 mob killed by a level 9 group will have an fDifference of two.
|
||||||
|
// This indicates that the mob was a fairly easy challenge.
|
||||||
|
|
||||||
|
float fDifference=fLevel-fCR;
|
||||||
|
|
||||||
|
int nDifference=FloatToInt(fDifference);
|
||||||
|
|
||||||
|
// if the difference was more than 11, nobody gets anything.
|
||||||
|
|
||||||
|
if (nDifference>11)
|
||||||
|
{
|
||||||
|
oObject = GetFirstFactionMember(oPC, TRUE);
|
||||||
|
while (GetIsObjectValid(oObject) == TRUE)
|
||||||
|
{
|
||||||
|
SendMessageToPC(oObject,"Your party gains no experience from defeating "+GetName(oMob));
|
||||||
|
oObject = GetNextFactionMember(oPC, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This calls the function at the top to check out how much the xp reward should
|
||||||
|
// be modified, based on fDifference. If fDifference is a positive number, then the
|
||||||
|
// modifier is less than one.
|
||||||
|
// For example, if the difference is four then the party will only get 0.3 experience
|
||||||
|
// for every one point of experience they could have earned if they were the same
|
||||||
|
// level as this mob.
|
||||||
|
// However if they are of a lower level than the mob, they get extra xp.
|
||||||
|
// It is worth fighting mobs of a higher level than yourself.
|
||||||
|
|
||||||
|
float fModifier = getmodifier(nDifference);
|
||||||
|
|
||||||
|
// The basic xp of any mob is it's challenge rating times 5.5. Ie first level mob gives 5.5
|
||||||
|
// second gives 11, 20th gives 110.
|
||||||
|
// A mob which is challenge rating 1/2 or 1/8 (such as kobolds level one and two
|
||||||
|
// or much of crypts level one) gives 5.0.
|
||||||
|
|
||||||
|
float fBasicxp;
|
||||||
|
|
||||||
|
if (fCR>=1.0)
|
||||||
|
{
|
||||||
|
fBasicxp=fCR*4.7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fBasicxp=4.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The exp will be shared out among the party. However the total xp pool
|
||||||
|
// is increased if the players are in a party. This is to lessen the bonus given
|
||||||
|
// to people who solo.
|
||||||
|
// A party of two will each get 80 per cent as much xp as either of them would have got for
|
||||||
|
// killing the mob solo.
|
||||||
|
// A party of 3 will each get 73 per cent of the exp which
|
||||||
|
// any of them would have got for killing the mob solo.
|
||||||
|
// solo. A party of six each gets 0.50 per cent of the exp they would have got if
|
||||||
|
// they had killed the mob solo.
|
||||||
|
// This means there is a great advantage to being in a party, as you can kill more mobs
|
||||||
|
// yet still get good exp.
|
||||||
|
// These figures ignore the adjustments from the levels of the players in the party.
|
||||||
|
// if more than four people are in the party, any future people do not add to the bonus.
|
||||||
|
|
||||||
|
float fPartybonus=1.0;
|
||||||
|
|
||||||
|
if (nNumber>1)
|
||||||
|
{
|
||||||
|
fPartybonus=(IntToFloat(nNumber));
|
||||||
|
fPartybonus=fPartybonus-1.0;
|
||||||
|
if (fPartybonus>4.0)
|
||||||
|
{
|
||||||
|
fPartybonus=4.0;
|
||||||
|
}
|
||||||
|
fPartybonus=fPartybonus*0.4;
|
||||||
|
fPartybonus=fPartybonus+1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the xp to be shared between the party is the xp the mob is worth (challenge rating times 4)
|
||||||
|
// times the modifer for the level difference (up or down depending on mob CR compared to party level)
|
||||||
|
// times any party modifier (up if the players are in a party)
|
||||||
|
|
||||||
|
|
||||||
|
float fPartyxp=fBasicxp*fModifier*fPartybonus;
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
//SendMessageToAllDMs("fPartyxp "+FloatToString(fPartyxp)+" =fBasicxp "+FloatToString(fBasicxp)+" *fModifier "+FloatToString(fModifier)+ "*fPartybonus; "+FloatToString(fPartybonus));
|
||||||
|
|
||||||
|
// The xp for each player is then the partyxp divided by all the players (summoned
|
||||||
|
// creatures have no effect on this)
|
||||||
|
|
||||||
|
float fPlayerxp=fPartyxp/(IntToFloat(nNumber));
|
||||||
|
int nPlayerxp=FloatToInt(fPlayerxp);
|
||||||
|
|
||||||
|
// however we also want to make sure no players get more xp in a group
|
||||||
|
// than they would have done solo. This could happen if a high level char
|
||||||
|
// adventures with low level chars.
|
||||||
|
// no PC can ever get more exp than the strongest member of the faction could have got
|
||||||
|
// if they fought the mob solo
|
||||||
|
|
||||||
|
float fTestxp;
|
||||||
|
fDifference=fHighlevel-fCR;
|
||||||
|
nDifference=FloatToInt(fDifference);
|
||||||
|
fTestxp=fBasicxp*getmodifier(nDifference);
|
||||||
|
if (fPlayerxp>fTestxp)
|
||||||
|
{
|
||||||
|
fPlayerxp=fTestxp;
|
||||||
|
nPlayerxp=FloatToInt(fTestxp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fPlaydifference is going to be the difference between each PCs level and the highest level
|
||||||
|
// in the party
|
||||||
|
|
||||||
|
float fPlaydifference;
|
||||||
|
nHighlevel=FloatToInt(fHighlevel);
|
||||||
|
int nPlaylevel;
|
||||||
|
int nXPtogive;
|
||||||
|
float fMaxxp;
|
||||||
|
int nMaxxp;
|
||||||
|
|
||||||
|
oObject = GetFirstFactionMember(oPC, TRUE);
|
||||||
|
while (GetIsObjectValid(oObject) == TRUE)
|
||||||
|
{
|
||||||
|
|
||||||
|
// nDifference now is the level of each PC as we go through them in turn
|
||||||
|
// fTestxp is simply what they would have got if they killed the mob solo
|
||||||
|
nPlaylevel=GetHitDice(oObject);
|
||||||
|
nDifference=FloatToInt(IntToFloat(nPlaylevel)-fCR);
|
||||||
|
fTestxp=fPlayerxp;
|
||||||
|
|
||||||
|
// Work out the max xp a player of that level is allowed to get
|
||||||
|
// This is the xp they would have got for killing something 3 levels above themselves alone
|
||||||
|
|
||||||
|
fMaxxp=(fBasicxp*(IntToFloat(nPlaylevel)+2.0));
|
||||||
|
nMaxxp=FloatToInt(fMaxxp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fTestxp is equal to the XP each player will get if no modifications are needed.
|
||||||
|
|
||||||
|
// if the difference between the individual character and the mob is more than
|
||||||
|
// six, he gets no XP even if the party does.
|
||||||
|
// This system does leave open the possibility of high level chars helping
|
||||||
|
// low level chars. This is possibly open to abuse but is a deliberate
|
||||||
|
// feature to allow friends to adventure together even if they are of different
|
||||||
|
// levels.
|
||||||
|
|
||||||
|
if (GetArea(oPC)!=GetArea(oObject))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if (nDifference>11)
|
||||||
|
{
|
||||||
|
SendMessageToPC(oObject,"You cannot gain much experience for defeating "+GetName(oMob));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
// otherwise, they get the exp we calculated above as long as they are not dead.
|
||||||
|
if (GetCurrentHitPoints(oObject)>=1)
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
nXPtogive=nPlayerxp;
|
||||||
|
|
||||||
|
//if (nXPtogive<1)
|
||||||
|
// {
|
||||||
|
// nXPtogive=1;
|
||||||
|
// }
|
||||||
|
// If the character is travelling in a higher level party, they get a penalty
|
||||||
|
|
||||||
|
if (nPlaylevel<(FloatToInt(fLevel)-8))
|
||||||
|
{
|
||||||
|
nDifference=FloatToInt(fLevel)-nPlaylevel-8;
|
||||||
|
fPlaydifference=getmodifier(nDifference);
|
||||||
|
fTestxp=fPlayerxp*fPlaydifference;
|
||||||
|
nXPtogive=FloatToInt(fPlayerxp*fPlaydifference);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The server seems to be doing this on its own now
|
||||||
|
if (Multipen(oObject))
|
||||||
|
{
|
||||||
|
|
||||||
|
nXPtogive=FloatToInt(fTestxp*0.8);
|
||||||
|
SendMessageToPC(oObject,"Multiclass xp penalty affects you");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (nXPtogive>nMaxxp)
|
||||||
|
{
|
||||||
|
nXPtogive=nMaxxp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Now we give a bonus to lowbies
|
||||||
|
if (nPlaylevel<=3)
|
||||||
|
{
|
||||||
|
nXPtogive=nXPtogive*(5-nPlaylevel);
|
||||||
|
}
|
||||||
|
if (nXPtogive<2)
|
||||||
|
{
|
||||||
|
nXPtogive=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (GetIsObjectValid(GetItemPossessedBy(oObject,"jw_exp_book")))
|
||||||
|
{
|
||||||
|
SendMessageToPC(oObject,"The Scholar's Tome in your inventory ensures you do not gain experience");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ((PCHasExpToLevel(oObject)==TRUE)&&(nPlaylevel<=3))
|
||||||
|
{
|
||||||
|
SendMessageToPC(oObject,"You cannot gain any more experience this way until you train to your next level.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessageToPC(oObject,"You gain "+IntToString(nXPtogive)+" experience for defeating "+GetName(oMob));
|
||||||
|
GiveXPToCreature(oObject,nXPtogive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oObject = GetNextFactionMember(oPC, TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
56
_content/prc8_battle_top/jw_inc_spells.nss
Normal file
56
_content/prc8_battle_top/jw_inc_spells.nss
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//:: jw_inc_spells.nss
|
||||||
|
#include "x0_i0_transform"
|
||||||
|
|
||||||
|
// Trigger the nearest object with matching tag to convert.
|
||||||
|
// This should be called by the trigger object! It ASSUMES
|
||||||
|
// that GetEnteringObject() will work for OBJECT_SELF here.
|
||||||
|
void JWTriggerObjectTransform(string sCreature, int nVisualEffect=VFX_NONE, string sTag="tag_of_trigger");
|
||||||
|
|
||||||
|
int ScrollResist(object oCaster, object oTarget, float fDelay = 0.0);
|
||||||
|
|
||||||
|
int ScrollResist(object oCaster, object oTarget, float fDelay = 0.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
oCaster=GetObjectByTag("PR_Zacharias");
|
||||||
|
if (fDelay > 0.5)
|
||||||
|
{
|
||||||
|
fDelay = fDelay - 0.1;
|
||||||
|
}
|
||||||
|
int nResist = ResistSpell(oCaster, oTarget);
|
||||||
|
effect eSR = EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE);
|
||||||
|
effect eGlobe = EffectVisualEffect(VFX_IMP_GLOBE_USE);
|
||||||
|
effect eMantle = EffectVisualEffect(VFX_IMP_SPELL_MANTLE_USE);
|
||||||
|
if(nResist == 1) //Spell Resistance
|
||||||
|
{
|
||||||
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSR, oTarget));
|
||||||
|
}
|
||||||
|
else if(nResist == 2) //Globe
|
||||||
|
{
|
||||||
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eGlobe, oTarget));
|
||||||
|
}
|
||||||
|
else if(nResist == 3) //Spell Mantle
|
||||||
|
{
|
||||||
|
if (fDelay > 0.5)
|
||||||
|
{
|
||||||
|
fDelay = fDelay - 0.1;
|
||||||
|
}
|
||||||
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMantle, oTarget));
|
||||||
|
}
|
||||||
|
return nResist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the nearest object with matching tag to convert.
|
||||||
|
// This should be called by the trigger object! It ASSUMES
|
||||||
|
// that GetEnteringObject() will work for OBJECT_SELF here.
|
||||||
|
void JWTriggerObjectTransform(string sCreature, int nVisualEffect=VFX_NONE, string sTag="tag_of_trigger")
|
||||||
|
{
|
||||||
|
object oPC = GetEnteringObject();
|
||||||
|
if ( ! GetIsPC(oPC) ) { return; }
|
||||||
|
if (sTag=="tag_of_trigger")
|
||||||
|
{
|
||||||
|
sTag=GetTag(OBJECT_SELF);
|
||||||
|
}
|
||||||
|
object oOrigin = GetNearestObjectByTag(sTag);
|
||||||
|
TransformObjectToCreature(oOrigin, sCreature, nVisualEffect);
|
||||||
|
//DestroyObject(OBJECT_SELF, 5.0);
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -48,7 +48,7 @@ void main()
|
|||||||
nDamage = d6(14);
|
nDamage = d6(14);
|
||||||
nDC = 36;
|
nDC = 36;
|
||||||
|
|
||||||
PlayDragonBattleCry();
|
PRCPlayDragonBattleCry();
|
||||||
|
|
||||||
//Get first target in spell area
|
//Get first target in spell area
|
||||||
oTarget = GetFirstObjectInShape(SHAPE_SPELLCONE, 14.0, GetSpellTargetLocation(), TRUE);
|
oTarget = GetFirstObjectInShape(SHAPE_SPELLCONE, 14.0, GetSpellTargetLocation(), TRUE);
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
_content/prc8_battle_top/nw_s2_bardsong.ncs
Normal file
BIN
_content/prc8_battle_top/nw_s2_bardsong.ncs
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
405
_content/prc8_battle_top/wm_include.nss
Normal file
405
_content/prc8_battle_top/wm_include.nss
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
// WILD MAGIC SYSTEM by Lex
|
||||||
|
// Adapted to HCR system by Archaegeo
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
|
||||||
|
// Set MATERCOMP to 0 to not use material components for those spells that need.
|
||||||
|
object oMod=GetModule();
|
||||||
|
|
||||||
|
int MATERCOMP = 1;
|
||||||
|
|
||||||
|
// Indicates magical normality
|
||||||
|
int WM_NORMAL = 0;
|
||||||
|
// Indicates lack of magical energy
|
||||||
|
int WM_NULL = 1;
|
||||||
|
// Indicates erratic magical energy
|
||||||
|
int WM_WILD = 2;
|
||||||
|
|
||||||
|
// Checks to see whether the spell script should not continue normally.
|
||||||
|
// Use: if (WildMagicOverride()) { return; }
|
||||||
|
// The function should be able to figure out the three parameters on its own.
|
||||||
|
// If not, or if you are using it in a non-spell script, provide up to three
|
||||||
|
// objects involved in the check. Leave any unused parameters as OBJECT_INVALID
|
||||||
|
// to have them autodetect, or use the same object more than once.
|
||||||
|
// Should work in item activation scripts!
|
||||||
|
int WildMagicOverride(object oArea = OBJECT_INVALID,
|
||||||
|
object oCaster = OBJECT_INVALID,
|
||||||
|
object oTarget = OBJECT_INVALID);
|
||||||
|
|
||||||
|
// Similar to WildMagicOverride, but does not include Wild effects. Mostly used
|
||||||
|
// in situations where wild effects would be inappropriate, like in an AOE's
|
||||||
|
// heartbeat and OnEnter scripts.
|
||||||
|
int NullMagicOverride(object oArea = OBJECT_INVALID,
|
||||||
|
object oCaster = OBJECT_INVALID,
|
||||||
|
object oTarget = OBJECT_INVALID);
|
||||||
|
|
||||||
|
// Modifies the magic state of oTarget. nState is one of
|
||||||
|
// WM_NORMAL, WM_NULL, WM_WILD. Wild and Null magic stack, allowing
|
||||||
|
// you to safely add and remove these effects without interfering with
|
||||||
|
// other things that deal with these states. Modifying WM_NORMAL positively
|
||||||
|
// will decrease the wild and null effects that much, while modifying it
|
||||||
|
// negatively will remove all wild and null effects.
|
||||||
|
void SetWMState(object oTarget, int nState, int nAmount=1);
|
||||||
|
|
||||||
|
// Returns WM_NORMAL, WM_NULL, or WM_WILD.
|
||||||
|
// If the object is both wild and null, WM_NULL is returned.
|
||||||
|
int GetWMState(object oTarget);
|
||||||
|
|
||||||
|
// Creates a Wild Magic area of effect. Creatures in the AOE
|
||||||
|
// are considered Wild until they leave it.
|
||||||
|
// EXPERIMENTAL.
|
||||||
|
// Problems: Placeables don't seem to be affected by this,
|
||||||
|
// so spells can be cast into the AOE as long as they target
|
||||||
|
// either a placeable or a location.
|
||||||
|
effect EffectWildMagicAOE();
|
||||||
|
|
||||||
|
// Creates a Null Magic area of effect. Creatures in the AOE
|
||||||
|
// are considered null until they leave it.
|
||||||
|
// EXPERIMENTAL.
|
||||||
|
// Problems: Placeables don't seem to be affected by this,
|
||||||
|
// so spells can be cast into the AOE as long as they target
|
||||||
|
// either a placeable or a location.
|
||||||
|
effect EffectNullMagicAOE();
|
||||||
|
|
||||||
|
// Removes all magical effects on a target.
|
||||||
|
void RemoveMagicalEffects (object oTarget);
|
||||||
|
|
||||||
|
// Used by WildMagicOverride()
|
||||||
|
int GoWild(object oCaster, object oTarget, location lLocation);
|
||||||
|
|
||||||
|
// Used by GoWild()
|
||||||
|
void SpecialCast (int nSpell, object oTarget, location lLocation, int nCasterLevel, int nMetaMagic);
|
||||||
|
|
||||||
|
// A creature or placeable nearby oTarget is randomly
|
||||||
|
// chosen and returned. May return oTarget, especially
|
||||||
|
// if there are few objects nearby.
|
||||||
|
object GetRandomNearby(object oTarget=OBJECT_SELF);
|
||||||
|
|
||||||
|
// Used by GoWild()
|
||||||
|
void RandomCast();
|
||||||
|
|
||||||
|
// Checks for the old WM_STATE variable and makes the necessary
|
||||||
|
// adjustments. Called by Get and SetWMState, probably no use
|
||||||
|
// for it elsewhere.
|
||||||
|
void DoWMUpdate(object oTarget)
|
||||||
|
{
|
||||||
|
int nState = GetLocalInt(oTarget, "WM_STATE");
|
||||||
|
DeleteLocalInt(oTarget, "WM_STATE");
|
||||||
|
if (!nState) return;
|
||||||
|
SetWMState(oTarget, nState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWMState(object oTarget, int nState, int nAmount=1)
|
||||||
|
{
|
||||||
|
DoWMUpdate(oTarget);
|
||||||
|
if (nState < 0 || nState > 2) nState = 0;
|
||||||
|
if (nState == WM_NULL)
|
||||||
|
{
|
||||||
|
int x = GetLocalInt(oTarget, "MAGICSTATE_NULL") + nAmount;
|
||||||
|
if (x < 0) x = 0;
|
||||||
|
SetLocalInt(oTarget, "MAGICSTATE_NULL", x);
|
||||||
|
int nType = GetObjectType(oTarget);
|
||||||
|
// Dispel magical effects on the target
|
||||||
|
if (x > 0) RemoveMagicalEffects(oTarget);
|
||||||
|
}
|
||||||
|
else if (nState == WM_WILD)
|
||||||
|
{
|
||||||
|
int x = GetLocalInt(oTarget, "MAGICSTATE_WILD") + nAmount;
|
||||||
|
if (x < 0) x = 0;
|
||||||
|
SetLocalInt(oTarget, "MAGICSTATE_WILD", x);
|
||||||
|
}
|
||||||
|
else if (nState = WM_NORMAL)
|
||||||
|
{
|
||||||
|
if (nAmount > 0) {
|
||||||
|
SetWMState(oTarget, WM_NULL, -nAmount);
|
||||||
|
SetWMState(oTarget, WM_WILD, -nAmount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLocalInt(oTarget, "MAGICSTATE_NULL", 0);
|
||||||
|
SetLocalInt(oTarget, "MAGICSTATE_WILD", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetWMState(object oTarget)
|
||||||
|
{
|
||||||
|
DoWMUpdate(oTarget);
|
||||||
|
int nNull = GetLocalInt(oTarget, "MAGICSTATE_NULL");
|
||||||
|
if (nNull > 0) return WM_NULL;
|
||||||
|
int nWild = GetLocalInt(oTarget, "MAGICSTATE_WILD");
|
||||||
|
if (nWild > 0) return WM_WILD;
|
||||||
|
return WM_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NullMagicOverride(object oArea = OBJECT_INVALID,
|
||||||
|
object oCaster = OBJECT_INVALID,
|
||||||
|
object oTarget = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
int nModuleState = GetWMState(GetModule());
|
||||||
|
object oItem = GetItemActivated();
|
||||||
|
if (oItem == OBJECT_INVALID) oItem = PRCGetSpellCastItem();
|
||||||
|
int nItemState = GetWMState(oItem);
|
||||||
|
location lTargetLocation;
|
||||||
|
if (oCaster == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oCaster = GetLastSpellCaster();
|
||||||
|
lTargetLocation = PRCGetSpellTargetLocation();
|
||||||
|
}
|
||||||
|
if (oCaster == OBJECT_INVALID) {
|
||||||
|
oCaster = GetItemActivator();
|
||||||
|
lTargetLocation = GetItemActivatedTargetLocation();
|
||||||
|
}
|
||||||
|
if (oCaster == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oCaster = OBJECT_SELF;
|
||||||
|
lTargetLocation = GetLocation(OBJECT_SELF);
|
||||||
|
}
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = PRCGetSpellTargetObject();
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = GetItemActivatedTarget();
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = oCaster;
|
||||||
|
if (oArea == OBJECT_INVALID) oArea = GetArea(oCaster);
|
||||||
|
if (oArea == OBJECT_INVALID) oArea = GetArea(oTarget);
|
||||||
|
int nCasterState = GetWMState(oCaster);
|
||||||
|
int nTargetState = GetWMState(oTarget);
|
||||||
|
int nAreaState = GetWMState(oArea);
|
||||||
|
|
||||||
|
if (nModuleState == 1 ||
|
||||||
|
nItemState == 1 ||
|
||||||
|
nCasterState == 1 ||
|
||||||
|
nTargetState == 1 ||
|
||||||
|
nAreaState == 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (oTarget == oCaster)
|
||||||
|
{
|
||||||
|
object oInvis = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", lTargetLocation);
|
||||||
|
if (GetWMState(oInvis) == WM_NULL)
|
||||||
|
{
|
||||||
|
DestroyObject(oInvis);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
DestroyObject(oInvis);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WildMagicOverride(object oArea = OBJECT_INVALID,
|
||||||
|
object oCaster = OBJECT_INVALID,
|
||||||
|
object oTarget = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
int nModuleState = GetWMState(GetModule());
|
||||||
|
object oItem = GetItemActivated();
|
||||||
|
if (oItem == OBJECT_INVALID) oItem = PRCGetSpellCastItem();
|
||||||
|
int nItemState = GetWMState(oItem);
|
||||||
|
location lTargetLocation = PRCGetSpellTargetLocation();
|
||||||
|
if (oCaster == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oCaster = GetLastSpellCaster();
|
||||||
|
lTargetLocation = PRCGetSpellTargetLocation();
|
||||||
|
}
|
||||||
|
if (oCaster == OBJECT_INVALID) {
|
||||||
|
oCaster = GetItemActivator();
|
||||||
|
lTargetLocation = GetItemActivatedTargetLocation();
|
||||||
|
}
|
||||||
|
if (oCaster == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oCaster = OBJECT_SELF;
|
||||||
|
lTargetLocation = GetLocation(OBJECT_SELF);
|
||||||
|
}
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = PRCGetSpellTargetObject();
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = GetItemActivatedTarget();
|
||||||
|
if (oTarget == OBJECT_INVALID) oTarget = oCaster;
|
||||||
|
if (oArea == OBJECT_INVALID) oArea = GetArea(oCaster);
|
||||||
|
if (oArea == OBJECT_INVALID) oArea = GetArea(oTarget);
|
||||||
|
|
||||||
|
// Null magic code moved
|
||||||
|
int bIsNull = NullMagicOverride(oArea, oCaster, oTarget);
|
||||||
|
if (bIsNull) { return bIsNull; }
|
||||||
|
|
||||||
|
int nCasterState = GetWMState(oCaster);
|
||||||
|
int nTargetState = GetWMState(oTarget);
|
||||||
|
int nAreaState = GetWMState(oArea);
|
||||||
|
|
||||||
|
if (nModuleState == 2 ||
|
||||||
|
nItemState == 2 ||
|
||||||
|
nCasterState == 2 ||
|
||||||
|
nTargetState == 2 ||
|
||||||
|
nAreaState == 2)
|
||||||
|
{
|
||||||
|
return GoWild(oCaster, oTarget, lTargetLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oTarget == oCaster) {
|
||||||
|
object oInvis = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", lTargetLocation);
|
||||||
|
if (GetWMState(oInvis) == WM_WILD)
|
||||||
|
{
|
||||||
|
DestroyObject(oInvis);
|
||||||
|
return GoWild(oCaster, oTarget, lTargetLocation);
|
||||||
|
}
|
||||||
|
DestroyObject(oInvis);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GoWild(object oCaster, object oTarget, location lLocation)
|
||||||
|
{
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
if (GetLocalInt(OBJECT_SELF, "WILDCASTING"))
|
||||||
|
{
|
||||||
|
DeleteLocalInt(OBJECT_SELF, "WILDCASTING");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nSpell = PRCGetSpellId();
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
int nRoll = d100();
|
||||||
|
|
||||||
|
if (nRoll == 100) {
|
||||||
|
object oNewTarget = GetRandomNearby(oTarget);
|
||||||
|
float fDuration = IntToFloat(d20(2)*6);
|
||||||
|
int nState = d2();
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
|
||||||
|
EffectVisualEffect(VFX_IMP_HEAD_ODD),
|
||||||
|
oNewTarget, fDuration);
|
||||||
|
SetWMState(oNewTarget, nState);
|
||||||
|
DelayCommand(fDuration, SetWMState(oNewTarget, nState, -1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 96)
|
||||||
|
{
|
||||||
|
AssignCommand(oCaster, SpecialCast(nSpell, oTarget,
|
||||||
|
lLocation, nCasterLevel,
|
||||||
|
METAMAGIC_MAXIMIZE));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 86)
|
||||||
|
{
|
||||||
|
AssignCommand(oCaster, SpecialCast(nSpell, oTarget,
|
||||||
|
lLocation, nCasterLevel,
|
||||||
|
METAMAGIC_EXTEND));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 56)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 54)
|
||||||
|
{
|
||||||
|
CreateObject(OBJECT_TYPE_PLACEABLE, "plc_butterflies",
|
||||||
|
GetLocation(oCaster));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 51)
|
||||||
|
{
|
||||||
|
AssignCommand(oCaster, SpecialCast(nSpell, oCaster,
|
||||||
|
lLocation, nCasterLevel,
|
||||||
|
nMetaMagic));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 41)
|
||||||
|
{
|
||||||
|
object oNewCaster = GetRandomNearby(oTarget);
|
||||||
|
object oNewTarget = GetRandomNearby(oCaster);
|
||||||
|
lLocation = GetLocation(oNewTarget);
|
||||||
|
AssignCommand(oNewCaster, SpecialCast(nSpell, oNewTarget,
|
||||||
|
lLocation, nCasterLevel,
|
||||||
|
nMetaMagic));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 26)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (nRoll >= 11)
|
||||||
|
{
|
||||||
|
object oNewTarget = GetRandomNearby(oCaster);
|
||||||
|
lLocation = GetLocation(oNewTarget);
|
||||||
|
AssignCommand(oCaster, SpecialCast(nSpell, oNewTarget,
|
||||||
|
lLocation, nCasterLevel,
|
||||||
|
nMetaMagic));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssignCommand(oCaster, RandomCast());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialCast (int nSpell, object oTarget,
|
||||||
|
location lLocation, int nCasterLevel,
|
||||||
|
int nMetaMagic)
|
||||||
|
{
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
SetLocalInt(oCaster, "WILDCASTING", TRUE);
|
||||||
|
ClearAllActions();
|
||||||
|
if (oTarget == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oTarget = GetNearestObjectToLocation(OBJECT_TYPE_CREATURE, lLocation);
|
||||||
|
}
|
||||||
|
AssignCommand(oCaster, ActionCastSpellAtObject(nSpell, oTarget,
|
||||||
|
nMetaMagic, TRUE, nCasterLevel,
|
||||||
|
PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
|
||||||
|
DelayCommand(5.5, DeleteLocalInt(oCaster, "WILDCASTING"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// To do: Get a better random spell chooser
|
||||||
|
void RandomCast ()
|
||||||
|
{
|
||||||
|
object oTarget = GetRandomNearby(OBJECT_SELF);
|
||||||
|
location lLocation = GetLocation(oTarget);
|
||||||
|
SpecialCast(Random(412), oTarget, lLocation,
|
||||||
|
PRCGetCasterLevel(OBJECT_SELF), PRCGetMetaMagicFeat());
|
||||||
|
}
|
||||||
|
|
||||||
|
object GetRandomNearby(object oTarget=OBJECT_SELF)
|
||||||
|
{
|
||||||
|
object oNewTarget;
|
||||||
|
int nCounter = 0;
|
||||||
|
int nType;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
oNewTarget = GetNearestObject(OBJECT_TYPE_ALL, oTarget, nCounter);
|
||||||
|
nType = GetObjectType(oNewTarget);
|
||||||
|
if ((nType == OBJECT_TYPE_CREATURE ||
|
||||||
|
nType == OBJECT_TYPE_PLACEABLE) &&
|
||||||
|
d8() == 1)
|
||||||
|
{
|
||||||
|
break; // Target selected
|
||||||
|
}
|
||||||
|
if (nCounter++ > 20)
|
||||||
|
{
|
||||||
|
oNewTarget = oTarget;
|
||||||
|
break; // Did not find random target, choose self as default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oNewTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect EffectWildMagicAOE()
|
||||||
|
{
|
||||||
|
int nAOE = AOE_PER_FOGKILL;
|
||||||
|
return EffectAreaOfEffect(nAOE, "wm_aoe_e", "wm_aoe_h", "wm_aoe_x");
|
||||||
|
}
|
||||||
|
|
||||||
|
effect EffectNullMagicAOE()
|
||||||
|
{
|
||||||
|
int nAOE =AOE_PER_FOGMIND;
|
||||||
|
return EffectAreaOfEffect(nAOE, "nm_aoe_e", "nm_aoe_h", "nm_aoe_x");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveMagicalEffects (object oTarget)
|
||||||
|
{
|
||||||
|
effect eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect)) {
|
||||||
|
if (GetEffectSubType(eEffect) == SUBTYPE_MAGICAL)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eEffect);
|
||||||
|
}
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user