Home » MODDING HQ 1.13 » v1.13 Coding Talk » Code Snippets  () 1 Vote
Re: Code Snippets[message #345622 is a reply to message #345608] Sun, 22 May 2016 14:55 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
AIList.cpp
if ( pSoldier->bVisible )

AIMain.cpp
if ( gfTurnBasedAI && pSoldier->bVisible )

should be
pSoldier->bVisible != -1

or
pSoldier->bVisible == TRUE



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345642 is a reply to message #345622] Mon, 23 May 2016 08:09 Go to previous messageGo to next message
wanne (aka RoWa21) is currently offline wanne (aka RoWa21)

 
Messages:1961
Registered:October 2005
Location: Austria
sevenfm wrote on Sun, 22 May 2016 11:55
AIList.cpp
if ( pSoldier->bVisible )

AIMain.cpp
if ( gfTurnBasedAI && pSoldier->bVisible )

should be
pSoldier->bVisible != -1

or
pSoldier->bVisible == TRUE


Thanks, committed in revision 8230.

Report message to a moderator

Sergeant Major

Re: Code Snippets[message #345649 is a reply to message #345642] Mon, 23 May 2016 12:53 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In Buildings.cpp\GenerateBuilding:
gpWorldLevelData[ sCurrGridNo ].ubExtFlags[0] |= MAPELEMENT_EXT_ROOFCODE_VISITED;

gubBuildingInfo[ sCurrGridNo ] = ubBuildingID;

// consider this location as possible climb gridno
// there must be a regular wall adjacent to this for us to consider it a
// climb gridno

This sets building information not only for tiles inside building, but also for adjacent tiles outside of building which is wrong.

Adding check
if( InARoom(sCurrGridNo, NULL) )
	gubBuildingInfo[ sCurrGridNo ] = ubBuildingID;

fixes the problem.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345692 is a reply to message #345649] Thu, 26 May 2016 21:10 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In FindLocations.cpp/SearchForItems()

Toggle Spoiler


this
else if ( EffectiveArmour( &(pSoldier->inv[HELMETPOS]) ) > EffectiveArmour( pObj ) )
{
	iTempValue = 100 * EffectiveArmour( pObj ) / EffectiveArmour( &(pSoldier->inv[VESTPOS]) );
}

and this
else if ( EffectiveArmour( &(pSoldier->inv[HELMETPOS]) ) > EffectiveArmour( pObj ) )
{
	iTempValue = 100 * EffectiveArmour( pObj ) / EffectiveArmour( &(pSoldier->inv[LEGPOS]) );
}

looks like a copypaste bug as we are checking HELMETPOS item but compare with VESTPOS/LEGPOS item.

Also, it's always a great idea to divide by function that can return zero, without any checks or smth.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345693 is a reply to message #345692] Thu, 26 May 2016 21:50 Go to previous messageGo to next message
Flugente

 
Messages:3509
Registered:April 2009
Location: Germany
Good find, fixed in r8238.


I know now that it could never work between us, as much as we wanted to, it could never be! Not because you're a rabbit, but because you're black.

If you want, you can donate to me. This will not affect how and what I code, and I will not code specific features in return. I will be thankful though.

Report message to a moderator

Captain

Re: Code Snippets[message #345694 is a reply to message #345693] Thu, 26 May 2016 22:02 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Flugente it's also seems that check is reversed, we should check that found armour object has more protection than our current armour item, instead the code will consider object if it has less protection.
Should be
if ( effectivearmour_currentpos > 0 && effectivearmour_obj  > effectivearmour_currentpos )

At least, earlier we check that found weapon has more deadliness than current weapon
if (Weapon[pObj->usItem].ubDeadliness > Weapon[pSoldier->inv[HANDPOS].usItem].ubDeadliness)



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345695 is a reply to message #345693] Thu, 26 May 2016 22:07 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
Actually the whole code block doesn't make any sense to me. We compare our current armor to an object and if our current armor is better than that object we replace our armor with the worse object? Heh?

edit: Sevenfm was quicker. big grin

[Updated on: Thu, 26 May 2016 22:08]




Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #345698 is a reply to message #345695] Thu, 26 May 2016 23:16 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Points.cpp\TerrainBreathPoints()
if ( ubMovementCost == WALKING_WEAPON_RDY || ubMovementCost == WALKING_DUAL_RDY )
{
	iPoints += APBPConstants[BP_MOVEMENT_READY];
}

should be
if ( usMovementMode == WALKING_WEAPON_RDY || usMovementMode == WALKING_DUAL_RDY )
{
	iPoints += APBPConstants[BP_MOVEMENT_READY];
}



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345704 is a reply to message #345698] Fri, 27 May 2016 10:43 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
Thanks. I committed all the fixes in r8239 and r8240.

I also reverted Flugente's change for the armor and implemented a different fix. Btw. the "EffectiveArmour" function can never return 0. It will always return at least 1.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #345707 is a reply to message #345704] Fri, 27 May 2016 13:18 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
silversurfer wrote on Fri, 27 May 2016 12:43
Btw. the "EffectiveArmour" function can never return 0. It will always return at least 1.

It will return 0 if the item has wrong class. This should not happen normally, but if it happens for some reason, the game will just crash without any hint where to search for the problem, so I think it's a good idea to at least place Assert() before division or in EffectiveArmour().

This is exactly what happened in Ja2+AI - since old code checked helmet item instead of vest and passed wrong object to function, the game crashed at random times without any message, so I had to spend hour debugging until I found the reason of crashing.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345708 is a reply to message #345707] Fri, 27 May 2016 13:54 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
sevenfm wrote on Fri, 27 May 2016 12:18

It will return 0 if the item has wrong class. This should not happen normally, but if it happens for some reason, the game will just crash without any hint where to search for the problem, so I think it's a good idea to at least place Assert() before division or in EffectiveArmour().

I see now. Thank you. I changed the previous fix in r8241 so now it won't matter anymore if the function returns 0.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #345837 is a reply to message #345708] Sat, 04 June 2016 21:01 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Interface Enhanced.cpp:

for (cnt = 0; cnt < 36; cnt++)
{
	MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
		(INT16)(gItemDescGenSecondaryRegions[cnt].sLeft),
		(INT16)(gItemDescGenSecondaryRegions[cnt].sTop),
		(INT16)(gItemDescGenSecondaryRegions[cnt].sRight),
		(INT16)(gItemDescGenSecondaryRegions[cnt].sBottom),
		MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
	
		MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
		SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
		MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );

		iRegionsCreated++;
}

should be
for (cnt = 0; cnt < 26; cnt++)

because
INV_DESC_REGIONS gItemDescGenSecondaryRegions[26]; // Secondary data regions, 3x5


Also in InitDescStatCoords, this code is suspicious:
memset(gItemDescAttachmentsXY, 0, MAX_ATTACHMENTS);

because gItemDescAttachmentsXY is defined as
INV_ATTACHXY	gItemDescAttachmentsXY[MAX_ATTACHMENTS];

and INV_ATTACHXY is struct
typedef struct
{
	INT16		sX;
	INT16		sY;
	INT16		sHeight;
	INT16		sWidth;
	INT16		sBarDx;
	INT16		sBarDy;

} INV_ATTACHXY;



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345838 is a reply to message #345837] Sat, 04 June 2016 22:24 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
sevenfm wrote on Sat, 04 June 2016 20:01
Interface Enhanced.cpp:

should be
for (cnt = 0; cnt < 26; cnt++)

because
INV_DESC_REGIONS gItemDescGenSecondaryRegions[26]; // Secondary data regions, 3x5


I'd say the array should be increased to 36 instead because in theory an item can have more than 26 secondary properties. To me it looks like in the past someone added properties, adjusted the loop counter but forgot to adjust the array that holds the region definitions. It's not the first time that this happens, just in this case it had no consequences so far (like missing properties in UDB).



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #345844 is a reply to message #345838] Sun, 05 June 2016 07:44 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
silversurfer wrote on Sun, 05 June 2016 00:24
I'd say the array should be increased to 36 instead because in theory an item can have more than 26 secondary properties. To me it looks like in the past someone added properties, adjusted the loop counter but forgot to adjust the array that holds the region definitions. It's not the first time that this happens, just in this case it had no consequences so far (like missing properties in UDB).

I think you are right because cnt value can be incremented 35 times in DrawSecondaryStats.

Also, in DrawSecondaryStats:
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON || IC_PUNCH))
{
	// Weapons have no space on their UDB General page to show Secondary Stats anyway.
	return;
}

