Author: Marzo Sette Torres Junior
Date: 11-29-11 13:41
Strictly speaking, you don't need to recognize casters; you need to recodnize spells. This can be done by looking at spell shapes.
Here is an example of how it can be done; I haven't tested it, but it should work with some minor modifications. I took the route of deleting spells (instead of swapping for drained versions) and setting the magebane flag to prevent blink, invisibility and summon and clearing several spell effect flags (invisibility, curse, etc.). The code is not complete as I did not list all spell shapes. But it should be enough to get you started.
NPCs of hostile or random alignment get negatively affected all the time; neutral NPCs are affected only if they are being attacked by party members; friendly NPCs are positively affected if they are not fighting party members, negatively affected otherwise; party members are always positively affected.
A 'positive effect' is the removal of negative spell effects -- curse, charm, paralysis. A 'negative effect' is the removal of all spell effects (those above plus invisibility, might, protection) and spells. NPCs that lose their spells will show a fizzle and exclaim in disbelief, for color.
extern var getOuterContainer 0x945(var obj);
extern void spellFails object#(0x606) ();
// No idea what shape the storm cloak is.
void StormCloak shape#(0xXXX) ()
{
if (event == 5)
{
// Come back here next tick to do initial cleanup.
script item
{
nohalt;
call StormCloak;
}
}
else if (event == 6)
{
// Don't need to do anything really.
}
else if (event == 2)
{
// Add more spells here:
var spell_shapes = {281, 408, 527, 807, 856};
// Who is wearing the cloak:
var wearer = getOuterContainer(item);
// How far from the wearer we want to search.
var dist = 20;
// Find all nearby NPCs, of any shape, within 20 tiles and whether or
// not they are invisible.
var npc_list = wearer->find_nearby(-359, dist, 0x28);
// To prevent party NPCs from being affected.
var party = UI_get_party_list();
// For color.
var barks = ["My pretty spells are gone!", "My magic?!!", "My spells?!!"];
var numbarks = UI_get_array_size(barks);
for (npc in npc_list)
{
var align = npc->get_alignment();
var in_party = npc->get_npc_object();
// Is the NPC is being attacked by a party member?
if (in_party || !(npc->get_oppressor() in party))
{
// No. Check basic alignment only.
if (in_party || align == 0)
{
// Friendly NPCs and party members.
// Uncharm.
npc->clear_item_flag(2);
// Uncurse.
npc->clear_item_flag(3);
// Unparalyze.
npc->clear_item_flag(7);
// Do nothing else.
continue;
}
else if (align == 1)
{
// Neutral NPCs.
// Do nothing? Do everything? Your choice.
// I went with 'do nothing'.
continue;
}
}
// Hostile and random NPCs, fighting neutral NPCs or friendly NPCs
// being attacked by party members.
// We want to delete spells, if any.
// We also want to count how many spells were deleted.
int cnt = 0;
// Go through the spell shapes.
for (spell in spell_shapes)
{
// Remove all spells of this shape that the NPC is carrying.
cnt += npc->remove_cont_items(-359, spell, -359, -359, true);
}
// Did we delete any spells?
if (cnt > 0)
{
// We did. Now we must to do a couple more things.
// 'Magebane' effect: prevents mages from teleporting, turning
// invisible or summoning more foes.
npc->set_item_flag(31);
// Color: spell fizzle effect plus surprised bark.
script npc after UI_die_roll(4,8) ticks
{
call spellFails;
wait 4;
say barks[UI_get_random(numbarks)];
}
}
// The following are optional tweaks:
// Force visible.
npc->clear_item_flag(0);
// Uncharm.
npc->clear_item_flag(2);
// Uncurse.
npc->clear_item_flag(3);
// Unparalyze.
npc->clear_item_flag(7);
// Unprotect.
npc->clear_item_flag(9);
// Remove might.
npc->clear_item_flag(12);
}
// Script it to return here again.
script item after 4 ticks // Change this at your leisure.
{
nohalt;
call StormCloak;
}
}
}
|
|