Home » MODDING HQ 1.13 » v1.13 Coding Talk » Code Snippets  () 1 Vote
Code Snippets[message #172712] Wed, 23 January 2008 23:27 Go to next message
Madd_Mugsy

 
Messages:637
Registered:July 2005
Location: Canada
I know there are some coders out there who are making some bug fixes and adding some new stuff, but aren't a part of the 1.13 team (not yet anyway Wink). Some of you are making big mods with lots of changes, and some of you are just making a few tweaks and fixes for your own enjoyment.

I invite all you coders to post your bug fixes and code tweaks in this thread. They will be reviewed by myself and/or other 1.13 coders and may be included in future versions of 1.13 if they are solid and well received. Of course, you will be given credit if your fix/tweak makes it into the main code stream Smile

You can post code in the forum by using the "code" tag:


\\here is some code



Re: Code Snippets[message #172716] Wed, 23 January 2008 23:41 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
Thanks Mugsy. Sometimes few files are needed to demonstrate, we will post the links.
Re: Code Snippets[message #172747] Thu, 24 January 2008 04:27 Go to previous messageGo to next message
Kaiden

 
Messages:518
Registered:September 2003
I would also like to add, that a jumble of features in a beta test all at one time, is not such a great idea, and the mods should probably not be used together in conjunction, or at least not without a seperate download. Writing a bunch of code and throwing it together makes bug-hunting more difficult, and it also makes it more difficult to pull out certain features for 1.13 without missing peices of the code, or including code from other features. The exception, would be if each section of code was documented well enough to know which feature it belongs to and if each feature is entirely independant of the rest.


I know that quite a few players want NIV, and since the code is readily available, it's being included as a base for other coding projects. It's not so much of a problem with NIV, because it's fairly stable already, and has such a vast number of testers, that taking a few away isn't hurting anything. It may cause more harm than good though in the future with any 1.13 team sanctioned-but-not-yet-included projects, such as problems finding bugs, due to too many versions of the same code, incompatible save-games for one coder to test. Trust me, we've run into the same problem in the past within the team with just a hand full of coders.

[Updated on: Thu, 24 January 2008 04:41] by Moderator



Re: Code Snippets[message #172755] Thu, 24 January 2008 09:46 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
Somehow a balance should be found, a balance between new features and fixing current code, because stopping the progress may not be also a good ideea. This project will never be over, so there will never be a point where you can say "now we can add new things because everything works perfect", so this should be done along the way. New features should be added one by one, to be easier to track changes, bugs etc.

Its hard to say how it should look like, but I think its hard to keep it a platform. For example NIV has so great success that everybody will want to play it with or without another mod on top. So NIV should be part and will become part of 1.13 standard, but slowly, all these new things all the time change the platform ideea. I think we better get use to see 1.13 more like a new game with great modding support than like a platform for mods, alone. Again, hard to say what's best for the future, I may be wrong...
Re: Code Snippets[message #172757] Thu, 24 January 2008 10:12 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

Code that just externalizes things shouldn't introduce more bugs if done properly. Plus it's a great present for mod or TC developers!

I think a GUN_RANGE_MULTIPLIER/DIVIDER isn't gonna cause any problems. The problem is I had to modify 3 files, how should I put the code here?

@Afp
My vission of 1.13 it's not of JA2, but of a game engine that allows you to make a complete different game or TC (Total Conversion). This means EXTERNALIZING everything.

Also I don't mind removing all old code from JA2 (like old inventory and some commented out code from demo version)

btw Game Starting Sector is complete, it just needs some beta testing.. I'll upload later Wink

[Updated on: Thu, 24 January 2008 10:17] by Moderator

Re: Code Snippets[message #172761] Thu, 24 January 2008 10:37 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
Bellow I tried to set up the guidelines for a possible development system built as a balance between new features and current 1.13:


[color:#000099]1. "1.13 mod" is s new game built based on Jagged Alliance 2 source code. It is not a mod as the executable itself changed. It could be renamed.

2. 1.13 should include all files so no need for the original game - licence should be checked for this. In case the license does not allow this, this step will be skipped.

3. 1.13 is in continous development. New features are added to it while the existing bugs are fixed;

4. Anyone can try to add a new feature to the game. In order to do this, this steps should be followed:

- create a "New feature candidate" containing source code, documentation, and demo executable (if exist) based on the latest main 1.13 source code. In case of XML, the package will contain all XML files modified. The New Feature Candidate Demo will contain a single archive file that follow 1.13 folders structure + documentation.
- people can install this package and test it.
- after a certain amount of time, the "New feature candidate" is put on a public poll system and discussion thread, with the question: "Should this new feature be included in 1.13 game?"
- before integration (or before poll submission), the new feature should get the accept from the developers team that this new feature is possible, doesn't creat instability, doesn't colide with an existing feature etc. - generally a technical accept, based on the documentation provided. The creator should fix / change these issues untill he gets the technical acceptation.
- if the new feature candidate passes the poll, it is integrated in the main code and others new feature candidates queue for a while, untill the bugs are fixed or a relative stability is prooved.

5. The development keeps going endless, fixing current bugs and integrating new candidates; There always should be the possibility to reverse to the state before integration. So two official version are always out there. The one before and the one after, similar to "the last known good";[/color]

In the meantime, all new features or concepts can be tested separatelly or launched as mods, like New Inventory or Multiplayer are now. When their creators consider these are stable enough and ready, they submit the candidature and people vote for their integration into the main branch. During integration and soon after, the people can still get two versions, one of them not containing the new feature. This is a bit theoretical, but it may work. More or less this is how is done now, but it sets some standards like one single new feature at a time to the main branch or the poll system.
Re: Code Snippets[message #172762] Thu, 24 January 2008 10:43 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

2. Content (images, sounds etc) can be with a different license (preferably GPL) there are already other projects doing so for other games... Maybe we could take some of their textures/sounds Wink

4. Sounds like linux kernel development except the poll part Very Happy I agree!


Can we also add a drop feature poll? So as to keep things less buggy...
Re: Code Snippets[message #172843] Thu, 24 January 2008 16:14 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

------------------
RANGE MULTIPLIER
------------------

GameSettings.h

under
	UINT32 ubMeleeDamageMultiplier;

add
//Ar1z: Range multiplier/Divider
	INT16 iGunRangeMultiplier;


GameSettings.cpp
under
 gGameExternalOptions.ubGunDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_DAMAGE_MULTIPLIER",0);

add
	//Ar1z: Range multiplier/Divider
 gGameExternalOptions.iGunRangeMultiplier = iniReader.ReadInteger("JA2 Gameplay settings","GUN_RANGE_MULTIPLIER",100);
if (gGameExternalOptions.iGunRangeMultiplier == 0)
{
	gGameExternalOptions.iGunRangeMultiplier = 100;
}


Weapons.cpp
under
pData->curWeapon.usRange = (UINT16) atol(pData->szCharData);

add
Quote:
//Ar1z: Range multiplier/Divider

if (gGameExternalOptions.iGunRangeMultiplier < 0)
{
pData->curWeapon.usRange /= (gGameExternalOptions.iGunRangeMultiplier * -1) / 100;
}
else
{
pData->curWeapon.usRange *= gGameExternalOptions.iGunRangeMultiplier / 100;
}

Wink

Also you need to add the following into JA_OPTIONS.INI after GUN_DAMAGE_MULTIPLIER
; This is later divided by 100) if negative value it will perform division e.g. 200 = range x2, -150 = range /1.5
; ranges 1-99 should not be used. only use if you know what you are doing Wink
GUN_RANGE_MULTIPLIER = 150

[Updated on: Wed, 16 July 2008 18:23] by Moderator

Re: Code Snippets[message #172866] Thu, 24 January 2008 18:10 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
Smile Ok, a new snipet added here should have:

1. General description

- what is it doing and what is it good for;
- advantages and drawbacks;
- where it applys, a summary case study;
- any conflict with something else if this is possible;

2. Files affected;
3. Source code, comments inside;


Otherwise the range multiplayer is prety usseful, I think I will include it too Wink Thank Ar1z.
Re: Code Snippets[message #172898] Thu, 24 January 2008 21:44 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
Persistent Turn Based Option, a personal tweak.

Hehe, i've only had the code in front of me for a couple of days, so bear with me.. i really wanted to try something. So i pull this out of a hat of what i really wanted in the past, and it was easy enough for me to pull off.

This is a real rig-up, i don't like it 100%, it messes up initial random chance of whose turn it is when entering a new sector.. its bad because the player's turn is always first. I'd really like to change that, but i'm not sure how to randomize the event just yet. However, interrupts should stem this misfire of code somewhat.

Another issue, GAH!.. options screen is FULL ! .. serious TODO: make those "old-people" sized volume sliders a bit more reasonably sized and try to get a 3rd options column. And/or get some page number display and page first/last(just in case), next/prev buttons in there.

What its doing now (when ON):
Enters turn base mode when enemy present when:
I) Player first enters occupied sector.
II) Enemy arrives in sector when in tactical map view.
III) Enemy arrives via add 'b'addie cheat.

Exits turn based mode when:
I) Player turns off the option and allows a turn to end and original method of mode toggle takes over.
II) Sector is emptied of baddies.

Unknown behavior (as of yet)
Bloodcat ambushes should behave as originally, yet to see it in action
Combat mode start/stop due to NPC conversation/item interactions..
End combat due to killing the queen should be as original

My reasoning... I HATE HATE HATE, mad mouse skillz [/leet] vs. computer's move 20 baddies all at same time with individualized motion. When its obvious we are in a fight, and yet my mercs are all standing around waiting for indvidual orders.

Quote:

//***************************************************************************
Overhead.cpp
void ExitCombatMode( )
...
EndTopMessage( );

+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Exit combat mode");//arynn adds forced turn mode

// OK, we have exited combat mode.....
...

BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen )
...
// If we have reach a point where a cons. number of turns gone by....
- if ( gTacticalStatus.bConsNumTurnsNotSeen > 1 )
+ if ( gTacticalStatus.bConsNumTurnsNotSeen > 1 && !gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ])//arynn adds forced turn mode
{
//***************************************************************************
Soldier Add.cpp
void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection, BOOLEAN fUseAnimation, UINT16 usAnimState, UINT16 usAnimCode )
...
if ( pSoldier->ubBodyType != BLOODCAT )
{
SetEnemyPresence( );
+ //arynn adds forced turn mode START *note not for bloodcats..
+ if ( gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ])
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Forced Turn Mode Active, Entering Combat" );
+ EnterCombatMode( OUR_TEAM );
+ }//arynn adds forced turn mode END
}
//***************************************************************************
Turn Based Input.cpp
void TeleportSelectedSoldier();
+void ToggleTurnMode();//arynn adds forced turn mode
void ToggleTreeTops();
...
void GetKeyboardInput( UINT32 *puiNewEvent )
...
else
ToggleTreeTops();
break;

+ case 'T'://arynn adds forced turn mode
+ if ( fAlt && fCtrl && fShift)
+ {
+ ToggleTurnMode();
+ }

case '=':
...
void TeleportSelectedSoldier()
...
+void ToggleTurnMode()//arynn adds forced turn mode
+{
+ if ( !gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Forced Turn Mode" );
+ gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] = TRUE;
+ EnterCombatMode( OUR_TEAM );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Normal turn mode");
+ gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] = FALSE;
+ }
+}

