It is possible to cause the death of the CollectorNomad2 object (rush
to it before it possibly leaves again into the sidepackets the ship
won't fit through). The transition happens here:
```
f0 KillObject (objp=0x3d4d3e0 <Objects+384000>, killer=0x3cef7e0 <Objects>, damage=3) at /home/jengelh/D3/Descent3/damage.cpp:1036
f1 ApplyDamageToGeneric (hit_obj=0x3d4d3e0 <Objects+384000>, killer=0x3cef7e0 <Objects>, damage_type=6, damage=3, server_says=0, weapon_id=255) at /home/jengelh/D3/Descent3/damage.cpp:1401
f2 collide_generic_and_player (robotobj=0x3d4d3e0 <Objects+384000>, playerobj=0x3cef7e0 <Objects>, collision_point=0x7f877f40a830, collision_normal=0x7f877f40a858, f_reverse_normal=true, hit_info=0x7f877f40a810) at /home/jengelh/D3/physics/collide.cpp:2127
f3 collide_two_objects (A=0x3cef7e0 <Objects>, B=0x3d4d3e0 <Objects+384000>, collision_point=0x7f877f40a830, collision_normal=0x7f877f40a858, hit_info=0x7f877f40a810) at /home/jengelh/D3/physics/collide.cpp:2505
f4 do_physics_sim (obj=0x3cef7e0 <Objects>) at /home/jengelh/D3/physics/physics.cpp:1515
f5 ObjDoFrame (obj=0x3cef7e0 <Objects>) at /home/jengelh/D3/Descent3/object.cpp:2824
f6 ObjDoFrameAll () at /home/jengelh/D3/Descent3/object.cpp:2988
f7 GameFrame () at /home/jengelh/D3/Descent3/GameLoop.cpp:2980
f8 GameSequencer () at /home/jengelh/D3/Descent3/gamesequence.cpp:1221
f9 PlayGame () at /home/jengelh/D3/Descent3/game.cpp:834
f10 MainLoop () at /home/jengelh/D3/Descent3/descent.cpp:550
f11 Descent3 () at /home/jengelh/D3/Descent3/descent.cpp:508
f12 oeD3LnxApp::run (this=0x7f877f00db50) at /home/jengelh/D3/Descent3/sdlmain.cpp:151
<frame 2> (gdb) p robotobj
$1 = {
type = 2 '\002' (OBJ_ROBOT), dummy_type = 255 '\377', id = 276,
flags = 2135072, name = 0x5020000aff30 "CollectorNomad2",
handle = 2432, next = 178, prev = -1,
control_type = 1 '\001' (CT_AI), movement_type = 2 '\002' (MC_ROLLING),
render_type = 1 '\001' (LRT_GOURAUD), lighting_render_type = 1 '\001', roomnum = 58,
pos = {x = 2350.21484, y = -263.523956, z = 1868.59888},
orient = {
rvec = {x = 0.882905424, y = 1.63964216e-14, z = -0.469550878},
uvec = {x = -1.25793295e-14, y = 1, z = 1.12662192e-14},
fvec = {x = 0.469550878, y = -4.04037088e-15, z = 0.882905424}
},...}
```
Thus, KillObject sets obj->control_type=CT_DYING. In the same game
tick, Level6.cpp then calls aAIGoalFollowPathSimple which triggers
the assertion.
```
Int3 in $GIT/Descent3/osiris_predefs.cpp at line 571.(Descent 3 Debug Break)
f0 osipf_AIGoalFollowPathSimple (objhandle=2432, path_id=21, guid=7, flags=1052928, slot=3) at $GIT/Descent3/osiris_predefs.cpp:571
f1 AI_GoalFollowPathSimple (objhandle=2432, path_id=21, guid=7, flags=1052928, slot=3) at $GIT/scripts/osiris_import.h:170
f2 aAIGoalFollowPathSimple (objhandle=2432, pathid=21, flags=1052928, goalid=7, priority=3) at $GIT/scripts/DallasFuncs.cpp:3649
f3 LevelScript_0000::CallEvent (this=0x5020000ba430, event=256, data=0x7f963e71d930) at $GIT/scripts/Level6.cpp:2465
f4 CallInstanceEvent (id=0, ptr=0x5020000ba430, event=256, data=0x7f963e71d930) at $GIT/scripts/Level6.cpp:2209
f5 Osiris_CallLevelEvent (event=256, data=0x7f963e71d930) at $GIT/Descent3/OsirisLoadandBind.cpp:2000
f6 GameFrame () at $GIT/Descent3/GameLoop.cpp:3020
f7 GameSequencer () at $GIT/Descent3/gamesequence.cpp:1221
f8 PlayGame () at $GIT/Descent3/game.cpp:834
f9 MainLoop () at $GIT/Descent3/descent.cpp:550
f10 Descent3 () at $GIT/Descent3/descent.cpp:508
f11 oeD3LnxApp::run (this=0x7f963e80db50) at $GIT/Descent3/sdlmain.cpp:151
```
For lightning effect we using ps_rand() function which expects number in range [0, 0x7fff], but RAND_MAX is 0x7fffffff (INT_MAX, for 64-bit systems). In result lightnings strikes on every allowed frame and leads to epilepsy.
In `psrand.h` it attempts to undefine RAND_MAX and then redefine it.
This may work on some compilers but G++/Clang. To resolve this error
RAND_MAX was renamed to D3_RAND_MAX but **only** in files that
included `psrand.h`. The code behavior should restored to that of the
official release.
Added installation steps for all built targets. Added FORCE_PORTABLE_INSTALL cmake option that controls portable installation (only supported for now).