Home » MODDING HQ 1.13 » v1.13 Coding Talk » Code Snippets
() 1 Vote
|
Re: Code Snippets[message #355680 is a reply to message #355664]
|
Mon, 05 November 2018 22:50
|
|
ZedJA2 |
|
Messages:202
Registered:January 2018 |
|
|
What I downloaded comes as a 0 byte JA2_8635.exe file and as a JA@_8635.exe.part file of 8646 KB. Do I have to process this somehow? When I go ahead and have 7-Zip unpack the archive, it then has a rsrc, data, and other folder. Am I supposed to then start the JA2_8635.exe file in the same folder or is this some sort of thing I need to compile or use SVN software on?
Report message to a moderator
|
Sergeant 1st Class
|
|
|
|
Re: Code Snippets[message #355923 is a reply to message #355681]
|
Wed, 21 November 2018 16:21
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Overhead.cpp, CheckStatusNearbyFriendlies()
UINT8 ubLevelDifference = 0;
...
ubLevelDifference = (pLeader->stats.bExpLevel - pSoldier->stats.bExpLevel );
...
What will happen if pLeader->stats.bExpLevel < pSoldier->stats.bExpLevel?
Later the code checks:
if ( ubLevelDifference >= 0 )
which makes no sense at all because UINT8 cannot be negative.
Something is definitely wrong here.
[Updated on: Wed, 21 November 2018 16:33]
Left this community.Report message to a moderator
|
|
|
|
|
|
|
Re: Code Snippets[message #356091 is a reply to message #355649]
|
Mon, 03 December 2018 17:11
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
silversurfer wrote on Sun, 04 November 2018 22:52I figured it out. The standing up nonsense after jumping came from code that was commented, which I had to uncomment but it was bugged (probably the reason why it was commented...) so I also had to fix it. Now the merc properly takes the stance that he should no matter if he continues his path after jumping over a fence or not.
Just a minor issue - if you order merc to jump using [j] key, he will always stand up no matter what his original stance was (though the game at least correctly deducts AP points for standing). Could be dangerous in some situations.
Also maybe you know what prevents prone merc from plotting path over fence? In theory, he could crawl to it, jump over, and then continue crawling. It would be good for AI to allow crawling movement over fences, currently it limits usefulness of this movement mode for AI as it cannot plot path over fences.
[Updated on: Mon, 03 December 2018 17:25]
Left this community.Report message to a moderator
|
|
|
|
|
|
Re: Code Snippets[message #356103 is a reply to message #356093]
|
Wed, 05 December 2018 09:15
|
|
ZedJA2 |
|
Messages:202
Registered:January 2018 |
|
|
That actually makes a lot of sense. There are numerous places where you cannot go prone, but think you can, and usually these are near objects of some kind, like trees or fences.
Perhaps then, the better fix (but more involved) would be to allow the character to go to the Standing stance, but not cost anything to choose whatever ending stance they use once having jumped over the obstacle.
I mean, in real life, you would just choose what amount of leg power you want to use as you drop from the jump, and then just either stand, or reduce leg strength and fall with gravity into a crouch, or then drop fully, again mostly reducing leg strength to counter gravity and fall forward. Arguably, the soldier could do almost all of these in about the same amount of time, and with similar amounts of effort to achieve any post-jump stance, so using APs to choose stance after the obstacle is rather nonsensical. You use energy to clear the obstacle, not so much to hit the dirt or remain standing. Your final stance could be anything you chose after jumping, the AP cost would practically be the same, as would the time involved (if well practiced and used to hitting the dirt/hard ground).
So, if this is just a mechanic, the standing up first, to make sure you fit in the terrain available, because then it checks to see if it can go prone, but it cannot since not enough "room" to go prone in the terrain -- that's really the solution.
The problem is that standing after jumping may burn extra APs, and or doing prone after standing per the game's MECHANICS. Perhaps we just have to make sure what all stances after jumping back to ground, cost the same. Well also with climbing to the roof. You constantly waste APs because you are first forced into a crouched stance when you climb to the top and arrive on the roof, when in reality, when you pull yourself over the ledge, you will go with your momentum and finish at the stance you decide (barring injury). There is energy burnt there for taller stances when climbing though. But not when jumping downwards after you clear an obstacle or when jumping down to the ground. So I do believe you are right, SilverSurfer, that it is just an odd way to check for terrain clearance to fit a prone character in that direction. That's the other part of it as well, you don't get to choose what direction you face when you clear the fence -- which forces you to fit in certain terrain but not others depending on the room available when perhaps a mere turn of 90 degrees would avoid the change in stance.
[Updated on: Wed, 05 December 2018 09:17] Report message to a moderator
|
Sergeant 1st Class
|
|
|
|
Re: Code Snippets[message #356142 is a reply to message #356132]
|
Mon, 10 December 2018 23:19
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
XML_Merge.cpp
struct
{
PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
UINT16 curMerge[6];
UINT32 maxArraySize;
UINT32 curIndex;
UINT32 currentDepth;
UINT32 maxReadDepth;
}
typedef mergeParseData;
later curMerge[6] is initialised
memset(&pData->curMerge,0,sizeof(UINT16[4]));
something like
memset(&pData->curMerge,0,sizeof(pData->curMerge);
should work better.
[Updated on: Mon, 10 December 2018 23:19]
Left this community.Report message to a moderator
|
|
|
|
Re: Code Snippets[message #356150 is a reply to message #356142]
|
Wed, 12 December 2018 06:10
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Items.cpp, AttachObjectNAS()
case COMBINE_POINTS:
...
// add part of this one and then we're done
attachmentAmount = (UINT16)(*pAttachment)[0]->data.objectStatus;
attachmentAmount -= (ubLimit - (UINT16)(*this)[subObject]->data.objectStatus);
(*pAttachment)[0]->data.objectStatus = attachmentAmount;
if ((*pAttachment)[0]->data.ubShotsLeft == 0) {
pAttachment->RemoveObjectsFromStack(1);
}
(*this)[subObject]->data.ubShotsLeft = ubLimit;
break;
Why the code checks for shots left instead of objectStatus? This merge doesn't change shots left, only item status.
In my view, this code should look like:
if ((*pAttachment)[0]->data.objectStatus == 0) {
pAttachment->RemoveObjectsFromStack(1);
}
(*this)[subObject]->data.objectStatus = ubLimit;
break;
Can anyone explain it please?
Another strange code in Weapons.cpp, UseThrown()
HandleSoldierThrowItem(pSoldier, pSoldier->sTargetGridNo);
pSoldier->inv[HANDPOS].RemoveObjectsFromStack(1);
...
// anv: knife throw attack noise
UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
UINT8 ubVolume = Weapon[ usUBItem ].ubAttackVolume;
MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_UNKNOWN );
return( TRUE );
First we destroy the object in hands (thrown grenade), then check if weapon in hand has attack volume.
[Updated on: Wed, 12 December 2018 06:11]
Left this community.Report message to a moderator
|
|
|
|
Re: Code Snippets[message #357817 is a reply to message #356150]
|
Fri, 09 August 2019 20:11
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Looking at HourlyUpdate.lua
-- Bar/night club
if ( cHour >= 15 or cHour < 2) then
SetFactTrue( Facts.FACT_CLUB_OPEN )
SetFactFalse( Facts.FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED )
-- Reset boxes fought
for i = 0,2 do
-- Set false
gfBoxerFought(i,false)
end
-- If # of boxing matches the player has won is a multiple of
-- 3, and the boxers haven't rested, then make them rest
if ( gfBoxersResting == true ) then
-- Done resting now!
gfBoxersResting = false
gubBoxersRests = gubBoxersRests + 1
p = gubBoxingMatchesWon / 3
elseif ( p > gubBoxersRests ) then
-- Time for the boxers to rest!
gfBoxersResting = true
end
else
SetFactFalse( Facts.FACT_CLUB_OPEN )
end
I don't think it will work. This script gets access to gfBoxersResting and gubBoxersRests by registering them in Luaglobal.cpp
lua_pushboolean(L, gfBoxersResting);
lua_setglobal(L, "gfBoxersResting");
lua_pushinteger(L, gubBoxersRests);
lua_setglobal(L, "gubBoxersRests");
But as far as I understand, it only allows read access to C++ variables, so the code
gfBoxersResting = false
gubBoxersRests = gubBoxersRests + 1
doesn't change anything actually.
I think we need new functions l_SetgfBoxersResting and l_SetgubBoxersRests and use them in lua like:
SetgfBoxersResting(false)
SetgubBoxersRests(gubBoxersRests + 1)
Also, comparing the code with original C++ hardcoded hourly update, it looks very strange, for example, in original code we only execute it twice, at 15 and 2 hour, not every hour between 15 and 2.
Currently, even if lua script would work, it would change gfBoxersResting = true to false immediately next hour after the player have won the third battle, instead of waiting for the next day's 15 hour.
And I don't understand why use local p variable?
Currently, my HourlyUpdate.lua looks like:
Toggle SpoilerFacts =
{
FACT_BROTHEL_OPEN = 251,
FACT_MUSEUM_OPEN = 250,
FACT_CLUB_OPEN = 252,
FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED = 107,
}
--local p = 0
function HourlyQuestUpdate()
--if (cHour >= 4 or cHour < 20) then
if (cHour == 4) then
SetFactFalse( Facts.FACT_BROTHEL_OPEN )
elseif (cHour == 20) then
SetFactTrue( Facts.FACT_BROTHEL_OPEN )
end
-- Bar/night club
--if ( cHour >= 15 or cHour < 2) then
if ( cHour == 15 ) then
SetFactTrue( Facts.FACT_CLUB_OPEN )
SetFactFalse( Facts.FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED )
-- Reset boxes fought
for i = 0,2 do
-- Set false
gfBoxerFought(i,false)
end
-- If # of boxing matches the player has won is a multiple of
-- 3, and the boxers haven't rested, then make them rest
if ( gfBoxersResting == true ) then
-- Done resting now!
--gfBoxersResting = false
SetgfBoxersResting(false)
--gubBoxersRests = gubBoxersRests + 1
SetgubBoxersRests(gubBoxersRests + 1)
elseif ( gubBoxingMatchesWon / 3 > gubBoxersRests ) then
-- Time for the boxers to rest!
--gfBoxersResting = true
SetgfBoxersResting(true)
end
elseif ( cHour == 2 ) then
SetFactFalse( Facts.FACT_CLUB_OPEN )
end
-- Museum
--if ( cHour >= 9 or cHour < 18 ) then
if ( cHour == 9 ) then
SetFactTrue( Facts.FACT_MUSEUM_OPEN )
elseif ( cHour == 18 ) then
SetFactFalse( Facts.FACT_MUSEUM_OPEN )
end
end
and seems to work well.
Also, in l_ResetBoxers() function which is called every time player loads sector, gfBoxerFought[] is reset:
// set boxer ids back to NOBODY, so they can be reinitialised
static int l_ResetBoxers( lua_State *L )
{
for ( UINT8 i = 0; i < NUM_BOXERS; ++i )
{
gubBoxerID[i] = NOBODY;
gfBoxerFought[i] = FALSE;
}
return 0;
}
which is incorrect in my view, because gfBoxerFought[] should be reset in lua script every day at 15 hours, not every time player enters sector.
Also, after you have fought 3 times, manager will not talk with you, but if you wait until after midnight but before 2 hours, something is reset in his script and he will talk to you, allowing you to fight. Something in his script is reset every day at 24:00, but I dont't know where to find it.
What do you boxing/lua experts think?
[Updated on: Fri, 09 August 2019 22:26]
Left this community.Report message to a moderator
|
|
|
|
|
Re: Code Snippets[message #357842 is a reply to message #357832]
|
Mon, 12 August 2019 04:48
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
silversurfer wrote on Sun, 11 August 2019 13:37However, we should set gfBoxersResting to true when we have done 3 fights, no matter if it is 17 or 23 or whatever on the clock.
I think the original idea was that if player wins 3 fights, next day at 15 hours gfBoxersResting is set to true, as a result, player cannot fight this day, next day at 15 hours gfBoxersResting is set to false and player can fight again.
If we set gfBoxersResting immediately after the player have won 3 fights, next day at 15 hours it will be set to false and player can fight again, making the resting system useless as player now can fight 3 times every day and not waiting for one day between fights as it was in vanilla.
Quote:I think you are right that ResetBoxers() should be removed from strategicmap.lua and instead be used in HourlyUpdate.lua and we may need new functions to set gfBoxersResting and gubBoxersRests.
I think that ResetBoxers() should stay wehere it is now, because as I understand it it is called when new sector is loaded, and it's function since vanilla was to clean boxers IDs so the game can assign new ids for newly loaded sector. BoxersFought should be cleared at 15 hours every day as it was in vanilla, when the club opens, at least it's how I understand it at the moment.
With my changes, boxing seems to work better than before, but one problem still exists - Darren's dialogue status seems to be reinitialized only at 00:00, that means even if boxers are not resting and all 3 are available, you cannot have "another fight" until 00:00, that makes opening club at 15 hours meaningless. Unfortunately, I don't know where to look for Darren's dialogue and script to make it reset "another fight" option to 15 hours.
[Updated on: Mon, 12 August 2019 04:58]
Left this community.Report message to a moderator
|
|
|
|
|
|
|
Re: Code Snippets[message #357861 is a reply to message #357853]
|
Tue, 13 August 2019 14:35
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Something I don't understand in Lua, for example if I use test script:
-- Bar/night club
if ( cHour == 15 ) then
SetScreenMsg(FontColour.FONT_MCOLOR_DKWHITE, "Boxing club opened")
SetFactTrue( Facts.FACT_CLUB_OPEN )
SetFactFalse( Facts.FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED )
elseif ( cHour == 2 ) then
SetScreenMsg(FontColour.FONT_MCOLOR_DKWHITE, "Boxing club closed")
SetFactFalse( Facts.FACT_CLUB_OPEN )
end
The message "Boxing club opened" will appear at 16:00 and "Boxing club closed" will appear at 3:00.
At the same time, Darren appears in club at correct time 15:00 and disappears at 2:00.
cHour is defined in LuaGlobal.cpp as uiHourLua
lua_pushinteger(L, uiHourLua);
lua_setglobal(L, "cHour");
and uiHourLua is defined in Game Closck.cpp as:
guiHour = ( guiGameClock - ( guiDay * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR;
uiHourLua = guiHour;
So it should work correctly, but it doesn't.
If I add
to the start of HourlyQuestUpdate() in HourlyUpdate.lua, the script suddenly starts to work correctly and opens club at 15:00
[Updated on: Tue, 13 August 2019 14:47]
Left this community.Report message to a moderator
|
|
|
|
|
Re: Code Snippets[message #357863 is a reply to message #357862]
|
Tue, 13 August 2019 21:09
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Also it seems that
if ( gubBoxingMatchesWon / 3 > gubBoxersRests ) then
doesn't work because the resulting value is probably float in lua, unlike c++, so I changed it to
if ( math.floor(gubBoxingMatchesWon / 3) > gubBoxersRests ) then
and it seems to work correctly now.
Maybe it was the reason of p variable introduction? But it has no type, I doubt it auto converts value into int.
silversurfer wrote on Tue, 13 August 2019 20:00Have you tried modifying FACT_NO_CLUB_FIGHTING_ALLOWED when you modify the resting status of the boxers? My hope is that it updates Darren immediately instead of 24:00 o'clock.
As I understand it, FACT_NO_CLUB_FIGHTING_ALLOWED is defined dynamically each time NPC script asks for it:
quests.cpp
case FACT_NO_CLUB_FIGHTING_ALLOWED:
SOLDIERTYPE * pKingpin;
pKingpin = FindSoldierByProfileID( KINGPIN, FALSE );
if ( pKingpin )
gubFact[usFact] = ( gubQuest[ QUEST_KINGPIN_MONEY ] == QUESTINPROGRESS || gfBoxersResting || ( !BoxersAvailable() && PythSpacesAway(pKingpin->sGridNo, gModSettings.iKingpinRingTile) > 2 ) );
else
gubFact[usFact] = TRUE;
break;
The problem here is that we need BoxersAvailable() check, or Darren will allow boxing matches sometimes with unavailable boxers due to the way his script works, but if we just leave this check, he will not give money after fight, because conditions 21, 22, 23 check FACT_NO_CLUB_FIGHTING_ALLOWED (for no reason in my opinion, because if they are called that means that fight already happened, so no need for additional check).
Currently PythSpacesAway(pKingpin->sGridNo, gModSettings.iKingpinRingTile) > 2 condition is used to allow finishing fight and giving money when all boxers are beaten/killed, but it's not reliable, because there can be cases when Kingpin stands near ring but there are no boxers available, then player can wait until midnight, Darren's script will refresh and allow him to fight, resulting in a bug.
[Updated on: Tue, 13 August 2019 21:13]
Left this community.Report message to a moderator
|
|
|
|
Re: Code Snippets[message #357951 is a reply to message #357863]
|
Fri, 23 August 2019 13:57
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Something I don't understand.
Weapons.cpp, CalcChanceHTH()
// CALCULATE ATTACKER'S CLOSE COMBAT RATING (1-100)
if (ubMode == HTH_MODE_STEAL)
{
///////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Enhanced Close Combat System - different calculation for stealing
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
{
// We need to be agile and dexterous
iAttRating = ( 2 * EffectiveDexterity( pAttacker, FALSE ) + // coordination, accuracy *
2 * EffectiveAgility( pAttacker, FALSE ) + // speed & reflexes
pAttacker->stats.bStrength + // physical strength
pDefender->bExtraStrength + // additional strength from power armour
(10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
}
...
We add attacker's strength but defender's extra strength? How defender's strengh can help to steal weapon?
At the same time, when we calculate defender's rating, we only use his strength:
// CALCULATE DEFENDER'S CLOSE COMBAT RATING (0-100)
if (ubMode == HTH_MODE_STEAL)
{
// SANDRO - Enhanced Close Combat System - stealing defence based on dexterity and strength
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
{
iDefRating = ( EffectiveAgility( pDefender, FALSE )) + // speed & reflexes
2 * EffectiveDexterity( pDefender, FALSE ) + // coordination, accuracy
2 * pDefender->stats.bStrength + // physical strength
2 * pDefender->bExtraStrength + // additional strength from power armour
(10 * EffectiveExpLevel( pDefender ) ); // experience, knowledge
}
...
Left this community.Report message to a moderator
|
|
|
|
|
Re: Code Snippets[message #357995 is a reply to message #357953]
|
Mon, 02 September 2019 23:51
|
|
PltSgtMac |
Messages:1
Registered:September 2019 |
|
|
I think I have found an oversight in the code relating to "sector coolness". When calculating relative level by location on the map in Soldier Create.cpp:
// this returns 0 to DIFF_FACTOR_PALACE_DISTANCE (0 to +30)
ubLocationModifier = GetLocationModifier( ubSoldierClass );
It is assumed that it ranges from 0 to +30, but in GetLocationModifier() we see this:
HEADROCK HAM 5:
// The calculation has been replaced with an XML table.
ubLocationModifier = gCoolnessBySector[SECTOR(sSectorX, sSectorY)];
gCoolnessBySector seems to return a value between 0 and +20 for that sector from CoolnessBySector.xml
In the original code the value does range between 0 and +30:
// adjust for distance from Queen's palace (P3) (0 to +30)
ubLocationModifier = ( ( MAX_PALACE_DISTANCE - ubPalaceDistance ) * DIFF_FACTOR_PALACE_DISTANCE ) / MAX_PALACE_DISTANCE;
The .xlm file seems to be a simple Pythagorean distance formula replacement for the original formula:
// how far is this sector from the palace ?
// the distance returned is in sectors, and the possible range is about 0-20
ubPalaceDistance = GetPythDistanceFromPalace( sSectorX, sSectorY );
if ( ubPalaceDistance > MAX_PALACE_DISTANCE )
{
ubPalaceDistance = MAX_PALACE_DISTANCE;
}
All of this results in too low values (-5 to +11 instead of -5 to +14) for bAdjustedRoll in RandomizeRelativeLevel():
// convert to 0 to 10 (divide by 3), the subtract 5 to get a range of -5 to +5
bRollModifier = ( INT8 ) ( ubLocationModifier / ( DIFF_FACTOR_PALACE_DISTANCE / 10 ) ) - 5;
// convert to 0 to 10 (divide by 3), the subtract 5 to get a range of -5 to +5
bRollModifier = ( INT8 ) ( ubLocationModifier / ( DIFF_FACTOR_PALACE_DISTANCE / 10 ) ) - 5;
// roll a number from 0 to 9
bRoll = ( INT8 ) Random( 10 );
// adjust by the modifier (giving -5 to +14)
bAdjustedRoll = bRoll + bRollModifier;
This leads to lower chance of getting a high value for *pbRelLevel (Headrock called this Equipment Modifier in "How does it work? Part 11: Enemy Gun Selection"). In the end this means lower than expected random enemy/militia level (on average at least).
Of course I could just be missing something obvious.
Report message to a moderator
|
Civilian
|
|
|
Re: Code Snippets[message #358024 is a reply to message #357995]
|
Tue, 10 September 2019 21:39
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
In Interface.cpp\DrawCTHIndicator()
if ( gGameCTHConstants.IRON_SIGHTS_MAX_APERTURE_USE_GRADIENT && gCTHDisplay.ScopeMagFactor <= 1.0 && !pSoldier->IsValidAlternativeFireMode( pSoldier->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) )
...
if ( gCTHDisplay.ScopeMagFactor <= 1.0 && !pSoldier->IsValidAlternativeFireMode( pSoldier->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) )
...
// which bonus do we want to apply?
if ( pSoldier->IsValidAlternativeFireMode( pSoldier->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) )
...
FLOAT iMagFactor = CalcMagFactor( pSoldier, pWeapon, d2DDistance, gCTHDisplay.iTargetGridNo, (UINT8)pSoldier->aiData.bAimTime );
I think it should be pSoldier->aiData.bShownAimTime instead of pSoldier->aiData.bAimTime, like it's used later in this function:
//Get AP cost to fire this many bullets
INT16 sAPCosts = CalcTotalAPsToAttack( pSoldier, gCTHDisplay.iTargetGridNo, TRUE, pSoldier->aiData.bShownAimTime);
I think that aiData.bAimTime may be not set in this function yet.
Left this community.Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Code Snippets[message #358298 is a reply to message #358256]
|
Sun, 20 October 2019 00:17
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
Looking at opplist.cpp\MovementNoise()
INT8 bInWater = FALSE;
...
if (bInWater)
{
ubMaxVolume++; // in water, can be even louder
}
Great, but we never check tile for water before, should be
INT8 bInWater = Water(pSoldier->sGridNo)
probably.
Also,
UINT8 ubVolume;
...
ubVolume = 1 + ((iRoll - iStealthSkill + 1) / 16); // volume is 1 - 7 ...
...
case CRAWLING:
ubVolume -= 2;
break;
Now, if we have high stealth skill (or we are lucky to have low iRoll), and we are crawling, the resulting noise level will be UINT8(-1).
Having
if (ubVolume < 1)
{
ubVolume = 0;
}
is nice but I don't think it will help if ubVolume is already 255.
Also, the animation state is checked for
switch (pSoldier->usAnimState)
{
case CRAWLING:
ubVolume -= 2;
break;
case SWATTING:
ubVolume -= 1;
break;
case RUNNING:
ubVolume += 3;
break;
}
CRAWLING, SWATTING and RUNNING animation, but what about other anmation states like SWATTING_WK, RUNNING_W_PISTOL etc?
As far as I understand, pSoldier->usAnimState is not limited to only three types of animation, or am I wrong here?
[Updated on: Sun, 20 October 2019 05:11]
Left this community.Report message to a moderator
|
|
|
|
|
Re: Code Snippets[message #358318 is a reply to message #358311]
|
Tue, 22 October 2019 23:48
|
|
Deleted. |
|
Messages:2663
Registered:December 2012 Location: Russian Federation |
|
|
silversurfer wrote on Mon, 21 October 2019 13:47As for the animation I'm not sure. Maybe it's better to use pSoldier->usUIMovementMode? As far as I can see this is used to store the current movement mode (CRAWLING, SWATTING, WALKING, RUNNING) and despite the name it is used for all characters, not just player mercs.
I've done some testing, and it seems to work well with usUIMovementMode, except swatting with knife mode which sets usUIMovementMode to 314 instead of 5 (uses the same value as usAnimState) which is a bug probably.
Looks like the problem is in GetMoveStateBasedOnStance()
case ANIM_CROUCH:
if ( this->flags.fUIMovementFast )
{
return(SWATTING);
}
else
{
//***ddd
// only 1 bodytime is ready (drawn) currently, the rest need to be added
UINT16 usItem = this->inv[HANDPOS].usItem;
if ( this->inv[HANDPOS].exists( ) == true &&
//(this->ubBodyType == BIGMALE || this->ubBodyType == REGFEMALE )&&
(Item[usItem].usItemClass == IC_BLADE || Item[usItem].usItemClass == IC_THROWING_KNIFE) )
return(SWATTING_WK);
else
return(SWATTING);
}
break;
I don't think SWATTING_WK is a valid movement mode, it should return SWATTING always probably.
Tested it, and if we disable returning SWATTING_WK in GetMoveStateBasedOnStance(), then swatting with knife animation is not shown, it uses default swatting animation.
Looks like it was coded with some weird hack.
[Updated on: Wed, 23 October 2019 01:52]
Left this community.Report message to a moderator
|
|
|
|
Goto Forum:
Current Time: Thu Apr 18 02:24:10 GMT+3 2024
Total time taken to generate the page: 0.06411 seconds
|