You need a script (let's call it "gui_character_defenses" (but you can call it as you wish, as long as keep the initial "gui_" that one is mandatory or the script won't work)) that collects all the current effects and item properties of your character and launch it every time you open up the character screen. This can be done in the following manner:
.........
OnAdd=UIObject_Misc_RequestCharacterUpdates(0,"true","STATS")
OnAdd0=UIObject_Misc_ExecuteServerScript("gui_character_defenses")
.........
Of course you also need to modify the characterscreen.xml file to have a place where to write the defenses, but I imagine you have done it already.
As for the script itself, I am going to assume you will only be interested in non-limited elemental and physical resistances. You could include the limited ones, or damage reduction or vulnerabilities as well, but I'll keep it simple here. I will also assume you have given the panes a numbered name so that's easier to set their text in a code. One last thing, is that I've assumed that immunities and resistances from items are shown in a different panel than the ones from effects, but they're both shown.
void main()
{
object oPC = OBJECT_SELF;
int nELEMENT = 1; // Start from 1. 0 is ALL, which is not implemented.
int nAMOUNT;
int nTYPE;
int nSUB;
int nIMMUNITY;
int nRESIST;
effect eEFFECT;
// First get all elements and cycle the effects
while (nELEMENT < 2050) // // Effect elements variables are powers of 2. Sonic is 2048
{
nIMMUNITY = 0;
nRESIST = 0;
eEFFECT = GetFirstEffect(oPC);
while (GetIsEffectValid(eEFFECT) == TRUE)
{
nTYPE = GetEffectType(eEFFECT);
nSUB = GetEffectInteger(eEFFECT, 0);
if ((nTYPE == EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE)&&(nSUB == nELEMENT)) // Immunities Stack.
{
nIMMUNITY = nIMMUNITY + GetEffectInteger(eEFFECT, 1);
}
else if ((nTYPE == EFFECT_TYPE_DAMAGE_RESISTANCE)&&(nSUB == nELEMENT)) // Resistances don't.
{
nAMOUNT = GetEffectInteger(eEFFECT, 1);
if (nRESIST < nAMOUNT)
{
nRESIST = nAMOUNT;
}
}
eEFFECT = GetNextEffect(oPC);
}
SetGUIObjectText(oPC, "SCREEN_CHARACTER", "CHARACTER_IMMUNITY_EFFECT_" + IntToString(nELEMENT), -1, IntToString(nIMMUNITY) + "%");
SetGUIObjectText(oPC, "SCREEN_CHARACTER", "CHARACTER_RESISTANCE_EFFECT_" + IntToString(nELEMENT), -1, IntToString(nRESIST));
nELEMENT = nELEMENT * 2;
}
// Then we get the item properties from all items equipped.
object oITEM;
itemproperty iPROP;
int nSLOT;
int nTABLE;
nELEMENT = 0; // Item elements range from 0 to 14.
while (nELEMENT < 14)
{
if ((nELEMENT!=3)&&(nELEMENT!=4)) // Skip Physical and Subdual, they're bugged.
{
nSLOT = 0;
nIMMUNITY = 0;
nRESIST = 0;
while (nSLOT < 11)
{
oITEM = GetItemInSlot(nSLOT, oPC);
iPROP = GetFirstItemProperty(oITEM);
while (GetIsItemPropertyValid(iPROP) == TRUE)
{
nTYPE = GetItemPropertyType(iPROP);
nSUB = GetItemPropertySubType(iPROP);
nTABLE = GetItemPropertyCostTableValue(iPROP);
if ((nTYPE == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)&&(nSUB == nELEMENT)) // Immunities Stack.
{
nIMMUNITY = nIMMUNITY + StringToInt(Get2DAString("iprp_immuncost", "Value", nTABLE));
}
else if ((nTYPE == ITEM_PROPERTY_DAMAGE_RESISTANCE)&&(nSUB == nELEMENT)) // Resistances don't.
{
nAMOUNT = StringToInt(Get2DAString("iprp_resistcost", "Amount", nTABLE));
if (nRESIST < nAMOUNT)
{
nRESIST = nAMOUNT;
}
}
iPROP = GetNextItemProperty(oITEM);
}
nSLOT = nSLOT + 1;
}
SetGUIObjectText(oPC, "SCREEN_CHARACTER", "CHARACTER_IMMUNITY_ITEM_" + IntToString(nELEMENT), -1, IntToString(nIMMUNITY));
SetGUIObjectText(oPC, "SCREEN_CHARACTER", "CHARACTER_RESISTANCE_ITEM_" + IntToString(nELEMENT), -1, IntToString(nRESIST));
}
nELEMENT = nELEMENT + 1;
}
}