183 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /*//////////////////////////////////////////////////////////////////////////////
 | |
| // Script Name: pc_savebuffs
 | |
| ////////////////////////////////////////////////////////////////////////////////
 | |
|  Used with pi_buffing to run the buffing plugin for
 | |
|  Philos Single Player Enhancements.
 | |
| 
 | |
| Note: If a spell saves incorrectly check the spell script to see if the correct
 | |
| spell is being passed through the SignalEvent correctly.
 | |
| Known error in Shield of Faith spell as the below code in the shield of faith
 | |
| script sends Camoflage instead!
 | |
| "SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, 421, FALSE));"
 | |
| *///////////////////////////////////////////////////////////////////////////////
 | |
| #include "0i_nui"
 | |
| // sDataField should be one of the data fields for the table.
 | |
| // Returns a string of the data stored.
 | |
| string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag = "");
 | |
| // sDataField should be one of the data fields for that table.
 | |
| // sData is the string data to be saved.
 | |
| void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag = "");
 | |
| // sDataField should be one of the data fields for that table.
 | |
| // jData is the json data to be saved.
 | |
| void SetBuffDatabaseJson(object oPlayer, string sDataField, json jData, string sTag = "");
 | |
| // sDataField should be one of the data fields for the table.
 | |
| // Returns a string of the data stored.
 | |
| json GetBuffDatabaseJson(object oPlayer, string sDataField, string sTag = "");
 | |
| // Returns the level if this spell has a domain spell on nLevel, or 0.
 | |
| int GetHasDomainSpell(object oCaster, int nClass, int nLevel, int nSpell);
 | |
| 
 | |
| // We do some crazy hack to get all the correct information when casting spells.
 | |
| // GetLastSpellCastClass() will only give the class if this script is running
 | |
| //                         on the actual caster, i.e. our PC.
 | |
| // GetLastSpellLevel() will only give the level if this script is running on
 | |
| //                     the actual caster, i.e. our PC.
 | |
| // So for this to work we run this scrip in the event OnSpellCastAt of our
 | |
| // target, then we ExecuteScript this script again with the Caster (oPC)
 | |
| // as OBJECT_SELF for this script on its second pass. This allows us to get the
 | |
| // information from the above functions! Neat!
 | |
| void main()
 | |
| {
 | |
|     object oTarget = OBJECT_SELF;
 | |
|     // The first pass we get oCaster via GetLastSpellCaster() fails in ExecuteScript!
 | |
|     // The second pass we get oCaster via the variable "AI_BUFF_CASTER".
 | |
|     object oCaster = GetLocalObject(oTarget, "AI_BUFF_CASTER");
 | |
|     if(oCaster == OBJECT_INVALID) oCaster = GetLastSpellCaster();
 | |
|     // We setting up the save spells button we saved the PC to itself.
 | |
|     // Here we get the PC to make sure the caster of this spell is our saving PC.
 | |
|     object oPC = GetLocalObject(oCaster, "AI_BUFF_PC");
 | |
|     // The first pass we get nspell via GetLastSpell() fails in ExecuteScript!
 | |
|     // The second pass we get nSpell via the variable "AI_BUFF_SPELL".
 | |
|     int nSpell = GetLocalInt(oTarget, "AI_BUFF_SPELL");
 | |
|     if(nSpell == 0) nSpell = GetLastSpell();
 | |
|     // If this is a harful spell or The caster does not equal our saving PC then
 | |
|     // we need to fix the targets scripts back and run the correct OnSpellCastAt script.
 | |
|     if(GetLastSpellHarmful() || oPC != oCaster)
 | |
|     {
 | |
|         string sScript = GetLocalString(oTarget, "AI_BUFF_CAST_AT_SCRIPT");
 | |
|         SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript);
 | |
|         ExecuteScript(sScript, oTarget);
 | |
|         return;
 | |
|     }
 | |
|     // If the oTarget != oCaster then we are casting a spell on one of our
 | |
|     // associates. We must make a second pass to get the correct information.
 | |
|     // We do this by saving the Target, Caster, and Spell so we can get them
 | |
|     // in the second pass as Execute Script makes them impossible to get on a
 | |
|     // second pass.
 | |
|     if(oTarget != oCaster)
 | |
|     {
 | |
|         SetLocalObject(oPC, "AI_BUFF_TARGET", oTarget);
 | |
|         SetLocalObject(oPC, "AI_BUFF_CASTER", oCaster);
 | |
|         SetLocalInt(oPC, "AI_BUFF_SPELL", nSpell);
 | |
|         ExecuteScript("pc_savebuffs", oPC);
 | |
|         return;
 | |
|     }
 | |
|     // If this is the first pass and we get here then oCaster is casting a spell
 | |
|     // on themselves. So oTarget will be invalid and we should use oPC.
 | |
|     // If this is the second pass and we get here then we have saved oTarget
 | |
|     // to oPC and this will get them so we can save the target to the spell!
 | |
|     oTarget = GetLocalObject(oPC, "AI_BUFF_TARGET");
 | |
|     if(oTarget == OBJECT_INVALID) oTarget = oPC;
 | |
|     // We need to clean up this mess!
 | |
|     DeleteLocalObject(oPC, "AI_BUFF_TARGET");
 | |
|     DeleteLocalObject(oPC, "AI_BUFF_CASTER");
 | |
|     DeleteLocalInt(oPC, "AI_BUFF_SPELL");
 | |
|     // This blocks one spell from saving multiple times due to being an AOE.
 | |