void ToggleTreeTops()

//***************************************************************************
_EnglishText.cpp

L"Low CPU usage",
+ L"Forced Turn Mode", //arynn adds forced turn mode

};
...
L"When ON, game will run with much lower CPU usage.",
+ L"When ON and enemy present, Turn Base mode persists untill sector is free. \"cntrl+alt+shft+t\"",//arynn adds forced turn mode

};

//***************************************************************************
GameSettings.cpp
gGameSettings.fOptions[ TOPTION_LOW_CPU_USAGE ] = FALSE;
+ gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] = FALSE; //arynn adds forced turn mode

gGameSettings.ubSizeOfDisplayCover = 4;
...
TOPTION_LOW_CPU_USAGE,
+ TOPTION_TOGGLE_TURN_MODE, //arynn adds forced turn mode

NUM_GAME_OPTIONS, //Toggle up this will be able to be Toggled by the player





oh, PS.. i think i got it all.. added the remark whenever i made a change to have a hook to search
for when i was debugging, so it should all be here.. but iwas kind switching around a bit so something might have gone forgotten.

and PSS... English only.. i didnt work out the other languages yet if ever.

[Updated on: Wed, 16 July 2008 18:22] by Moderator

Re: Code Snippets[message #172997] Fri, 25 January 2008 09:24 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
night vision / sun vision toggle fix

old way = mercA has sun, mercB has night vision, shift-n, mercA now has night and mercB has sun
new way = mercA has sun, mercB has night, shift-n, now mercA has night and mercB has night, game reports night vision mode,shift-n again, both have sun goggle report sun vision mode

Annoying feature when usually im trying to get all into using sun goggles or night vision.
That one odd overlooked guy who was recently attach to a squad that just came back from a
night-op, nice and all.. except his last combat was a daytime defense and he still had sun glasses.
So when SHTF at day time he was runin around combat wearing night vision because at top of combat
shift-n was sent in and everyone EVERYONE toggled regardless of what to to toggle to.

What happens.. first merc is found that merc sets the mode of what is being toggled to, following
squad mates toggle items only if they are following same toggle mode. otherwise they ignore.

future modification, ability to remove type from face even if one doesn't alternate to the new mode.

examples in old, new and future fashion :
Quote:

merc A B C D E F
wearing nvg sg sg nvg nvg sg
helmet attach sg nvg none none none none
inventory none none nvg sg none none

post shift-n, now wearing :

old sg nvg nvg sg nvg sg
new sg sg sg sg nvg sg
future? sg sg sg sg none sg


Turn Based Input.cpp
Quote:

void GetKeyboardInput( UINT32 *puiNewEvent )
...



case 'N':
{
/* CHRISL - Adjusted this option to allow the game to search through Helmet attachments
as well as inventory positions. */
//arynn toggle night vision/sun vision fix
//arynn comments toggle night vision/sun vision to best able interpertation (educational purpose mostly)
//old way = mercA has sun, mercB has nightvision, shift-n, mercA now has night and mercB has sun
//new way = mercA has sun, mercB has night, shift-n, now mercA has night and mercB has night, game reports night vision mode,shift-n again, both have sun goggle report sun vision mode
SOLDIERTYPE *pTeamSoldier; // temp pointer for merc
OBJECTTYPE * pObj; // helmet object pointer, used in locating attached sun/night vision item
INT8 bLoop, bSlot1, bSlot2, bSlot3, temp, tempStatus=0; // index to merc (counter), index to headslot, index to obj in general inv, index to obj attched to helmet, temp postion that has target obj, temp holer for target obj status
INT16 lastBonus=0, tempItem=0; // lastbonus to compare for the better target boject, tempitem for swapping target obj with face object
+ INT8 first_squadmate_found=0, toggle_vision_mode=0; //arynn adds flags to determine first toggle type for others to follow/ignore swap command
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
{
//loop thru entire team
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
{
//entry here pTeamSoldier is_a merc and in selected squad and is not a robot
+ if(!first_squadmate_found) { first_squadmate_found++; };//arynn adds found first squad mate upgrade to stage 1

for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
{
//loop thru 2 head slots
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 )
{
+ if(first_squadmate_found==1) { toggle_vision_mode=1;}; //arynn adds found mode
+ if(first_squadmate_found==1) { first_squadmate_found++;} //arynn adds test if first squad mate and upgrade stage, then continue past else if check for break
+ else if (toggle_vision_mode != 1) {break;} //arynn adds its not the first squad mate, if its not same mode then break and dont swap

//entry here is: item found with sun goggle vision bonus (hopefully only one night vision object per both head slots?)
lastBonus=0; //re-initialize bonus for comparing best bonus object
bSlot2 = ITEM_NOT_FOUND; //re-initialize target object locator for general inventory variant
bSlot3 = ITEM_NOT_FOUND; //re-initialize target object locator for helmet attachment variant
temp = 0; //re-initalize general inventory position
pObj = &(pTeamSoldier->inv[HELMETPOS]);//set object pointer to address of helmet for locating potentially attached target object
while (temp != ITEM_NOT_FOUND)
{
temp = FindNightGoggles( pTeamSoldier, lastBonus );//call seeks thru inventory for best nightvision bonus oject that fits in headpos slots
if ( temp > ITEM_NOT_FOUND )
{
//entry here item has been found in general inventory that is_a night vision item for headpostion
lastBonus = Item[pTeamSoldier->inv[temp].usItem].nightvisionrangebonus; //sets bonus of found object for compare to helmet attached object
bSlot2 = temp; //set index to slot of best nightvision obj for face found
}
//else lastbonus and bslot remain as initialized, nightvision goggle not found in general inventory
}
for (int i = 0; i < MAX_ATTACHMENTS; i++)
{
//loop thru attachment to helmet object
if ( Item[ pObj->usAttachItem[i] ].nightvisionrangebonus > lastBonus && Item[ pObj->usAttachItem[i] ].usItemClass == IC_FACE )
{
//entry here is_a better nightvision object, and it fits in headposition
bSlot2 = ITEM_NOT_FOUND; //a better night vision object is attached, forget general inventory variant
bSlot3 = i; //attachment slot index of target object
lastBonus = Item[ pObj->usAttachItem[i] ].nightvisionrangebonus;//best night vision bonus reset for comparision ? multiple attached night vision objects ?
}
}
if ( bSlot3 != ITEM_NOT_FOUND )
{
//entry here is: item found as an attachment to the helmet object special case for swapping
// Duplicate item in helmet attachment slot
tempItem = pObj->usAttachItem[bSlot3]; //arynn uncertainty : a simple INT16 handles an object's entire dataset ?
//arynn uncertainty : in my experience, such a swap involves an algorithm such as:
//arynn uncertainty : OBJ temp, 1, 2; temp=1; 1=2; 2=temp;
tempStatus = pObj->bAttachStatus[bSlot3]; //arynn uncertainty : status ? as in condition ? or flag as an attached object ?
// Replace helmet attachment with face slot
pObj->usAttachItem[bSlot3] = pTeamSoldier->inv[bSlot1].usItem;
pObj->bAttachStatus[bSlot3] = pTeamSoldier->inv[bSlot1].ItemData.Generic.bStatus[0];
// Replace face slot with helmet attachment from temp
pTeamSoldier->inv[bSlot1].usItem = tempItem;
pTeamSoldier->inv[bSlot1].ItemData.Generic.bStatus[0] = tempStatus;
}
else if ( bSlot2 != ITEM_NOT_FOUND )
{
//entry here is: item found in general inventory, special function exists to handle swap
SwapObjs( pTeamSoldier, bSlot1, bSlot2, TRUE );//call swaps objects for soldier within basic inventory
}
break;//break here because operation has been completed, item found and swapped or not
}//end if wearing sun vision object - find night vision and swap
//following block is same as above except inverted towards currently wear nightvision and locating-swapping sun vision
else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0)
{

+ if(first_squadmate_found==1) { toggle_vision_mode=2;}; //arynn adds found mode
+ if(first_squadmate_found==1) { first_squadmate_found++;} //arynn adds test if first squad mate and upgrade stage, then continue past else if check for break
+ else if (toggle_vision_mode != 2) {break;} //arynn adds its not the first squad mate, if its not same mode then break and dont swap

lastBonus=0;
bSlot2 = ITEM_NOT_FOUND;
bSlot3 = ITEM_NOT_FOUND;
temp = 0;
pObj = &(pTeamSoldier->inv[HELMETPOS]);
while (temp != ITEM_NOT_FOUND)
{
temp = FindSunGoggles( pTeamSoldier, lastBonus );
if ( temp > ITEM_NOT_FOUND )
{
lastBonus = Item[pTeamSoldier->inv[temp].usItem].brightlightvisionrangebonus;
bSlot2 = temp;
}
}
for (int i = 0; i < MAX_ATTACHMENTS; i++)
{
if ( Item[ pObj->usAttachItem[i] ].brightlightvisionrangebonus > lastBonus && Item[ pObj->usAttachItem[i] ].usItemClass == IC_FACE )
{
bSlot2 = ITEM_NOT_FOUND;
bSlot3 = i;
lastBonus = Item[ pObj->usAttachItem[i] ].brightlightvisionrangebonus;
}
}
if ( bSlot3 != ITEM_NOT_FOUND )
{
// Duplicate item in helmet attachment slot
tempItem = pObj->usAttachItem[bSlot3];
tempStatus = pObj->bAttachStatus[bSlot3];
// Replace helmet attachment with face slot
pObj->usAttachItem[bSlot3] = pTeamSoldier->inv[bSlot1].usItem;
pObj->bAttachStatus[bSlot3] = pTeamSoldier->inv[bSlot1].ItemData.Generic.bStatus[0];
// Replace face slot with helmet attachment from temp
pTeamSoldier->inv[bSlot1].usItem = tempItem;
pTeamSoldier->inv[bSlot1].ItemData.Generic.bStatus[0] = tempStatus;
}
else if ( bSlot2 != ITEM_NOT_FOUND )
{
SwapObjs( pTeamSoldier, bSlot1, bSlot2, TRUE );
}
break;
}
}


fCharacterInfoPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
DeleteSoldierLight( pTeamSoldier );
PositionSoldierLight( pTeamSoldier );
}
}
+ if(toggle_vision_mode == 0) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Nothing happened.");}
+ if(toggle_vision_mode == 1) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Squad set for night vision.");}
+ if(toggle_vision_mode == 2) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Squad set for sun goggles.");}

