Guys this is great story for any programmer. I turned compiler optimization on in debug to get accurate profiling readings and a strange warning message popped up.
Weapon 'Harpoon#Weak' requires the "player allowed" flag, but it's not listed! Adding it by default.
Offending code:
if ( !(wip->wi_flags & WIF_PLAYER_ALLOWED) && stristr(wip->name, "#weak") ) {
int idx = -1;
char non_weak[NAME_LENGTH];
strncpy(non_weak, wip->name, strlen(wip->name) - 5);
idx = weapon_info_lookup(non_weak);
// only add the flag if the non-weak version is also player-allowed
if ( (idx >= 0) && (Weapon_info[idx].wi_flags & WIF_PLAYER_ALLOWED) ) {
Warning(LOCATION, "Weapon '%s' requires the \"player allowed\" flag, but it's not listed! Adding it by default.\n", wip->name);
wip->wi_flags |= WIF_PLAYER_ALLOWED;
}
}
So i investigate and found something really awesome. A heisenbug! Means a bug that disappears when you try to debug it. strncpy doesnt terminate a string by itself it only does it when the to be copied string ends before the number of chars given is reached. So when it passes the non_weak string to find the nonweak weapon its unterminated. It doesnt find the weapon and no warning is generated. But when i turn on optimizations something awesome happens. By a one in a million fluke there is a 0 in memory right where the string "Harpoon" ends, its terminated correctly it finds the weapon and bam a warning is generated. So i patched the function and looky look there pop up 3 more warnings. So what should i do about that do we fix the tables or just surpress the warning. i dont even know why you want to enable player allowed if its weak wouldnt this show in the weapon name would look pretty stupid if you ask me. It didnt appear till now cause there was the bug in the check function. here is the patch for anyone interested
Index: weapons.cpp
===================================================================
--- weapons.cpp (Revision 7344)
+++ weapons.cpp (Arbeitskopie)
@@ -3332,11 +3332,13 @@
first_cmeasure_index = i;
// if we are a "#weak" weapon then popup a warning if we don't have the "player allowed" flag set
- if ( !(wip->wi_flags & WIF_PLAYER_ALLOWED) && stristr(wip->name, "#weak") ) {
+ char* end = stristr(wip->name, "#weak");
+ if ( !(wip->wi_flags & WIF_PLAYER_ALLOWED) && end ) {
int idx = -1;
char non_weak[NAME_LENGTH];
- strncpy(non_weak, wip->name, strlen(wip->name) - 5);
+ memset(non_weak,0,NAME_LENGTH); // Valathil: strncpy doesnt explicity terminate the string it copies
+ strncpy(non_weak, wip->name, end - wip->name); // Valathil: Previous version fails on Weapons like WeaponName#weak#shivan
idx = weapon_info_lookup(non_weak);
// only add the flag if the non-weak version is also player-allowed