Home and Links
 Your PC and Security
 Server NAS
 DVD making
 Raspberry Pi
 PIC projects
 Other projects
 Next >>

Diving submarines

CF submarines

Adding the submarine unit 'type'

This is a 'work in progress'

The real problem with Submarines is the Players 'God's eye view' i.e. Subs can't 'dive'. To fix this, software code changes are needed.

As with missiles, the 'easy' way to dive your subs is to simply define a new unit 'type' (unit flags are held in a 'long' = 32bit word, so there are plenty 'spare'). You then modify the artwork (units.bmp) to add the 'transpartent' icon to the start of the file (so it's location can be 'hard coded' into the source game.cpp).

Then 'all' that's needed is to modify the game.cpp code (at about line 777) to 'hide' enemy subs at the end of their go

To 'dive' a sub, it's artwork icon (pointer) is set to 'transparent'. To surface it's set back to normal sub.
However to do this, we need to define a 'transparent' unit icon - and this must be 'fixed' in the units.bmp file (since it's position is going to be hard-coded into the source).
I modified units.bmp to add 6 'transparent' icons at pos=0-7 (this will preserve facing). Since this would mean the units definitions file (units.rsc) would have to change anyway, I moved the sub artwork icon to the next 'slot', pos=8-11.

Note that, since units can't 'stack', detecting enemy Submarines is just a matter of noting which hex's you own sea units are 'not allowed to enter' during their movement phase.

Enemy Subs not within 'range' of any of your own units are thus 'undetectable'.
Of course, if you do 'spot' an enemy sub. there is nothing to stop you attacking 'as normal'

On the first game turn, the first player will see enemy Subs that have been 'pre-deployed' = unless, in CoMET, you pre-deploy subs with the 'transparent' artwork icon. Of course, whilst this 'works' fine, it does mean that once deployed in CoMET you can't actually 'see' them :-)

Source code changes

To define the sub 'type' flag, in gamedefs.h, add :-
#define U_SUBMARINE 0x00001000
When the unit definitions file (.usrc) is compiled, units of type = submarine have to be 'built' with the new flag set by makunitset.cpp. After :-
if ( key == "type" ) {
add :-
else if ( val == "submarine" ) t.AddFlags( U_SUBMARINE );

The final change is to game.cpp source - it has to 'spot' when this players submarine is in water/deepwater and dive it before the next players turn or surface it (so the next player can see their own subs or enemy subs in shallow water)

Start by adding a definition to 'detect' if the unit is of type submarine in /source/comet/unit.h add :-
bool IsSubmarine( void ) const { return (u_flags & U_SUBMARINE) != 0; }

Now the complicated part. A unit game object has a 'u_type' value which is a 'pointer' (*prefix) into the unit type definition array (UnitType) held in computer in memory. These pointers are generated when the map is compiled (by looking up each units name in the compiled units file).

SO - what we need to do is change the u_type pointer from the 'submarine' icon to the 'transparent' icon and back again. This means 'saving' the two pointers generated when the map is created by cfed i.e. adding them to the 'map' (or mission') header. They will then be carried forward into the current game.

Since the transparent icon is always at the start of the icon array, all we need to do is note where the array, when loaded into memory, starts.
At the end of the turn, any submarine of the current player in water/deepwater is dived, all others surfaced. In game.cpp, at about line 777, in the section :-
while ( u ) {
next = static_cast(u->Next());
add :-
// detect submarines if ( u->IsSubmarine ) { // current player, in water/deepwater, dives (i.e. change the u_type for this unit) if ( ) { } else { // else surface } }

Now recompile CF and makeunits (which defines the u_type constants)... then and go set up the submarine unit defs and artwork and recompile the units file and that's it !

Next page :- Code mods Hills