/* CHRISL - Adjusted this option to allow the game to search through Helmet attachments
as well as inventory positions. */
}
break;


ps i hope i did that right.. i found a bug in the middle of posting this, rofl.. sigh..

[Updated on: Sat, 24 May 2008 16:25] by Moderator

Re: Code Snippets[message #173003] Fri, 25 January 2008 09:58 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
I think this thread is gonna have much more succes than anticipated. Smile Guys, we need to find a way to wrap the long lines in code, they mess browsers (Internet Explorer only) - it scrolls horisontal a lot.

EDIT: just wrap them with enter. Anyone using the code will figure ouy what happened.
Re: Code Snippets[message #173007] Fri, 25 January 2008 10:26 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

I've updated the above code... Wink I'll also send a link to a web page with all my changes for easier access (both me & you) Wink

http://ar1z.dnsalias.net/jamod.html
easier reading (RTF FORMAT for WORD)

[Updated on: Fri, 25 January 2008 11:54] by Moderator

Re: Code Snippets[message #173025] Fri, 25 January 2008 12:10 Go to previous messageGo to next message
Tron

 
Messages:227
Registered:August 2007
Location: Germany
Ar1z
Quote:
//Ar1z: Range multiplier/Divider

if (gGameExternalOptions.iGunRangeMultiplier < 0)
{
pData->curWeapon.usRange /= (gGameExternalOptions.iGunRangeMultiplier * -1) / 100;
}
else
{
pData->curWeapon.usRange *= gGameExternalOptions.iGunRangeMultiplier / 100;
}

Wink

Also you need to add the following into JA_OPTIONS.INI after GUN_DAMAGE_MULTIPLIER
; This is later divided by 100) if negative value it will perform division e.g. 200 = range x2, -150 = range /1.5
; ranges 1-99 should not be used. only use if you know what you are doing Wink
GUN_RANGE_MULTIPLIER = 150


That does not work as you expect. You're doing integer math. The result of an integer operation is always an integer. So
  • (-150 * -1) / 100 is 1 (and not two thirds of the range as you suggested)
  • 199 / 100 is 1
  • everything between -99 and -1 leads to a division by zero ((-50 * -1) / 100 is 0)
  • everything between 1 and 99 results in a range of 0 (50 / 100 is 0).

First rule of integer math: multiply first, divide later.

Quote:
UINT16& range = pData->curWeapon.usRange;
range = range * gGameExternalOptions.iGunRangeMultiplier / 100;

This also saves the mumbo jumbo with the negative values: now 50 simply is half the range etc.

BTW: drop this nonsensical hungarian notation stuff.

[Updated on: Sat, 24 May 2008 16:28] by Moderator

Re: Code Snippets[message #173030] Fri, 25 January 2008 12:28 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

Everyday you learn something new Wink

OK! what should I do for 150/100=1,5 instead of 1? typecasting with float?

Quote:
BTW: drop this nonsensical hungarian notation stuff.

what do you mean by that?
Re: Code Snippets[message #173031] Fri, 25 January 2008 12:41 Go to previous messageGo to next message
Tron

 
Messages:227
Registered:August 2007
Location: Germany
Ar1z
Everyday you learn something new Wink

Please learn the basics of the tools you're using.

Quote:
OK! what should I do for 150/100=1,5 instead of 1? typecasting with float?

I wrote already, what the correct solution is. Please reread above.

Quote:
Quote:
BTW: drop this nonsensical hungarian notation stuff.

what do you mean by that?

The redundant prefixes to variables: "iWhatever". It's just line noise and gets inconsistent (worst example is the messy JA2 code itself: often these prefixes are plain wrong).

[Updated on: Sat, 24 May 2008 14:55] by Moderator

Re: Code Snippets[message #173034] Fri, 25 January 2008 13:03 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

@Tron
Since this doesn't concern everyone... Except maybe other C++ newbies Wink I'll send you a pm!
Re: Code Snippets[message #173193] Sat, 26 January 2008 18:06 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

inventory choosing.cpp

ARMY_GUN_CHOICE_TYPE gRegularArmyGunChoices...

The above table should be in comment tags since I didn't find a reference anywhere ( except same file, commented out)...
Re: Code Snippets[message #173245] Sun, 27 January 2008 01:43 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
I dunno what im doing wrong, but i cant compile unless you drop this in.

im using msvc 2003 btw, and just update SVN folder, did a winmerge compare and almost re-broke it Wink
Quote:

All AI.h

#include "Queen Command.h"
+#include "cheats.h"
#include "Lighting.h"


Tactical All.h

#include "XML.h"
+#include "Lua Interpreter.h"

Lua.cpp
// Set up the game info
- LuaTacticalSetup( L);
- LuaStrategicSetup( L);
- LuaEnvironmentSetup( L);
+// LuaTacticalSetup( L);
+// LuaStrategicSetup( L);
+// LuaEnvironmentSetup( L);



First one affects the display of "Soldier %d decides action %d with data %d" during cheat mode.
Which i pretty much remarked anyway to shave off noise for the "function tracers" i put in.

Second one.. InitializeLua(); and ShutdownLua( ); calls inside Overhead.cpp

Third in lua.cpp three functions have no definitions, and can't link the build.


[Updated on: Sat, 24 May 2008 16:28] by Moderator

Re: Code Snippets[message #173255] Sun, 27 January 2008 04:05 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
Previously,
V1 only dealt with lowering ready weapons inbetween turnbased modes..
V2 i thought i had a nice one step fix, but it broke some anim resets in a situation i hadn't tested.
V3 its a little bigger, and its the original V2 version i had on file. Instead of avoiding the reset in the reset
function, it now avoids the reset in the problematic reset function's callers. Plus i had another problem which
seems to have cleared up in a seperate fix (see below)

This is a dirty fix. The heart of the problem really lies in the handling of "fNoAPToFinishMove" else where in the code.
But that maybe an overly complicated way to fix this problem. I'm not 100% sure what this flag is for, considering its not being
used just for "No AP To Finish Move", but also in some cases there IS plenty AP, or even still when the merc isn't even doing a move.
A quick search shows that the flag makes an appearance 33 times in the code.
The flag has a function that sets it "AdjustNoAPToFinishMove(bool)", which appears 26 times in the code.
There is even a secondary "reason why flag", "ubReasonCantFinishMove" that is hardly even tested or set, appears 6 times (2 declarations, 3 that set it, 1 test).
And to top it all, an enum of defines for reason " enum { REASON_STOPPED_NO_APS, REASON_STOPPED_SIGHT, }; "

The function i am aware of is that for various reasons, "fNoAPToFinishMove" is the indicator that the animation is in a freeze
state (aka "fast movement") Its used in sodlier runs out of AP when in motion (so you get the frozen mid-step look) Also
its used in new sightings of enemy/loot. Also its used in the case of an interrupt (where is reason why "REASON_STOPPED_INTERRUPT" ??)

The problem lies in the fact it is being set outside the "fast movement" facet, mostly in new sightings during off turn, or new sightings
from bystanding mercs (merc kills a guy, other merc sees the loot). Since this a turnbased effect, the "freeze" state is corrected when one
issues look, or when real-time kicks in, unfortunately it resets other animations due to "fNoAPToFinishMove" misuse, i corrected the "ready weapon"
state primarily due to the AP cost imposed, it is a point of frustration to expend the AP time and time again when it should not be happening.

Quote:

Overhead.cpp

void ExitCombatMode( )
{
...
if ( pSoldier->flags.fNoAPToFinishMove && pSoldier->stats.bLife >= OKLIFE )
{
pSoldier->AdjustNoAPToFinishMove( FALSE );
+
+ //arynn fix lower ready weapons
+ //previously "ready weapon" state was being dropped in a couple of cases
+ //the fix involves bypassing the reset animation state for the various "ready weapon" types
+ //since this is a reset animation function, we should be VERY specific about when and what we dont reset
+
+ UINT16 test;
+ test = pSoldier->usAnimState;
+ if (!( test == AIM_RIFLE_STAND || test == AIM_RIFLE_CROUCH ||
+ test == AIM_RIFLE_PRONE || test == AIM_DUAL_STAND ||
+ test == AIM_DUAL_CROUCH || test == AIM_DUAL_PRONE
+ ))
+ {
pSoldier->SoldierGotoStationaryStance( );
+ }//arynn fix lower ready weapon end_if


;**************************************************

HanldeUI.cpp

BOOLEAN MakeSoldierTurn( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos )
{
...

// ATE: make stationary if...
if ( pSoldier->flags.fNoAPToFinishMove )
{
+ //arynn fix lower ready weapons
+ //previously "ready weapon" state was being dropped in a couple of cases
+ //the fix involves bypassing the reset animation state for the various "ready weapon" types
+ //since this is a reset animation function, we should be VERY specific about when and what we dont reset
+ UINT16 test;
+ test = pSoldier->usAnimState;
+ if (!( test == AIM_RIFLE_STAND || test == AIM_RIFLE_CROUCH ||
+ test == AIM_RIFLE_PRONE || test == AIM_DUAL_STAND ||
+ test == AIM_DUAL_CROUCH || test == AIM_DUAL_PRONE
+ ))
+ {
pSoldier->SoldierGotoStationaryStance( );
+ }//arynn fix lower ready weapon end_if
}

--
addendum: for NIV src users, i found a problem, hopefully this is the extent of it. But apparently when upgrading code
to a more "cpp" vs "c", some how the wrong function call was put in place of another function call.

Quote:

Handle UI.cpp

UINT32 UIHandleCMoveMerc( UI_EVENT *pUIEvent )
{
- pSoldier->InternalSoldierReadyWeapon( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );
+ pSoldier->InternalDoMercBattleSound( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );
...

void EndMultiSoldierSelection( BOOLEAN fAcknowledge )
{
- pSoldier->InternalSoldierReadyWeapon( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );
+ pSoldier->InternalDoMercBattleSound( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );
...
BOOLEAN HandleMultiSelectionMove( INT16 sDestGridNo )
{
- pSoldier->InternalSoldierReadyWeapon( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );
+ pSoldier->InternalDoMercBattleSound( BATTLE_SOUND_OK1, BATTLE_SND_LOWER_VOLUME );

[Updated on: Sat, 24 May 2008 16:29] by Moderator

Re: Code Snippets[message #173289] Sun, 27 January 2008 16:52 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
I also agree about dropping hungarian notation, its considered obsolete even by Microsoft that promoted it. Their lates guidlines promote simple naming based on Camel/Pascal notation.

http://msdn2.microsoft.com/en-us/library/czefa0ke(vs.71).aspx
http://en.wikipedia.org/wiki/Hungarian_notation (see disavantages)
Re: Code Snippets[message #174632] Mon, 04 February 2008 19:06 Go to previous messageGo to next message
RiHatz
Messages:4
Registered:January 2008
Location: GER
hello,
here is some code for damage/impact beeing dependant on range of weapon and travelled distance of bullet. EDIT: and now also dependent on the calibre used!!

im testing this with the svn revision 1780 and the new inventory.
the only affected file is the 'LOS.cpp'

this is the first part: EDIT: new code

[quote]
INT32 CheckWhichCalibre ( UINT32 CFIL )
{
UINT32 Calibre;

//CFIL - Calibre From Item List
//All of the Calibres are beeing put into 8 groups
//this might not be the most convenient method of doing so..
if ( CFIL >= 71 && CFIL <= 79 || CFIL == 105 || CFIL == 106 || CFIL >= 118 && CFIL <= 120 || CFIL >= 351 && CFIL <= 397 || CFIL == 486 || CFIL == 487 || CFIL >= 504 && CFIL <= 511 || CFIL == 539 || CFIL >= 542 && CFIL <= 544 )
{
Calibre = 1;
}
else if ( CFIL >= 80 && CFIL <= 91 || CFIL >= 107 && CFIL <= 110 || CFIL == 129 || CFIL == 130 || CFIL >= 398 && CFIL <= 422 || CFIL >= 489 && CFIL <= 502 || CFIL >= 512 && CFIL <= 517 || CFIL >= 523 && CFIL <= 536 || CFIL == 538 || CFIL == 545 || CFIL == 546 || CFIL >= 559 && CFIL <= 569 || CFIL >= 576 && CFIL <= 581 || CFIL >= 586 && CFIL <= 591 || CFIL >= 1047 && CFIL <= 1052 )
{
Calibre = 2;
}
else if ( CFIL == 104 || CFIL == 485 || CFIL == 488 || CFIL == 547 || CFIL == 548 || CFIL >= 570 && CFIL <= 575 || CFIL == 582 || CFIL == 930 || CFIL == 931 )
{
Calibre = 3;
}
else if ( CFIL == 92 || CFIL == 93 || CFIL >= 96 && CFIL <= 99 || CFIL == 121 || CFIL == 122 || CFIL == 483 || CFIL == 484 || CFIL == 540 || CFIL == 541 || CFIL >= 549 && CFIL <= 552 || CFIL == 554 || CFIL >= 583 && CFIL <= 585 || CFIL == 932 || CFIL == 933 )
{
Calibre = 4;
}
else if ( CFIL == 94 || CFIL == 95 || CFIL == 123 || CFIL == 124 || CFIL >= 423 && CFIL <= 427 || CFIL >= 429 && CFIL <= 433 || CFIL >= 435 && CFIL <= 441 || CFIL >= 443 && CFIL <= 447 || CFIL >= 480 && CFIL <= 482 || CFIL >= 1056 && CFIL <= 1062 )
{
Calibre = 5;
}
else if ( CFIL >= 100 && CFIL <= 103 || CFIL >= 125 && CFIL <= 127 || CFIL >= 449 && CFIL <= 453 || CFIL >= 455 && CFIL <= 478 || CFIL >= 518 && CFIL <= 521 || CFIL == 553 )
{
Calibre = 6;
}
else if ( CFIL == 117 || CFIL >= 555 && CFIL <= 558 )
{
Calibre = 7;
}
else if ( CFIL == 116 || CFIL == 454 || CFIL == 479 || CFIL == 503 || CFIL == 522 )
{
Calibre = 8;
}
else
{
//for debugging only
Calibre = 0;
}
return ( Calibre );
}


INT32 BulletImpactReducedByRange( UINT32 Calibre, INT32 iImpact, INT32 DistanceTravelled, INT32 Range)
{
double percentage;
double CalModifier;
float NumberForSQRT = DistanceTravelled;



//no Impact reduction for very small Distances (ca.3 Tiles)
if ( DistanceTravelled >= 30 )
{
//Different Impact reduction for the different Calibres
switch ( Calibre )
{
case 0 : DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("No Impact Reduction for Distance, because Calibre is not specified")); break;
case 1 : ( CalModifier = 0.38 ); break;
case 2 : ( CalModifier = 0.30 ); break;
case 3 : ( CalModifier = 0.26 ); break;
case 4 : ( CalModifier = 0.025 ); break;
case 5 : ( CalModifier = 0.02 ); break;
case 6 : ( CalModifier = 0.01 ); break;
case 7 : ( CalModifier = 0.006 ); break;
case 8 : ( CalModifier = 0.001 );
}

if ( Calibre == 0 )
{
CalModifier = 0;
}

percentage = ( ((CalModifier * DistanceTravelled * DistanceTravelled / 100) + ( sqrt(NumberForSQRT)/2)) * (1-(Range/750)) );

if ( percentage >= 95 )
{
percentage = 95;
}

if (percentage <= 0 )
{
percentage = 0;
}

iImpact = iImpact * (1-(percentage/100));

}
return ( iImpact );
}
[/code]

furthermore this function needs to be called when the hit of the bullet is handled.
this is done in the function:

BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntended )

its quite a large function. in there you will find two (one for intendet hit and one for luckily hitting someone else) lines which look as follows:

iImpact = pBullet->iImpact;

these lines have to be replaced by this:

[quote]
iImpact = BulletImpactReducedByRange ( CheckWhichCalibre ( pBullet->pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.usGunAmmoItem), pBullet->iImpact, pBullet->iLoop, pBullet->iRange );
[/code]

well, i could only do a debug build. im using visual studio 2008 professionel and i get 2 errors when trying to build a release. maybe someone can help. here is the error:

SignTool Error: IStore2::Load returned error: 0x80070003
SignTool Error: An error occurred while attempting to load the signing
certificate from: c:\documents and settings\paul\ja2.spc
Project : error PRJ0019: A tool returned an error code from "Signing the code"
EDIT: problem solved!

after first few test fights the damage reduction "feels" quite fun and playable. of course its most easy to finetune this.

and if someone knows anything about the weird AI behavior please let me know.


greetings,
ri-hatz

[Updated on: Wed, 16 July 2008 18:22] by Moderator

Re: Code Snippets[message #174691] Tue, 05 February 2008 09:13 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
RiHatz
well, i could only do a debug build. im using visual studio 2008 professionel and i get 2 errors when trying to build a release. maybe someone can help. here is the error:

SignTool Error: IStore2::Load returned error: 0x80070003
SignTool Error: An error occurred while attempting to load the signing
certificate from: c:\documents and settings\paul\ja2.spc
Project : error PRJ0019: A tool returned an error code from "Signing the code"



Hehe happy me.. i got 2005 a few days ago and finaly got it up (thanks to bud who owes me a favor, and happens to be going 2008). I downed NIV src and did a couple of builds (which dint compile in 2003). I too got the signing error when building release, tho it still completed the build. I took it upon myself to clean this error up, i'm not 100% on what the change does but at least i cleared the errors from my build output.

Since you are in 2008, it may be slightly different, best guess is to follow my pattern and see if there any changes, and if so hope they are subtle.

1) Fire up help, search for "Tool Build Order Dialog Box " or more or less combo of those keywords.

2) In 2005 it says :
"The Build Order dialog box allows you to specify the order in which Visual C++ build tools are run.

To access this dialog box, right-click your project in Solution Explorer, and then select the Build Order context menu item."

3) In 2005, right-click the ja2 sub-project, in the pop-up menu seek "Tool Build Order.."
You get a dialog with a main body containing a list of tools with check boxes.

4) De-check "Post-Build Event Tool" and "OK" the dialog.

5) Re-compile release configuration and see what happens. good luck

That should do it, works for me. Again im not 100%, i might have broke something, but it compiles with 0 errors, and thats the point.


Oops, forgot to ask, the snippet above, does that clear out the "sniper-variant .38 specials" the AI
tends to run around with ?







[Updated on: Tue, 05 February 2008 09:26] by Moderator

Re: Code Snippets[message #174704] Tue, 05 February 2008 11:13 Go to previous messageGo to next message
RiHatz
Messages:4
Registered:January 2008
Location: GER
thanks arynn it helped. i can now build the realease without errors.
about the "sniper-variant .38 specials" i have no idea.

i should get this exe hosted somewhere now, so people can test it.
maybe someone wants to help with that?
Re: Code Snippets[message #174944] Wed, 06 February 2008 19:18 Go to previous messageGo to next message
RiHatz
Messages:4
Registered:January 2008
Location: GER
a question to the moderators:

the code i posted above changed completely, because i added calibre dependency for the damage drop-off.

should i post the new code in a new post or edit the old post???

greetings..
Re: Code Snippets[message #174947] Wed, 06 February 2008 20:10 Go to previous messageGo to next message
Marlboro Man

 
Messages:1259
Registered:October 2005
Location: USA
Edit the old post and make note of it there.


Re: Code Snippets[message #175242] Sat, 09 February 2008 23:34 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
Just mentioning a change to my previous post (also bumping for activity on this thread)
See drop ready weapon fix

k, i got V3 in. It should be working, I had an extra problem to boot, concerning NIV code. If you are using NIV code you should take a look.

[Updated on: Mon, 11 February 2008 21:48] by Moderator

Re: Code Snippets[message #175491] Tue, 12 February 2008 22:55 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
Swag Goggle fix.

I decided to add a second post of this function, primarily because the first one is a Non NIV variant

This is NIV based. I haven't gone thru trunk yet to compare and check if its possible, but i wanted to drop in what i've got so far.

ALRIGHTY THEN....

This function was a point of frustration for me. Despite it being a handy macro to reduce manual goggle swapping, i found myself
having to manually swap goggles fairly often. My play style involves often breaking up teams to do various tasks, also includes alot
of reorganization of squad make up. Unfortunately team goggle states do not easily flow with this pattern.

I now present you with the new Swap_Goggles () function that behaves like shift-z does for stealth. Instead of a flat toggle
for each squad mate. It determines a mode to swap to, then everyone swaps or does not swap according to their personal situation.
This means that withing 2 presses of 'shift-n' each merc will be in mode for night or day operations.

This function also is beefier. It now handles mercs that do not have both types of goggles, also it handles mercs who aren't wearing
goggles but have the space for them at the time. The only mercs that get left out are the mercs who have no face slots (ie wearing gas
and ears at the time) or those mercs who have no goggles what so ever. Also in some cases when team is swapping, an individual may
fail to swap due to inventory capacity.

This chart shows typical arrangements and results after operation and compares to the current way. Note that the merc's all
end up being in the best possible state considering that the wrong goggles carry penalties (ie NVG in daytime / SVG at night)
Quote:

Situations :
given: | A B C D E F G H I J K L
wearing | N S S N N S - - - - - Gas/Ear
in helmet | S N - - - - S N - - - N
inventory | - - N S - - - - S N - S
after shift-n
wearing:
old way | S N N S N S - - - - - Gas/Ear
new way | S S S S - S S - S - - Gas/Ear
shift-n again:
old way | N S S S N S - - - - - Gas/Ear
new way | N N N N N - - N - N - Gas/Ear


There is a few improvements/issues yet to be handled:
1) worn items move to helmet instead of general inventory when applicable
2) when swapping with SVG in inventory NVG bypass slot size restrictions, there needs to be a way to shift them into a legal slot.
3) I'd like to add single merc function, however i'm not seeing it as a priority
4) I'd also like to see the function handle AP costs for swapping in combat, thats a little beyond my ability atm.

This snippet is for NIV source. I completely reorganized it and add a bit of new code, so its best to completely over write
the current function. Or simply rename it to Swap_Goggles2(), and adjust the caller in HandeUI.cpp.

Also i left behind plenty of comments and commented message tracers for help those follow whats happening. It might look
ugly, but im not one that likes to read pure code. PS got about 290 lines here, hope it fits Wink


Turn Based Input.cpp
Quote:

void SwapGoggles()
{
// CHRISL - Adjusted this option to allow the game to search through Helmet attachments as well as inventory positions.

//Arynn toggle night vision/sun vision improvement
//idealology : this is the ("i need to be wearing this" || "i need to stop stop wearing this" (NVG/SVG)) squad-level macro (vs. SIRT's un-friendly manual by-hand method)
//old way = mercA has sun, mercB has nightvision, shift-n, mercA now has night and mercB has sun
// (still forces manual correction, and it happens often enough to warrent this improvement (or even question the point of this function)
//new way1= mercA has sun, mercB has night, shift-n, now mercA has night and mercB has night, game reports night vision mode,shift-n again, both have sun goggle report sun vision mode
//new way2= empty face slots are swapped into, also mercs with undesired goggle types swap them out into general inventory

//arynn TODO : include a "swap goggle for individual merc" vs entire squad swap (much like the 'z'|'shft-z' key is for stealth mode)
//arynn TODO : force AP rules during combat

SOLDIERTYPE *pTeamSoldier; // temp pointer for merc
OBJECTTYPE * pObj; // helmet object pointer, used in locating sub-linked attached sun/night vision item
INT8 bLoop; // bLoop : main loop control/index to merc
INT8 bSlot1; // bSlot1= face slot index
INT8 Swap_Goggles_mode=0; // the mode (NVG/SVG) to which the squad is swapping to 0 = unknown/none, 1= swap to NVG, 2= swap to SVG
INT8 Swap_Goggles_facestate=0; // per person state switcher indicating various face swap modes (see comment below)
INT8 item_found_in_helmet=0; // flag to help facilitate swap with empty face slot (limitation with SwapObj(empty slot, attahment slot) ? (i get NADA item in helmet)

for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
{ //loop thru entire team roster

if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
{
//entry here pTeamSoldier is_a merc and in current squad and is not a robot

//first establish Swap_Goggles_mode if not done yet
if(!Swap_Goggles_mode)//master test to jump past redundant testing (no point in rechecking for each merc once Swap_Goggles_mode is set)(just a minor optimization)
{
if(!Swap_Goggles_mode)//check face first
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s, look in face.",pTeamSoldier->name);
for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
{
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 ){Swap_Goggles_mode=1;}//swap to opposite
else if ( Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0 ){Swap_Goggles_mode=2;}//swap to opposite
}
}
if(!Swap_Goggles_mode)//check helmet
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s, look in helm.",pTeamSoldier->name);
pObj = &(pTeamSoldier->inv[HELMETPOS]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].brightlightvisionrangebonus > 0 && Item[ iter->usItem ].usItemClass == IC_FACE )
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"helm found SVG. brightlightvisionrangebonus = %i", Item[ iter->usItem ].brightlightvisionrangebonus);
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"helm found SVG. nightvisionrangebonus = %i", Item[ iter->usItem ].nightvisionrangebonus);
Swap_Goggles_mode=2;//note change in logic, we set swap to what we found (it might be the only find we ever get)
}
else if ( Item[ iter->usItem ].nightvisionrangebonus > 0 && Item[ iter->usItem ].usItemClass == IC_FACE )
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"helm found NVG. brightlightvisionrangebonus = %i", Item[ iter->usItem ].brightlightvisionrangebonus);
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"helm found NVG. nightvisionrangebonus = %i", Item[ iter->usItem ].nightvisionrangebonus);
Swap_Goggles_mode=1;//swap to obj found, we set swap to what we found (it might be the only find we ever get)
}
}
}
if(!Swap_Goggles_mode)//check general inventory
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s, look in inv.",pTeamSoldier->name);
OBJECTTYPE* pGoggles;
if (pGoggles = FindSunGogglesInInv( pTeamSoldier ))
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"inv found SVG.");
Swap_Goggles_mode=2;//swap to obj found, we set swap to what we found (it might be the only find we ever get)
}
else if (pGoggles = FindNightGogglesInInv( pTeamSoldier ))
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"inv found NVG.");
Swap_Goggles_mode=1;//swap to obj found, we set swap to what we found (it might be the only find we ever get)
}
}
if(!Swap_Goggles_mode)//this guy is hopeless, doesnt have anything to swap around
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any goggles.",pTeamSoldier->name);
continue;//this guy is done, reiterate the loop to the next guy
}
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"PING >> if(!Swap_Goggles_mode) master block");

}//end of determine Swap_Goggles_mode

