after having the newest core productive for several days I found a serious bug *sigh*
Does nobody TEST the cores? This core is unchanged since March 2016 - obviously nobody uses it, or am I wrong??
The problem:
Reading the AOS resistances and damages goes totally wrong - it doubles the values defined in npcdesc.cfg. Here is an example, tested with an empty world file, and with our npcdesc.cfg:
Here we have the entry for a dragon in our npcdesc.cfg:
Code: Select all
// Original NPC entry
NpcTemplate N003b
{
Name <DRAGON>
Title Drache
Script simplenpc
GermArt 1
PoisonResistance 100
Behaviour LootMonster
ObjType 0x003b
Icon 0x20d6
TrueColor 0
Gender 0
STR 1d30+795
INT 1d40+435
DEX 1d20+85
Runspeed 40
NpcLevel 3810
Parry 1d40+55
MagicResistance 1d2+98
Tactics 1d2+98
Wrestling 1d3+90
AR 50
AttackDamage 2d12+4
AttackSpeed 30
AttackAttribute Wrestling
AttackHitScript :combat:npchitscript
FireResist 750
ColdResist 50
PoisonResist 250
FireDamage 10
Alignment evil
IdleSound 0x016c
AttackHitSound 0x016d
DamageSound 0x016e
DeathSound 0x016f
AttackMissSound 0x0234
}
So - our dragon should have 750 fire resistance, 50 cold resistance, 250 poison resistance, no energy resistance and do 10 fire damage. And it has an AR of 50. We still use AR, hence AOSResistances are zero in uoclient.cfg. We also use hit zones and AR zones, but AR is not the problem here, this works well.
I used the following tiny testscript to read the values from our new NPC directly:
Code: Select all
program testvalues(who)
var mobile := Target(who, 0);
if (mobile)
if (mobile.ar)
print(mobile.ar);
print(mobile.resist_fire);
print(mobile.resist_cold);
print(mobile.resist_poison);
print(mobile.resist_energy);
print(mobile.damage_fire);
print(mobile.damage_cold);
print(mobile.damage_poison);
print(mobile.damage_energy);
endif
endif
endprogram
Code: Select all
50 AR
1500 fire resist
100 cold resist
500 poison resist
0 energy resist
20 fire damage
0 cold damage
0 poison damage
0 energy damage
So okay - maybe its a small core bug, and we can catch it in the scripts, by dividing the values by 2? Well - yes, BUT...
Here is the save entry of this dragon in npcs.txt:
Code: Select all
// Save in npcs.txt, after create
NPC N003b
{
Name Volan, der Drache
Serial 0x20a3
ObjType 0x3b
Graphic 0x3b
X 2777
Y 880
Z 0
Facing 6
Revision 1
Realm britannia
CProp Typ i7
TrueColor 0x0
TrueObjtype 0x3b
Gender 0
Race 0
Strength 800
Intelligence 451
Dexterity 98
Parry 74
MagicResistance 99
Tactics 100
Wrestling 92
Life 800
Mana 451
Stamina 98
CreatedAt 0
AR 50
script simplenpc
SpeechColor 37
RunSpeed 40
FireResist 1500
ColdResist 100
PoisonResist 500
FireDamage 20
}
Okay - POL goes down, saves, and is started new, reading its saves, including our dragon.
After it is up, I log in and use my small testscript to check our dragon, and this is the output:
Code: Select all
// Output of testscript after stopping the core, restarting and loading the save
50 AR
3000 fire resist
200 cold resist
1000 poison resist
0 energy resist
40 fire damage
0 cold damage
0 poison damage
0 energy damage
So - every time we have to restart our system, all NPCs with resistances and damages not zero have DOUBLED values!!!
After stopping the POL core again, the save entry for our dragon looks now like this
Code: Select all
// Nnpcs.txt - save after going down again
NPC N003b
{
Name Volan, der Drache
Serial 0x20a3
ObjType 0x3b
Graphic 0x3b
X 2775
Y 871
Z 0
Facing 1
Revision 1
Realm britannia
CProp Typ i7
TrueColor 0x0
TrueObjtype 0x3b
Gender 0
Race 0
Strength 800
Intelligence 451
Dexterity 98
Parry 74
MagicResistance 99
Tactics 100
Wrestling 92
Life 800
Mana 451
Stamina 98
CreatedAt 0
AR 50
script simplenpc
SpeechColor 37
RunSpeed 40
FireResist 3000
ColdResist 200
PoisonResist 1000
FireDamage 40
}
I am NOT amused. How could this slip through????
Now I sit with a productive shard, players online and nearly 4 days gaming in our save and have to find out this.
I am forced to delete ALL our monsters before I put down the shard, or we will have a completely unusable shard.
Could you please look into this real FAST?? I cannot believe that nobody saw this for 5 Months now...
I also tried to recompile my core (just hours before) for Windows, under Windows 7 and with VC 2013, without problems, and the core compiled under Debian (our productive core) has the same behavior. So I am quite sure it is a bug. Documentation says nothing about changed behavior in this regard.
Here is my guess:
There are two new and shiny functions in npc.cpp:
void NPC::loadResistances( int resistanceType, Clib::ConfigElem& elem )
void NPC::loadDamages( int damageType, Clib::ConfigElem& elem )
Both do this:
Code: Select all
...
switch ( resistanceType )
{
case 0:
npc_ar_ = static_cast<u16>( value );
break;
case 1:
{
if ( value != 0 )
{
fire_resist( fire_resist().addToValue( static_cast<s16>( value ) ) );
curr_fire_resist( curr_fire_resist().addToValue( static_cast<s16>( value ) ) );
}
break;
}
...
Code: Select all
inline AosValuePack& AosValuePack::addToValue( s16 other )
{
value += other;
return *this;
}
The same seems to happen, if we read the resistances from the save (npcs.txt). I suspect, this is the reason.
Maybe we need a new inline method:
Code: Select all
inline AosValuePack& AosValuePack::setToValue( s16 other )
{
value = other;
return *this;
}
OWHorus
EDIT:
I just checked - items (equipment has several set resistances and damages) are stable - thanks to god, because it would have been awful to replace these all. But they are loaded correctly, and stored correctly...
OWH
EDIT2:
I seem to have a solution, but I doubt, that it is the correct one...
I added a new inline function - see above - and use it to set the curr_xxx_resist and curr_xxx_damage values. The rest is unchanged. As a consequence newly created NPCs have now the correct values, and store / load correctly.
There seems to be a mix up between the Template values, the 'real' values which are used and the mod values. I further experimented with the unchanged core (without my hack), and found, that if you set a mod for example to fire_resist, the value you read back in script is changed correctly, the mod value is stored correctly too - but the fire_resist value in the save has now the _new_ changed value. If you save, stop the server, and reload it from the save the NPC has again the incorrect value, since the mod is read back from the save, but as base value the stored _changed_ value is used. So the mod is added twice (it is contained in the world file, and calculated into the resist value, but not taken into account during load).
I doubt that this works with my hack, there is more at fault. But since we do not use AOS-Resistances with mods in our scripts, this will work. (Also NPCs do not use equipment which will change resistances).
The resistances of items are correct, loaded from the world save or created new. Also the character is updated fine if he equips things which change his resistances.
But somehow I have the impression, that this part of the core is not ready.
I really hope, that you find the time to look into that. It was my impression, that the core has a stable state, and you are waiting for feedback and will release it.
OWHorus