should be
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON | IC_PUNCH))



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345846 is a reply to message #345838] Sun, 05 June 2016 10:31 Go to previous messageGo to next message
DepressivesBrot is currently offline DepressivesBrot

 
Messages:3658
Registered:July 2009
silversurfer wrote on Sat, 04 June 2016 21:24
I'd say the array should be increased to 36 instead because in theory an item can have more than 26 secondary properties. To me it looks like in the past someone added properties, adjusted the loop counter but forgot to adjust the array that holds the region definitions. It's not the first time that this happens, just in this case it had no consequences so far (like missing properties in UDB).
And that's why constants/defines are good and 'magic numbers' are bad

[Updated on: Sun, 05 June 2016 10:32]




Chat with us!
#bearpit on IRC
Discord
Get your latest 1.13 Builds
(Pls don't use my forum PMs for general game queries)

Report message to a moderator

Captain

Re: Code Snippets[message #345849 is a reply to message #345846] Sun, 05 June 2016 16:08 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
Seven, we are both wrong. big grin
UDB only allows to display 6x4 icons in the box. There is not enough space to display more. Nevertheless I set a new #define that is used for the array and the loop. It's set to 24. We don't have coordinates for more entries anyway.

sevenfm wrote on Sun, 05 June 2016 06:44

Also, in DrawSecondaryStats:
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON || IC_PUNCH))
{
	// Weapons have no space on their UDB General page to show Secondary Stats anyway.
	return;
}