Swap_Goggles_facestate=0; //initialize with potential fail state, which is adjusted, if applicable, by the following loop

//if here we at least have merc, and now a mode. now we look into face slot situation.
//Swap_Goggles_facestate modes :
//0 face slots unavailable for swap, and no items found
//1 already wearing item goto next guy,
//2 found item to swap out
//3 HEAD1POS was the last empty position found
//4 HEAD2POS was the last empty position found

//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Face slots : 1: %i, 2: %i", pTeamSoldier->inv[HEAD1POS].exists(), pTeamSoldier->inv[HEAD2POS].exists());

for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
{
if(Swap_Goggles_mode==1)//1= swap to NVG
{
if ( Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0 )
{Swap_Goggles_facestate = 1;break;}//we are wearing NVG already
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 )
{Swap_Goggles_facestate = 2; break;}//ok got item to swap out
if (! pTeamSoldier->inv[bSlot1].exists())
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"MT SLOT");
Swap_Goggles_facestate = bSlot1;}//at least there is one empty slot

}
if(Swap_Goggles_mode==2)//2= swap to SVG
{
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 )
{Swap_Goggles_facestate = 1;break;}//we are wearing SVG already
if ( Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0 )
{Swap_Goggles_facestate = 2; break;}//ok got item to swap out
if (! pTeamSoldier->inv[bSlot1].exists())
{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"MT SLOT");
Swap_Goggles_facestate = bSlot1;}//at least there is one empty slot
}
}
/*
//a test block ahead of the actual control flow block's "continue;" (allows us to form a string and display it bfore control flow breaks loop)
CHAR16 tempstr[32];
switch (Swap_Goggles_facestate)
{
case 0 : wcscpy(tempstr, L"no free face slots"); break; //continue to nxt guy
case 1 : wcscpy(tempstr, L"already wearing"); break; //continue to nxt guy
case 2 : wcscpy(tempstr, L"item found"); break; //check bslot
case 3 : wcscpy(tempstr, L"MT head1pos"); break; //set bSlot1 to empty position
case 4 : wcscpy(tempstr, L"MT head2pos"); break; //set bSlot1 to empty position
default : wcscpy(tempstr, L"error"); break; //report error and continue
}

ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s, Swap_Goggles_mode = %i, state = %i %s, slot = %i",
pTeamSoldier->name, Swap_Goggles_mode, Swap_Goggles_facestate, tempstr, bSlot1 );
*/
switch (Swap_Goggles_facestate)
{
case 0 :
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any available slots for goggles.",pTeamSoldier->name);
continue; break; // fail state no free face slots to swap into
case 1 : continue; break; // fail state already wearing desired goggles
case 2 : break; // bSlot1 index to found object to swap with
case 3 : bSlot1 = Swap_Goggles_facestate;break; // set bSlot1 to last known empty slot
case 4 : bSlot1 = Swap_Goggles_facestate;break; // set bSlot1 to last known empty slot
default : ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"error inside SwapGoggles() varible Swap_Goggles_state");
continue;
break;
}