|     if(GetLocalInt(oPC, "AI_ONLY_ONE")) return;
 | |
|     SetLocalInt(oPC, "AI_ONLY_ONE", TRUE);
 | |
|     // We delay this for just less than half a round due to haste.
 | |
|     DelayCommand(2.5, DeleteLocalInt(oPC, "AI_ONLY_ONE"));
 | |
|     // Here is the whole problem and why we must do a second pass if the target
 | |
|     // is not the caster. These only work if this script is run by the caster.
 | |
|     int nClass = GetLastSpellCastClass();
 | |
|     int nLevel = GetLastSpellLevel();
 | |
|     // Everything below saves the spell to the database with all our now correct info.
 | |
|     int nDomain = GetHasDomainSpell(oPC, nClass, nLevel, nSpell);
 | |
|     int nMetaMagic = GetMetaMagicFeat();
 | |
|     string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
 | |
|     if(nDomain) sName += " [Domain]";
 | |
|     if(nMetaMagic > 0 && StringToInt(Get2DAString("classes", "MemorizesSpells", nClass)))
 | |
|     {
 | |
|         // We must add the level of the metamagic to the spells level to get the spells correct level.
 | |
|         if(nMetaMagic == METAMAGIC_EMPOWER) { sName += " (Empowered)"; nLevel += 2; }
 | |
|         else if(nMetaMagic == METAMAGIC_EXTEND) { sName += " (Extended)"; nLevel += 1; }
 | |
|         else if(nMetaMagic == METAMAGIC_MAXIMIZE) { sName += " (Maximized)"; nLevel += 3; }
 | |
|         else if(nMetaMagic == METAMAGIC_QUICKEN) { sName += " (Quickened)"; nLevel += 4; }
 | |
|         else if(nMetaMagic == METAMAGIC_SILENT) { sName += " (Silent)"; nLevel += 1; }
 | |
|         else if(nMetaMagic == METAMAGIC_STILL) { sName += " (Still)"; nLevel += 1; }
 | |
|     }
 | |
|     json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata");
 | |
|     string sList = JsonGetString(JsonArrayGet(jMenuData, 0));
 | |
|     json jSpells = GetBuffDatabaseJson(oPC, "spells", sList);
 | |
|     json jSpell = JsonArray();
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell));
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel));
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonInt(nMetaMagic));
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonInt(nDomain));
 | |
|     string sTargetName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget, TRUE)));
 | |
|     jSpell = JsonArrayInsert(jSpell, JsonString(sTargetName));
 | |
|     jSpell = JsonArrayInsert(jSpells, jSpell);
 | |
|     SetBuffDatabaseJson(oPC, "spells", jSpells, sList);
 | |
|     SendMessageToPC(oPC, sName + " has been saved for fast buffing on " + sTargetName + ".");
 | |
|     ExecuteScript("pi_buffing", oPC);
 | |
| }
 | |
| string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag)
 | |
| {
 | |
|     string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE)));
 | |
|     string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;";
 | |
|     sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
 | |
|     SqlBindString(sql, "@name", sName);
 | |
|     SqlBindString(sql, "@tag", sTag);
 | |
|     if (SqlStep (sql)) return SqlGetString (sql, 0);
 | |
|     else return "";
 | |
| }
 | |
| void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag)
 | |
| {
 | |
|     string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE)));
 | |
|     string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;";
 | |
|     sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
 | |
|     SqlBindString(sql, "@data", sData);
 | |
|     SqlBindString(sql, "@name", sName);
 | |
|     SqlBindString(sql, "@tag", sTag);
 | |
|     SqlStep (sql);
 | |
| }
 | |
| void SetBuffDatabaseJson (object oPlayer, string sDataField, json jData, string sTag)
 | |
| {
 | |
|     string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE)));
 | |
|     string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;";
 | |
|     sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
 | |
|     SqlBindJson (sql, "@data", jData);
 | |
|     SqlBindString (sql, "@name", sName);
 | |
|     SqlBindString (sql, "@tag", sTag);
 | |
|     SqlStep (sql);
 | |
| }
 | |
| json GetBuffDatabaseJson (object oPlayer, string sDataField, string sTag)
 | |
| {
 | |
|     string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE)));
 | |
|     string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;";
 | |
|     sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
 | |
|     SqlBindString (sql, "@name", sName);
 | |
|     SqlBindString (sql, "@tag", sTag);
 | |
|     if (SqlStep (sql)) return SqlGetJson (sql, 0);
 | |
|     else return JsonArray ();
 | |
| }
 | |
| int GetHasDomainSpell(object oCaster, int nClass, int nLevel, int nSpell)
 | |
| {
 | |
|     int nIndex, nMaxIndex, nMSpell, nMmSpell, bDomain, nSubRadSpell, nSubSpell;
 | |
|     string sSubRadSpell;
 | |
|     if(StringToInt(Get2DAString("classes", "MemorizesSpells", nClass)))
 | |
|     {
 | |
|         nMaxIndex = GetMemorizedSpellCountByLevel(oCaster, nClass, nLevel);
 | |
|         while(nIndex < nMaxIndex)
 | |
|         {
 | |
|             nMSpell = GetMemorizedSpellId(oCaster, nClass, nLevel, nIndex);
 | |
|             if(nSpell == nMSpell)
 | |
|             {
 | |
|                 if(GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex)) return nLevel;
 | |
|             }
 | |
|             nIndex ++;
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 |