Actually that bug caused the UDB to work properly for weapons. I removed the whole block. It is not needed anymore since the implementation of the second page for general stats.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #345858 is a reply to message #345849] Mon, 06 June 2016 09:03 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Weapons.cpp\CalcChanceToHitGun
if (pSoldier->pathing.bLevel == pTarget->pathing.bLevel && pSoldier->pathing.bLevel > 0)
	sCoweringPenalty = 0; // No cowering penalties when both are on the roof!
else if (pSoldier->pathing.bLevel < pSoldier->pathing.bLevel && gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
	sCoweringPenalty *= 2; // Much harder to shoot at anyone cowering above you.
else if (pSoldier->pathing.bLevel > pSoldier->pathing.bLevel)
	sCoweringPenalty /= 2; // Much easier to shoot at cowerers below you.

(pSoldier level is compared to pSoldier level instead of pTarget)
should be
if (pSoldier->pathing.bLevel == pTarget->pathing.bLevel && pSoldier->pathing.bLevel > 0)
	sCoweringPenalty = 0; // No cowering penalties when both are on the roof!
else if (pSoldier->pathing.bLevel < pTarget->pathing.bLevel && gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
	sCoweringPenalty *= 2; // Much harder to shoot at anyone cowering above you.
else if (pSoldier->pathing.bLevel > pTarget->pathing.bLevel)
	sCoweringPenalty /= 2; // Much easier to shoot at cowerers below you.
iChance -= sCoweringPenalty;




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #345867 is a reply to message #345858] Mon, 06 June 2016 17:30 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
Nice find. Fixed in r8249.


Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #346741 is a reply to message #345867] Thu, 25 August 2016 23:33 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
stable 7609:
Weapons.cpp, CalcNewChanceToHitGun
// silversurfer: this doesn't make sense. We always apply a penalty when we can see the target?
// invisible targets are already taken into account one step above in aimbonus from target
// VISIBILITY
/*if (iRange > 0 && iSightRange > iRange)
{
	FLOAT fTempPenalty = (FLOAT)((FLOAT)iSightRange / (FLOAT)iRange);
	fTempPenalty = (FLOAT)(100 / fTempPenalty);
	fAimModifier += ((100-fTempPenalty) * gGameCTHConstants.AIM_VISIBILITY)/100;
	fAimModifier = __max( gGameCTHConstants.AIM_TARGET_INVISIBLE, fAimModifier );
}*/

I think the idea was to take into account effective 'visual distance' to target which can be increased by grass and other obstacles.
Also, if scope gives some visibility bonus, effective 'visual distance' will be reduced, representing that we 'can see target better'.
Similar calculations are used in OCTH.
This code was removed in recent versions, but the option AIM_VISIBILITY still exists in CTHConstants.ini.

Also, in iSightRange calculation:
if (iSightRange == 0) 
{	// Can't see the target but we still need to know what the sight range would be if we could so we can deal with cover penalties
	iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false, true );
	fCantSeeTarget = true;
}

ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); // Target ubID