// if (Swap_Goggles_state != 2) {continue;} // temp fail safe

//if here we have a merc, mode, and now a face slot.. lets find an object (or place) in inventory to swap with
//FIND ITEM IN INV BLOCK ===================================================================================
item_found_in_helmet=0; //re-initialize flag
if(Swap_Goggles_mode==1)//seek NVG
{
int bestBonus = 0;
OBJECTTYPE* pGoggles = FindNightGogglesInInv( pTeamSoldier );
if (pGoggles)
{
bestBonus = Item[pGoggles->usItem].nightvisionrangebonus;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"NVG found in INV, BONUS = %i",bestBonus);
}
//search for better goggles on the helmet
pObj = &(pTeamSoldier->inv[HELMETPOS]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus
&& Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
item_found_in_helmet = 1;//set item_found_in_helmet flag
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"NVG found in helm, BONUS = %i",bestBonus);
}
}
// ok we have our inventory data time to do something
if ( pGoggles )
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SwapObjs to NVG");
if(Swap_Goggles_facestate == 2)
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE ); //object to object swap
//arynn TODO : fix the case where goggles are being placed in illegal inv slots (size problem)
}
else //empty faceslots
{
//ok cant SwapObjs with a helm attachment to an empty face slot (or you get the NADA item in the helm)
if(!item_found_in_helmet)
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE ); //object to empty slot swap (non-attachment)
}
else
{ //how to handle ?? remove attach to inv[slot] ? //this looks like its working
pObj->RemoveAttachment(pGoggles, &(pTeamSoldier->inv[ bSlot1 ]));//object to empty slot swap (attachment)
}
}
}
else //no item found in Inventory, try to handle item in face slot
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"NVG NOT FOUND");
if(Swap_Goggles_facestate == 2) // drop face item into empty INV slot, bSlot1 holds the position index
{
if(! PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE))
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any room to store their sun goggles.",pTeamSoldier->name);
}
//arynn TODO : add in possiblity to store item in helm (involves checking for helm, and helm can accept attachment)
}
else
{ // this is arrived to, when goggle not on face, nor in inventory
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any goggles.",pTeamSoldier->name);
}
}
}
// PART 2 FIND ITEM IN INV BLOCK==================================================================================
else if (Swap_Goggles_mode==2)//seek SVG
{
int bestBonus = 0;
OBJECTTYPE* pGoggles = FindSunGogglesInInv( pTeamSoldier );
if (pGoggles)
{
bestBonus = Item[pGoggles->usItem].brightlightvisionrangebonus;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SVG found in INV, BONUS = %i",bestBonus);
}
//search for better goggles on the helmet
pObj = &(pTeamSoldier->inv[HELMETPOS]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus
&& Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus;
item_found_in_helmet = 1;//set item_found_in_helmet flag
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SVG found in helm, BONUS = %i",bestBonus);
}
}
// ok we have our inventory data time to do something
if ( pGoggles )
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SwapObjs to SVG");
if(Swap_Goggles_facestate == 2)
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE ); //object to object swap
//arynn TODO : fix the case where goggles are being placed in illegal inv slots (size problem)
}
else //empty faceslots
{
//ok cant SwapObjs with a helm attachment to an empty face slot (or you get the NADA item in the helm)
if(!item_found_in_helmet)
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE ); //object to empty slot swap (non-attachment)
}
else
{ //how to handle ?? remove attach to inv[slot] ? //this looks like its working
pObj->RemoveAttachment(pGoggles, &(pTeamSoldier->inv[ bSlot1 ]));//object to empty slot swap (attachment)
}
}
}
else //no item found in Inventory, try to handle item in face slot
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SVG NOT FOUND");
if(Swap_Goggles_facestate == 2) // drop face item into empty INV slot, bSlot1 holds the position index
{
if(! PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE))
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any room to store their night vision goggles.",pTeamSoldier->name);
}
//arynn TODO : add in possiblity to store item in helm (involves checking for helm, and helm can accept attachment)
}
else
{ // this is arrived to, when goggle not on face, nor in inventory
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not have any goggles.",pTeamSoldier->name);
}
}
}
fCharacterInfoPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
pTeamSoldier->DeleteSoldierLight( );
pTeamSoldier->PositionSoldierLight( );
}//end of pTeamSoldier is_a merc and in current squad and is not a robot
}//end of Loop Team