ubTargetID can be NOBODY if we shoot at empty tile, but the code doesn't check that, passing wrong soldier pointer to SoldierToSoldierLineOfSightTest, this can result in crash in some situations (calc cth for shooting at invisible empty tile).
The same bug exists in CalcChanceToHitGun.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #346743 is a reply to message #346741] Fri, 26 August 2016 11:35 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
sevenfm wrote on Thu, 25 August 2016 22:33
stable 7609:
Weapons.cpp, CalcNewChanceToHitGun
Toggle Spoiler

I think the idea was to take into account effective 'visual distance' to target which can be increased by grass and other obstacles.
Also, if scope gives some visibility bonus, effective 'visual distance' will be reduced, representing that we 'can see target better'.
Similar calculations are used in OCTH.
This code was removed in recent versions, but the option AIM_VISIBILITY still exists in CTHConstants.ini.

The reason I commented this part of the code is that it doesn't make any sense to me.

iRange is the range to target.
iSightRange is the distance that we can see.

Now the above code says that if range to target is greater than zero and we can see further than the target we still get a penalty. What? It doesn't even take fCantSeeTarget into account.
fCantSeeTarget is used in function CalcNewChanceToHitAimTargetBonus and there it applies AIM_TARGET_INVISIBLE penalty.

Maybe I'm missing something here so if you still see a need for the above code we can always put it back but I would suggest to extend the if clause to:
if (iRange > 0 && iSightRange > iRange && fCantSeeTarget)

I prefer not to be penalized for seeing the target.

If there is no reason to put it back I agree that AIM_VISIBILITY should be removed from the code and CTHConstants.ini.


sevenfm wrote on Thu, 25 August 2016 22:33

ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); // Target ubID

ubTargetID can be NOBODY if we shoot at empty tile, but the code doesn't check that, passing wrong soldier pointer to SoldierToSoldierLineOfSightTest, this can result in crash in some situations (calc cth for shooting at invisible empty tile).
The same bug exists in CalcChanceToHitGun.

Simply changing the if clause to:
if (ubTargetID != NOBODY && iSightRange == 0)

should do the trick.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #346781 is a reply to message #346743] Thu, 01 September 2016 21:45 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Quote:
iSightRange is the distance that we can see.

It's not correct. sDistVis is the maximum visible distance.
sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;

iSightRange is effective visual distance to target.
If shooter can clearly see target, then iSightRange = iRange.
If there are some visual obstacles like grass or trees, then iSightRange will be greater than iRange, so some penalty will be applied because target cannot be seen clearly.
So I think that original code is ok.

[Updated on: Thu, 01 September 2016 21:51]




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #346785 is a reply to message #346781] Thu, 01 September 2016 22:59 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
sevenfm wrote on Thu, 01 September 2016 20:45

If shooter can clearly see target, then iSightRange = iRange.
If there are some visual obstacles like grass or trees, then iSightRange will be greater than iRange, so some penalty will be applied because target cannot be seen clearly.
So I think that original code is ok.

I see. In that case I will put back the code when I find some time, maybe this weekend.
Still gotta do the display for target movement penalty. So far the visual representation of the shadow reticle had some issues and I will have to find another solution.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #346805 is a reply to message #346785] Sat, 03 September 2016 15:00 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
I have put back the AIM_VISIBILITY calculation in CalcNewChanceToHitGun in r8294. I also fixed that possible NULL pointer condition.

Also I added a little indicator that is supposed to represent the penalty we get when aiming at a moving target.

http://picload.org/image/rrwdarlg/indicator4.png

The white arrow in picture 1 shows the movement direction of the target and is not part of the movement indicator. ;-)

The movement indicator is represented by 4 arrows to the side of the outer targeting ring. In the first picture they are barely noticeable because there is no penalty. The shooter is standing behind the target.

In the second picture you can see the shooter to the left of the target which means that he suffers full penalty. This initial penalty will be smaller the smaller the angle to the targets movement is.

The third picture shows that we can reduce the penalty by spending time on aiming. There is still a penalty but it's not as big as without aiming.

[Updated on: Sat, 03 September 2016 15:01]




Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #350370 is a reply to message #346805] Fri, 21 July 2017 21:43 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
CalcThrownChanceToHit:

if ( Item[ usHandItem ].mortar )
{
	if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
		iChance += (gSkillTraitValues.sCtHModifierMortar * max( 0, ((100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ))/100)));
	else
		iChance += gSkillTraitValues.sCtHModifierMortar; // -60% for untrained mercs
}

Looks like this expression
iChance += (gSkillTraitValues.sCtHModifierMortar * max( 0, ((100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ))/100)));

not only has too many brackets but also is wrong because dividing integer 100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) by integer 100 will always result in integer 0 or 1, so it should look like:
iChance += gSkillTraitValues.sCtHModifierMortar * max( 0, 100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT )) / 100;


Also, in CalcBestThrow:
// this is try to minimize enemies wasting their (limited) toss attacks:
switch( ubDiff )
{
case 0:
case 1:
	// don't use unless have a 70% chance to hit
	if (pBestThrow->ubChanceToReallyHit < 70)
	{
		pBestThrow->ubPossible = FALSE;
	}
	break;
case 2:
case 3:
case 4:
	// don't use unless have a 50% chance to hit
	if (pBestThrow->ubChanceToReallyHit < 50)
	{
		pBestThrow->ubPossible = FALSE;
	}
	break;
default:
	break;
}

AI soldier will not attack with grenade/GL/mortar if he has less than 50% CTH.
With default MORTAR_CTH_MODIFIER = -60 even perfect soldier with max stats (but without heavy weapons trait) will have CTH = 100% - 60% = 40% max, that means AI soldiers will never use mortars if someone decides to play with ASSIGN_SKILL_TRAITS_TO_ENEMY = FALSE.

[Updated on: Fri, 21 July 2017 21:58]




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350371 is a reply to message #350370] Fri, 21 July 2017 22:40 Go to previous messageGo to next message
silversurfer

 
Messages:2793
Registered:May 2009
You are correct, the formula in CalcThrownChanceToHit should be corrected.