//master level output statements
if(Swap_Goggles_mode == 0) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"No one owns any goggles.");}
if(Swap_Goggles_mode == 1) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Squad set for night vision.");}
if(Swap_Goggles_mode == 2) {ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Squad set for sun goggles.");}
}





[Updated on: Wed, 16 July 2008 18:24] by Moderator

Re: Code Snippets[message #175514] Wed, 13 February 2008 10:46 Go to previous messageGo to next message
Ar1z

 
Messages:33
Registered:January 2008
Location: Greece

Nice work Arynn. Here's a thought you could add a check, if it's day or night and make the merc automatically equip the nv goggles or sunglasses etc... Wink
Re: Code Snippets[message #175519] Wed, 13 February 2008 13:08 Go to previous messageGo to next message
Starwalker

 
Messages:768
Registered:October 2005
Location: Hannover, Germany
Ar1z
Nice work Arynn. Here's a thought you could add a check, if it's day or night and make the merc automatically equip the nv goggles or sunglasses etc... Wink

That would defy the penalties that I gave those items, players should care themselves for using the proper gear Wink


Re: Code Snippets[message #175547] Wed, 13 February 2008 21:16 Go to previous messageGo to next message
arynndarkstar

 
Messages:8
Registered:December 2007
@ Ar1z Thanks. ^^
Yeah, a pre-day/night check was considered. Honestly, i don't know how to check that, lol. I could have looked around more, but i wanted a working function. Its really just a couple of key presses till satisfied anyway.

@ Starwlker
I understand what you're saying. However i think the idea is more of a "im toggling this stuff already, might as toggle to the right mode in one stroke" Seriously i'm considering this as an idea to justify AP cost (see below).

The underlying AP cost problem is that half the time 2 toggles are required. One to get all on same page, and a possible second toggle to get in right mode. How can i justify forcing an AP cost in this situation ?

Since i got functionality out of this, im gonna apply game rules to it. Simply because it costs AP to to do it manually. So in getting the swap goggle into "its fair to charge AP now" mode, the function has get to the right mode with one key stroke. I have a few ideas on how to handle :

1) separate function into 2 functions. one for NVG, other SVG. Apply access to them by including another key command.
con - yet another key command (and 2 keys dedicated to same basic operation to boot) this was my 1st idea, i do not like it on a personal level Wink
2) Day/Night check - Mode is determined by lighting or Day/Night/Cave situation.
pro- prevents accidental AP expense thru mis-input (like the drop backpack thing i hit that button
twice evry now and then and its not all that enjoyfull) <_<
3) Change this functions core approach. Instead of squad base, its multi-selected.
pro- side effect -it allows for one guy at a time toggle, neat but not terribly important
con - player still has to identify who needs changing. which is, at best, tedious and not exactly a "fun challenge"