As for CalcBestThrow I guess that the code is old and conservative. If a soldier fires tear gas or mustard gas it needs to be accurate as the cloud will be small at the start. Accuracy must be high or the grenade might land 10 tiles away from the target. With the standard HE grenades it doesn't matter that much cause we now have fragments that can hurt people in a certain radius. I wouldn't change the thresholds there in general but you could add clauses that check for ASSIGN_SKILL_TRAITS_TO_ENEMY with a lower threshold. This way you'd only use lower thresholds for people that don't assign traits to the enemy. The downside is that the enemy grenades could be wasted because of poor accuracy but it may be a nice firework. ;-)

What you also could do is to remove (or halve for example) the skill penalties for enemies if ASSIGN_SKILL_TRAITS_TO_ENEMY is FALSE. This would increase their accuracy across the board so they can reach the thresholds. Still, it's not an ideal solution.



Wildfire Maps Mod 6.07 on SVN: https://ja2svn.mooo.com/source/ja2/branches/Wanne/JA2%201.13%20Wildfire%206.06%20-%20Maps%20MOD

Report message to a moderator

Lieutenant
Re: Code Snippets[message #350507 is a reply to message #350371] Tue, 08 August 2017 14:33 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In HandleInitialRedAlert:
if ( bTeam == ENEMY_TEAM && gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_P && gbWorldSectorZ == 0 )
{
	// alert Queen and Joe if they are around
	...

It doesn't look right. There are mods that change the location of Queen, Joe and palace. Maybe these hardcoded values should be externalized somehow?



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350511 is a reply to message #350507] Tue, 08 August 2017 22:19 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In _GermanText.cpp:
STR16 pMilitiaButtonsHelpText[] =
{
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\Zuordnen (|L|i|n|k|s |K|l|i|c|k)\nGrüne Miliz", // button help text informing player they can pick up or drop militia with this button
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\Zuordnen (|L|i|n|k|s |K|l|i|c|k)\nReguläre Miliz",
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\Zuordnen (|L|i|n|k|s |K|l|i|c|k)\nElite Miliz",
L"Verteile Miliz gleichwertig über alle Sektoren",
};

compiler shows warning about unrecognized \ sequence, maybe it should look like:
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\nZuordnen (|L|i|n|k|s |K|l|i|c|k)\nGrüne Miliz", // button help text informing player they can pick up or drop militia with this button
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\nZuordnen (|L|i|n|k|s |K|l|i|c|k)\nReguläre Miliz",
L"Zuordnung auflösen (|R|e|c|h|t|s |K|l|i|c|k)\nZuordnen (|L|i|n|k|s |K|l|i|c|k)\nElite Miliz",
L"Verteile Miliz gleichwertig über alle Sektoren",



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350513 is a reply to message #350511] Tue, 08 August 2017 22:39 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
DisplayLoadScreenWithID:
const BOOLEAN fExternalLS = (szSector != NULL && szSector != "N") && ((DAY <= ubLoadScreenID && ubLoadScreenID <= NIGHT_ALT) || (ubLoadScreenID == UNDERGROUND));

probably should be
const BOOLEAN fExternalLS = (szSector != NULL && strcmp(szSector, "N") != 0) && ((DAY <= ubLoadScreenID && ubLoadScreenID <= NIGHT_ALT) || (ubLoadScreenID == UNDERGROUND));



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350514 is a reply to message #350507] Wed, 09 August 2017 03:44 Go to previous messageGo to next message
Buggler is currently offline Buggler

 
Messages:211
Registered:November 2009
sevenfm wrote on Tue, 08 August 2017 11:33
In HandleInitialRedAlert:
if ( bTeam == ENEMY_TEAM && gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_P && gbWorldSectorZ == 0 )
{
	// alert Queen and Joe if they are around
	...

It doesn't look right. There are mods that change the location of Queen, Joe and palace. Maybe these hardcoded values should be externalized somehow?


Maybe a quick externalization could used either
- Queen's location in MercProfiles.xml OR
- STRATEGIC_AI_SPAWN_SECTOR in Mod_Settings.ini



No savegame (just before e bug occurs), no cure.

'Not everything that counts can b counted, n not everything that can b counted counts' - Albert Einstein
I may answer/reply in my old public posts & prefer PM over e former [FUDforum's PM suxx]

Report message to a moderator

Sergeant 1st Class
Re: Code Snippets[message #350515 is a reply to message #350514] Wed, 09 August 2017 08:45 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
@Buggler
I made a quick fix that only checks that Queen/Joe are in the same sector to alert them:
// alert Queen and Joe if they are around
SOLDIERTYPE *			pSoldier;

pSoldier = FindSoldierByProfileID( QUEEN, FALSE );
if( pSoldier && 
	pSoldier->sSectorX == gWorldSectorX &&
	pSoldier->sSectorY == gWorldSectorY &&
	gbWorldSectorZ == 0 )
{
	pSoldier->aiData.bAlertStatus = STATUS_RED;
}

pSoldier = FindSoldierByProfileID( JOE, FALSE );
if( pSoldier && 
	pSoldier->sSectorX == gWorldSectorX &&
	pSoldier->sSectorY == gWorldSectorY &&
	gbWorldSectorZ == 0 )
{
	pSoldier->aiData.bAlertStatus = STATUS_RED;
}

Maybe need to check bLife and bActive also to make sure they are alive and functioning.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350779 is a reply to message #350515] Tue, 29 August 2017 12:45 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Soldier Control.cpp, AIDoctorSelf()
// alert ourself
this->aiData.bAlertStatus	  = min(this->aiData.bAlertStatus,  STATUS_RED);

Should be
this->aiData.bAlertStatus	  = max(this->aiData.bAlertStatus,  STATUS_RED);

Currently it will lower alert status from BLACK to RED.

same is in FreePrisoner():
// alert both soldiers
this->aiData.bAlertStatus = min( this->aiData.bAlertStatus, STATUS_RED );
pSoldier->aiData.bAlertStatus = min( pSoldier->aiData.bAlertStatus, STATUS_RED );

and in EVENT_SoldierHandcuffPerson()
// alert the soldier
pSoldier->aiData.bAlertStatus = min( pSoldier->aiData.bAlertStatus, STATUS_RED );

and in EVENT_SoldierApplyItemToPerson()
// alert the soldier
pSoldier->aiData.bAlertStatus = max( pSoldier->aiData.bAlertStatus, STATUS_RED );



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350785 is a reply to message #350779] Tue, 29 August 2017 13:43 Go to previous messageGo to next message
Flugente

 
Messages:3509
Registered:April 2009
Location: Germany
Urgs. That was rather stupid of me. I'll commit the fix when i'm back home (unless you do it first).

Edit: Fixed in r8465.

[Updated on: Tue, 29 August 2017 20:57]




I know now that it could never work between us, as much as we wanted to, it could never be! Not because you're a rabbit, but because you're black.

If you want, you can donate to me. This will not affect how and what I code, and I will not code specific features in return. I will be thankful though.

Report message to a moderator

Captain

Re: Code Snippets[message #350796 is a reply to message #350785] Wed, 30 August 2017 10:22 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In CreatureDecideAction.cpp, CreatureDecideActionBlack():
// if we found one								
if (!TileIsOutOfBounds(sClosestDisturbance))
{
	// then make decision as if at alert status RED, but make sure
	// we don't try to SEEK OPPONENT the unconscious guy!
	return(DecideActionRed(pSoldier,FALSE));
}

Looks like a copypaste bug from DecideActionBlack(), should be:
return(CreatureDecideActionRed(pSoldier,FALSE));

As calling DecideActionRed() for creature may result in bad things.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #350808 is a reply to message #350796] Thu, 31 August 2017 11:24 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Also it seems that fBuckshot is not initialized properly in UseGunNCTH except for throwing knives, this can potentially cause problems when shooting.

Easy fix:
BOOLEAN fBuckshot = 0;

[Updated on: Thu, 31 August 2017 11:24]




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #351487 is a reply to message #350808] Wed, 15 November 2017 12:37 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
Looking at the code in Queen Command.cpp:
// HEADROCK HAM 3.2: enemy reinforcements arrive with 0 APs.
if (gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 1 || gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 2)
{			
	pSoldier->bActionPoints = 0;

	// Flugente: due to a fix, also note here that the reinforcements get no APs.
	pSoldier->usSoldierFlagMask |= SOLDIER_NO_AP;

	// Flugente: campaign stats
	if ( IsOurSoldier(pSoldier) )
		gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_PLAYERSIDE;
	else
		gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_ENEMY;
}

Why we apply campaign stats only when reinforcements arrive with zero AP?

[Updated on: Wed, 15 November 2017 14:04]




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #351983 is a reply to message #351487] Thu, 11 January 2018 02:00 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
in CalcBulletDeviation():
iRangeRatio = __max(1.0f, (FLOAT)(uiRange / sEffRange));

Since uiRange is UINT32 and sEffRange is UINT16, it will probably not work as intended.

[Updated on: Thu, 11 January 2018 02:23]




Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #352925 is a reply to message #351983] Tue, 03 April 2018 20:32 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
In Assignments.cpp:

void UpdatePatientsWhoAreDoneHealing( void )
pSoldier = MercPtrs[0];
...
// Flugente: stats can also be damaged
if ( !gGameOptions.fFoodSystem || (gGameOptions.fFoodSystem && pSoldier->bFoodLevel > FoodMoraleMods[FOOD_NORMAL].bThreshold && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_NORMAL].bThreshold) )
{
	if ( pSoldier->usStarveDamageHealth > 0 || pSoldier->usStarveDamageStrength > 0 )
		fHasDamagedStat = TRUE;
}

Probably should be pTeamSoldier instead of pSoldier which always points to MercPtrs[0]



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #352929 is a reply to message #352925] Tue, 03 April 2018 22:40 Go to previous messageGo to next message
Flugente

 
Messages:3509
Registered:April 2009
Location: Germany
Oooh. That was stupid, thanks for spotting it, fixed in r8550.


I know now that it could never work between us, as much as we wanted to, it could never be! Not because you're a rabbit, but because you're black.

If you want, you can donate to me. This will not affect how and what I code, and I will not code specific features in return. I will be thankful though.

Report message to a moderator

Captain

Re: Code Snippets[message #353872 is a reply to message #352929] Fri, 22 June 2018 20:00 Go to previous messageGo to next message
Deleted.

 
Messages:2663
Registered:December 2012
Location: Russian Federation
in AIUtils.cpp:

UINT8 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight )
...
    // go through each soldier, looking for "friends" (soldiers on same team)
    for (uiLoop = gTacticalStatus.Team[ auTeam ].bFirstID; uiLoop < gTacticalStatus.Team[ auTeam ].bLastID; ++uiLoop)
    {
        pFriend = MercPtrs[ uiLoop ];
...

Why bLastID is not included in the loop?
Looking at other places in the code, bLastID is real last id of the team that should be used.
There are also some other places in the game code where bLastID is excluded from search.



Left this community.

Report message to a moderator

Lieutenant

Re: Code Snippets[message #353874 is a reply to message #353872] Sat, 23 June 2018 18:45 Go to previous messageGo to previous message
Taleman is currently offline Taleman

 
Messages:68
Registered:October 2010
Location: Finland
Could any JA2 coder be encouraged to fix using mouse wheel under Wine? I have played only under wine for a few years already, and it works better than under windows. Only thing that does not work is mouse wheel.

Testing notepad.exe under wine shows that mouse wheel can be made to work.

Report message to a moderator

Corporal
Previous Topic: New Attachment System Beta
Goto Forum:
  


Current Time: Fri Mar 29 08:02:57 GMT+2 2024

Total time taken to generate the page: 0.02744 seconds