Honestly idea #2 is my fav, its straight forward and to the point. I'm open to suggestions, but i can't think of anything better than this.

I believe the penalties imposed by wearing the wrong goggles for the time of day, should be more of a expression of realism than an excuse for tedious item management. In vanilla JA2.. i never bothered.. i got NVG and i just wore them all the time, i dint give a crap, i wasnt penalized.. i was more worried about inventory space and the best place to put them, your face, a real fire and forget type thing..

1.13 gives me helmet slots, and penalizes me for being lazy with the NVG's.. i think its great honestly.

But as it is here, or with NIV/base 1.13, the macro is a cheat. I don't like it. It cost AP to do it manually, it should cost AP to do it thru the macro. It needs further attention.





[Updated on: Wed, 13 February 2008 21:23] by Moderator

Re: Code Snippets[message #175598] Thu, 14 February 2008 12:46 Go to previous messageGo to next message
Starwalker

 
Messages:768
Registered:October 2005
Location: Hannover, Germany
Arynn
@ Starwlker
I understand what you're saying. However i think the idea is more of a "im toggling this stuff already, might as toggle to the right mode in one stroke" Seriously i'm considering this as an idea to justify AP cost (see below).

I am not against what you are doing, I am only against automatic toggling.
If the player cares for it himself, then your work takes some of his load, which is fine. But I want not that players are going to forget about it altogether.


Re: Code Snippets[message #175639] Thu, 14 February 2008 19:36 Go to previous messageGo to next message
afp

 
Messages:77
Registered:November 2007
Temporary fix for crouch AP bug - the cursor read 13 APs, when you shoot changing direction you spend 15. It's a temporary fix, there are many flaws there.


file points.cpp
function MinAPsToShootOrStab
line 1444

//charge the maximum of the 2
if ((gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_CROUCH) ||
(gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE))
//afp temporary fix of the AP crouch bug
bAPCost += usTurningCost + usRaiseGunCost;
else
bAPCost += __max(usTurningCost,usRaiseGunCost);
Re: Code Snippets[message #177773] Sun, 09 March 2008 03:36 Go to previous messageGo to next message
jones
Messages:4
Registered:April 2001
Location: USA
CTRL + ALT traps the cursor inside the JA2 window so scrolling works in window mode


Quote:



Index: Utils/Cursors.cpp
===================================================================
--- Utils/Cursors.cpp (revision 1869)
+++ Utils/Cursors.cpp (working copy)
@@ -1293,12 +1293,40 @@

}

+//j
+void check_mouse_restriction(void)
+{
+ static bool mouse_clipped = false;
+ static long ticks;
+
+ if (gfKeyState[ALT] && gfKeyState[CTRL] && time(NULL) > ticks + 2)
+ if (mouse_clipped)
+ {
+ mouse_clipped = false;
+ ClipCursor(NULL);
+ ScreenMsg(140,0,L"Cursor Freed");
+ ticks = time(NULL);
+ }
+ else
+ {
+ mouse_clipped = true;
+ RECT aRect;
+ SetRect(&aRect,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
+ ClientToScreen(ghWindow,(LPPOINT)&aRect);
+ ClientToScreen(ghWindow,(LPPOINT)&aRect+1);
+ ClipCursor(&aRect);
+ ScreenMsg(140,0,L"Cursor Clipped");
+ ticks = time(NULL);
+ }
+}
void BltJA2CursorData( )
{
if ( ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) )
{
DrawMouseText();
DrawMouseGraphics();
+//j
+ check_mouse_restriction();
}
}

[Updated on: Wed, 16 July 2008 18:20] by Moderator

Re: Code Snippets[message #177956] Tue, 11 March 2008 04:31 Go to previous messageGo to next message
Kaiden

 
Messages:518
Registered:September 2003
Jones!

What happened? You had some really nice features and then stopped posting, no source left, etc...


Re: Code Snippets[message #190901] Wed, 16 July 2008 02:27 Go to previous messageGo to next message
lillebror
Messages:1
Registered:October 2006
Location: Denmark
Weapons.cpp
lol great if playing a Rambo game or 007 single IMP game..

just remove // and u have a aimbot or rambo effect... or both...

hillarius funny AI bashing when used on INSANE

the cats civ and creatures are not effected so just add more xxxx_TEAM



//ATE: Added if we are in meanwhile, we always hit...
if ( AreInMeanwhile( ) )
{
uiHitChance = 100;
}

// ROLL DICE
// << edit by StoreBror
// uiDiceRoll = random( 100 );
// if ( pSoldier->bTeam == OUR_TEAM ) {
// uiHitChance = 100;
//}
// ROLL DICE
// << edit Mr.NiCe
// uiDiceRoll = random( 100 );
// if ( pSoldier->bTeam == ENEMY_TEAM ) {
// uiHitChance = 1;
//}
uiDiceRoll = Random( 100 );
// >>

#ifdef JA2BETAVERSION
if ( gfReportHitChances )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Hit chance was %ld, roll %ld (range %d)", uiHitChance, uiDiceRoll, PythSpacesAway( pSoldier->sGridNo, pSoldier->sTargetGridNo ) );
}
#endif

fGonnaHit = uiDiceRoll <= uiHitChance;

// GET TARGET XY VALUES
Re: Code Snippets[message #191110] Fri, 18 July 2008 18:40 Go to previous messageGo to next message
Headrock

 
Messages:1781
Registered:March 2006
Location: Jerusalem
Ok I did this yesterday and figured out most people would at least be interested in this.

One of my old experiments was about trying to cut weapon ranges and increase sight-range simultaneously, to change the nature of the game. My idea was that by spotting enemies from afar (and, being spotted) while having to get in relatively close to take a shot, the game becomes much more tactics-oriented. Suddenly, pistols and SMGs became much more suitable for combat than they are today, and much more thought can be given to stealth and smart movements.

Unfortunately, the biggest flaw in this was inherent in JA2. Namely, Chance-to-hit. See, CTH only moves between 1% and 99%. The guys at Sirtech obviously thought that it would be best if there was always SOME chance for error, and SOME chance for success. Now, I don't mind missing once in a while even when CTH is set to highest, but the minimum bothered me. What this minimum means (1% CTH at any given time) is that 1 in every 100 shots would score a hit, regardless of how wildly one was firing.

Naturally, this is quite realistic, as even a wildly firing madman has a certain likelyhood of hitting the target, which is why I don't think the minimum should be set to 0%. However, I do believe that not only is a 100-to-1 ratio unrealistic (meaning, the probability should be MUCH lower), but that it also is one of the reasons why MGs and other autofire weapons in this game so GROSSLY outperform most of the single-fire weapons.

At first I thought it would be a good idea to make CTH a float rather than an integer. Unfortunately, it didn't take long for me to realize that C++ doesn't really like floats. So instead I played a little trick:

Weapons.h
#define MINCHANCETOHIT 0


Weapons.cpp
  if (iChance < MINCHANCETOHIT)
	{
		if ( TANK( pSoldier ) )
		{
			// allow absolute minimums
			iChance = 0;
		}
		else
		{
			if ( Random( 10 ) <= 8 )
			{
				iChance = MINCHANCETOHIT;
			}

			else
			{
				iChance = MINCHANCETOHIT+1;
			}
		}
	}


This is the only change that has to be made. Everything else falls into place as a result, and I haven't had any bugs yet nor do I believe there would be.

Once this is done, there's a 1/1000 (or is it 1/900?) chance to hit when there's "no real chance", rather than 1/100 as it was before.

Now I realize that some people wouldn't like this, but that's true for every idea. However I believe that most people would like the impact this has on the game. For starters, autofire becomes much less accurate once it can go below 1% chance of hitting. Previously, one could spray and pray quick effectively, especially with faster SMGs, ARs and MGs. Now, spraying a large area with a long autofire burst isn't likely to hit anything. Even machinegunners would prefer to, and by all means should, fire in short bursts.
Naturally, tracer fire also becomes much more potent, but I'm already working on an idea to change that so it balances out.

There are several code editions I'd like to make to augment this feature, most importantly teaching NPCs to fight accordingly, and perhaps post the whole thing as a mod. Of course I would accept any help anyone can give, as C++ still gives me headaches. Anyhow I'll post some ideas in the feature request forum and see if they catch on.

Peace and happy coding!


Re: Code Snippets[message #191117] Fri, 18 July 2008 19:28 Go to previous messageGo to next message
Headrock

 
Messages:1781
Registered:March 2006
Location: Jerusalem
Oh, also, Ar1z's gun range multiplier - I managed to get something like that done today, except it doesn't accept options.ini output yet, but it does affect everything correctly including the tooltips. I'll post parts of it later.


Re: Code Snippets[message #191131] Fri, 18 July 2008 21:19 Go to previous messageGo to next message
KEN C

 
Messages:253
Registered:May 2007
Location: Aberdeen Washington USA
Please make changes like this optional. Some people believe burst and auto fire are not accurate enough right now.
Re: Code Snippets[message #191137] Fri, 18 July 2008 21:48 Go to previous messageGo to previous message
Headrock

 
Messages:1781
Registered:March 2006
Location: Jerusalem
@ OLDN000B:

As I said, the idea is mostly geared towards a mini-mod. However, as I also said, I'm working on a way to use tracers (oh, and aimed bursts) to really make automatic weapons behave more lifelike, and equally dangerous. But this change, or should I say "fix", is meant to stop pistols from dropping enemies (or mercs) at ridiculous ranges. 1 of every 100 bullets is a sure hit at any range, that's just ridiculous.


Previous Topic: New Attachment System Beta
Goto Forum:
  


Current Time: Sun Dec 16 08:07:46 EET 2018

Total time taken to generate the page: 0.02840 seconds