Needed this to run UnrealEd http://download.microsoft.com/download/vb50pro/utility/1/win98/EN-US/Msvbvm50.exe

16 units is 1 foot, from DeusExPlayer.uc:
// check a 100 foot radius around me for combat
if ((npc != None) && (VSize(npc.Location - p.Location) < (1600 + npc.CollisionRadius)))

what does this ResetKeyboard() function do?

in HX, use the switchcooplevel command to load a level

in order to decompile HX with UnrealEd, or compile HXRandomizer, you'll need to add the EditPackages lines to the DeusEx.ini file in the HX System folder
EditPackages=Core
EditPackages=Engine
EditPackages=Editor
EditPackages=Fire
EditPackages=IpDrv
EditPackages=UWindow
EditPackages=UBrowser
EditPackages=Extension
EditPackages=DeusExUI
EditPackages=ConSys
EditPackages=DeusExConversations
EditPackages=DeusExSounds
EditPackages=DeusExItems
EditPackages=DeusExDeco
EditPackages=DeusExCharacters
EditPackages=DeusExConText
EditPackages=DeusExConAudioAIBarks
EditPackages=MPCharacters
EditPackages=DeusExText
EditPackages=IpServer
EditPackages=DeusEx
EditPackages=HX
EditPackages=HXRandomizer


v1.5.9 Alpha:
	fix skill values resetting every 5 missions?
	better way to merge compiler_settings.json into compiler_settings.default.json
	VersionToInt reserve some more digits for hidden version numbers and alphas and betas
		argument for optional int build, and make alphas and betas use negative numbers?
			or assume that if the other arguments match the current version then the build should match too?
		make a warning when I call VersionToInt with build number less than 0 so I remember to clean them up?
		bump the minimum versions for every config so everyone is updated
	HX notes don't travel, goals do
	config for difficulty settings
		in DXRando, easy: { combatDifficulty: 1 } means easy is the key and combat difficulty is a result of it
		in HXRando, we can look up which rando settings to use based on the combatDifficulty, so it'll be backwards lookup
		I might want to switch configs to use an array of struct KeyValuePair { name key; int val; }, need to make sure it fits in replication
	need to do something about all the object names, maybe some of them can be switched to class+tag combos
	refactor DXRFlags to do binding on the flags, should be similar to LoadFlags because stored_version will be the newest version when saving
	cleanup goals when finishing missions, especially hong kong
	can I partially re-enable Paul's conversation in liberty island and remove the part where he gives you a weapon?
		will need to mark it as played when entering unatco though, pretty sure it can break stuff
	DXRWeapons projectile damage
	DXRPasswords and DXRKeys using Containers as possible locations? can be risky

v1.5.9:
	sub base elevator needs call down button
	bug in sub base backtracking chopper
	fix charged pickups going in hand
	weapon/ammo descriptions should show the max ammo
	improve: DXRKeys: INFO: key maintenancekey got num: 1, slot: 0, actor: 12_Vandenberg_Tunnels.MedKit0
		DXRKeys: swapping MedKit.MedKit0(-1437.876587,3819.677734,-3246.906738) and NanoKey.NanoKey1(-1138.429199,3494.751221,-3084.074463) distance == 470.914337
	
	ninja mode:
		I can make ninja mode spawn more continuous blood on a timer or tick
		faster weapon switching speeds for ninja mode?
		wider range on the sword for ninja mode?
		can I also give low tech skill more levels, or repurpose other skills?
		maybe gas grenades should be allowed too? emp grenades? other grenades?
		too much throwing knives ammo?
	Stick With the Prod (and Plus) should give the AugStealth instead of AugSpeed?
		rename them to Stick With the Prod (Pure) and Stick With the Prod (Plus)?
		start with the muscles aug so you can move explosive barrels? combat strength is useless anyways
	do I need to make choppers appear when backtracking? like appearing at the mapexit on the roof of the sub base?
	tweak rotations for teleporters?
	enough advanced options to be able to play unrandomized
		-disable item/container shuffling, aug cannisters and aug values, skill values, loadout, names)
	manually add actors to the safety checks for keys and datacubes, as an easier version of the safe_rules
	make horde mode use the DXRAutosave blocking manual saves method instead of the hack-y permanent fake datalink
	use better logic for The Merchant's location, like cameras?
	use key safe location logic for hazmats vs damage zones (this might only be a big deal for paris?)
	crowd control spawn medbot, friendly milbot
	crowd control incremental speed effects
	crowd control, ensure you don't go past the max ammo
	fix the dumb button to backtrack in paris metro, stacked boxes is better
	if I get rid of the ZoneVelocity on WaterZone5 in 06_hongkong_storage, I can add a dynamicteleporter to make that pipe a 2-way connection
		might also need to do WaterZone1, but that would make it difficult to hold your breath through there, I could make a dynamicteleporter bring you past that
	DXREntranceRando: WARNING: GenerateConnections(12) succeeded but took 24 attempts! seed: 158016, genconsfails: 7, validatefails: 17
	HX: DXRMissions, DXRFixup? DXRHordeMode? credits, new game plus? DXRStats? crowd control, gonna need to add simulated to like every function
	automated tests in HX?
	lore friendly enemy spawns? triads would be good extra enemies in hong kong at least
	any way I could get DXRNames to work with replication?
	maybe clean up the credits a bit more, especially the DXRFlags section
	scale difficulty with extra players like diablo, slightly increase enemy randomization and combat difficulty

for v1.6 programatically modify conversations? ===================

GUI for NG+? can open a window similar to the advanced settings page
create new "stories", start with a hub area (either hell's kitchen or hong kong, but which hell's kitchen?)
	class DXRStories extends DXREntranceRando;
	move stuff from DXRBacktracking into functions to "open up" areas, so they can be called from DXRStories
	connect a bunch of random maps to it (from any mission)
	how to determine if a map should be neutral or hostile?
	remove all vanilla npcs and dialog and add new ones
	after beating a hub area, it can take you to the "next" area just by running a different seed, maybe do something to ensure it's based on a different hub area
	I need to reuse the data in DXREntranceRando, maybe by subclassing it
for better log message window, look at DeusExRootWindow ClientMessage function, and HUDLogDisplay AddLog and SetLogTimeout functions
HUD to show current energy use per second, similar to the damage resistance HUD
	could allow randomization of aug energy usage
dynamically generate patrol routes? will probably need a new state for scriptedpawns to replace patrolling
randomize item pool by replacing 50% of items?
with flags binding, maybe I could convert some of them to floats or ints x100

CleanerBot Tick function could also cleanup Effects, TrashPaper, Fragment...


in Actor.uc
// Probe messages.
native(117) final function Enable( name ProbeFunc );
native(118) final function Disable( name ProbeFunc );

// Properties.
native final function string GetPropertyText( string PropName );
native final function SetPropertyText( string PropName, string PropValue );
native static final function name GetEnum( object E, int i );

// Configuration.
native static final function string GetConfig( string ConfigSection, string ConfigKey);  // DEUS_EX CAC
native(536) final function SaveConfig();
native static final function StaticSaveConfig();
native static final function ResetConfig();

// "fixes"? for ammo in mission 5
	local Inventory item, nextItem;
	local Ammo a;
	local Vector locs[4];
	local class<Ammo> types[5];
	local class<Ammo> type;
	local int i, k, r;

	// remove ammo from the player when captured
	for( item = player().Inventory; item != None; item = nextItem) {
		nextItem = item.Inventory;
		a = Ammo(item);
		if( a != None ) {
			a.AmmoAmount = 0;
			player().UpdateAmmoBeltText(a);
		}
	}

	// make up for it by adding ammo on the guard's desk
	types[0] = class'Ammo10mm';
	types[1] = class'Ammo762mm';
	types[2] = class'AmmoShell';
	types[3] = class'Ammo3006';
	types[4] = class'AmmoDartPoison';
	locs[0] = vect(-2084.170654, 1212.210327, -132.129761);// the first guard's desk
	locs[1] = vect(-2104.531494, 1232.512817, -132.130157);
	locs[2] = vect(-2140.163330, 1245.518555, -132.130081);
	locs[3] = vect(-2183.612061, 1241.690430, -132.129669);
	for(i=0; i < ArrayCount(locs); i++) {
		if( ! chance_single(dxr.flags.ammo) ) continue;

		r = initchance();
		type = types[0];
		for(k=0; k<ArrayCount(types); k++) {
			if( chance( 100/ArrayCount(types), r ) ) type = types[k];
		}
		chance_remaining(r);
		a = Spawn( type,,, locs[i] );
	}

//causes issues with test "simple GenerateConnections validation" for some reason, using GetUnusedTransferByOffset instead of GetNextTransferIdx works better
function SortTransfers()
{
    local int i, t;
    local MapTransfer temp;
    local int numxfersbymap[50];

    for(i=0; i<numXfers; i++) {
        numxfersbymap[i] = GetNumXfersByMap(xfers[i].mapname);
    }

    for(i=0; i+1<numXfers; i++) {
        if( numxfersbymap[i] < numxfersbymap[i+1] ) {

            temp = xfers[i];
            t = numxfersbymap[i];

            xfers[i] = xfers[i+1];
            numxfersbymap[i] = numxfersbymap[i+1];

            xfers[i+1] = temp;
            numxfersbymap[i+1] = t;

            i=-1;
        }
    }
}


UWindowHTMLTextArea
ninja mode (maybe rename low tech skill to ninjitsu, and always run silent?
fix "softlock" in 03_batterypark, maybe by adding an atm and datacube, or copying over the threatened bum from 02_street, putting a note on curly's body, hiding money and/or datacubes on the map...
-filben wants 1000 credits!
-using a vending machine takes 2 credits, so the vending machines in unatco mean -40 credits
-manderley gives you a minimum of 500 credits, so you have a minimum of 460 credits and I need to give a minimum of 540 credits in 03_batterypark
-hacking an atm gives less money, so I need to have more than 540 in the atm?
	-hacked atm balance modifier - balanceModifier = winTerm.GetSkillLevel() * 0.5;
	-which means level 1 gets half money
-I can do 800 in the atm with a datacube for it, and 150 on the ground somewhere
-will also need something if you kill curly, dropping a datacube would be cool
-should I also make the phone booth breakable?
-I can also try copying the AlleyBum and AlleyThug (maybe 3 thugs this time?) from 02 nyc streets, but I'm pretty sure I'll manually need to modify his ConListItems (sets flags AlleyBumRescued and PlayerKnowsUnderworldPassword)
	// check to see if player rescued bum
	if (!flags.GetBool('MS_ThugsDead'))
	{
		count = 0;

		foreach AllActors(class'ThugMale2', thug2, 'AlleyThug')
			count++;

		// set the resuced flag if the bum is still alive
		if (count == 0)
		{
			foreach AllActors(class'BumMale', bum, 'AlleyBum')
				flags.SetBool('AlleyBumRescued', True,, 3);

			flags.SetBool('MS_ThugsDead', True,, 3);
		}
	}

	if (flags.GetBool('OverhearAlleyThug_Played') &&
		!flags.GetBool('MS_ThugAttacks'))
	{
		foreach AllActors(class'Actor', A, 'ThugAttacks')
			A.Trigger(Self, Player);

		flags.SetBool('MS_ThugAttacks', True,, 3);
	}



maybe add a list of unimportantMaps for DXREntranceRando? maybe chateau, freeclinic, nyc sewers, smuggler, gas station, graveyard?
    in order to keep play time more consistent never do all or none of them?
have different "Level Sets"

should I add an option for "normal skill rando every 5 missions"?

combine medkits/biocells/lockpicks/multitools into just items drop rate?


class DataLinkPlay injects DataLinkPlay;

function PlaySpeech( int soundID )
{
    log("PlaySpeech("$soundID$")");
    Super.PlaySpeech( 1 );
}

function EEventAction SetupEventSpeech( ConEventSpeech event, out String nextLabel )
{
    log("SetupEventSpeech: "$event.conSpeech.speech);
	event.conSpeech.speech = "Prod with the prod!";

    return Super.SetupEventSpeech(event, nextLabel);
}


//=============================================================================
// ConWindow
//
// Used for non-interactive conversations displayed in first-person
// mode.  This type of conversation can only display spoken text,
// choices are -not- allowed.  
//=============================================================================

class ConWindow extends DeusExBaseWindow;

function DisplayText(string text, Actor speakingActor)
{
	if (winSpeech == None ) 
		CreateSpeechWindow();

	winSpeech.SetSpeech(text, speakingActor);
}

function AppendText(string text)
{
	if (winSpeech == None ) 
		CreateSpeechWindow();

	winSpeech.AppendSpeech(text);
}

//=============================================================================
// ConWindowActive
//
// Used for third-person, interactive conversations with the PC involved.
//=============================================================================
class ConWindowActive extends ConWindow;

// ----------------------------------------------------------------------
// DisplayChoice()
//
// Displays a choice, but sets up the button a little differently than 
// when displaying normal conversation text
// ----------------------------------------------------------------------

function DisplayChoice( ConChoice choice )
{
	local ConChoiceWindow newButton;

	newButton = CreateConButton( HALIGN_Left, colConTextChoice, colConTextFocus );
	newButton.SetText( "~ " $ choice.choiceText );
	newButton.SetUserObject( choice );

	// These next two calls handle highlighting of the choice
	newButton.SetButtonTextures(,Texture'Solid', Texture'Solid', Texture'Solid');
	newButton.SetButtonColors(,colConTextChoice, colConTextChoice, colConTextChoice);

	// Add the button
	AddButton( newButton );
}

// ----------------------------------------------------------------------
// DisplaySkillChoice()
//
// Displays a Skilled choice, a choice that's only visible if the user
// has a particular skill at a certain skill level
// ----------------------------------------------------------------------

function DisplaySkillChoice( ConChoice choice )
{
	local ConChoiceWindow newButton;

	newButton = CreateConButton( HALIGN_Left, colConTextSkill, colConTextFocus );
	newButton.SetText( 	"~  " $ choice.choiceText $ "  (" $ choice.SkillNeeded $ ":" $ choice.SkillLevelNeeded $ ")" );
	newButton.SetUserObject( choice );

	// Add the button
	AddButton( newButton );
}

class ConWindowSpeech extends AlignWindow;

function SetSpeech(String newSpeech, optional Actor speakingActor)
{
	if (newSpeech == "")
	{
		txtSpeech.SetText("");
		txtSpeech.Show(False);
	}
	else
	{
		txtSpeech.SetText(newSpeech);

		// Use a different color for the player's text
		if ((speakingActor != None) && (DeusExPlayer(speakingActor) != None))
			txtSpeech.SetTextColor(colConTextPlayer);
		else	
			txtSpeech.SetTextColor(colConTextNormal);

		txtSpeech.Show(True);
	}
}

function AppendSpeech(String newSpeech)
{
	txtSpeech.AppendText(CR() $ CR() $ newSpeech);
}


for v1.5 ========================

another issue with DXREntranceRando:
    if I make a connection from paris metro to chateau, DXREntranceRando will ensure I can get to the metro to get to the chateau, but it won't realize that I also need to get to the club first
    similarly, you go from 12_vandenberg_cmd to gas station, but you need to get to 12_vandenberg_computer first before the chopper will appear
    might need a `string other_required_map` for each transfer?
lots of doors that need buttons on the other side in mission 14, and maybe 12_vandenberg_tunnels could use that too instead of making it open on player bump
write tests for repeated use of teleporters, and for denying one-way maps
need to test that a player can move back and forth through all maps, not just capable of visiting them all once, or getting stuck/softlocked in a dead-end

for v1.4========================

nah said:
"also ULevel::SpawnPlayActor also exposed a bNoColissionFail parameter, which is really handy/needed when you wanna replace any actors. some otherwise fail to spawn"

I could make an AugSkill class to turn any skill into an augmentation (might need dummy child classes just due to the way the augmentation manager works)
    -look AugAqualung as an example, could easily adjust the player's skill level in state Active Begin and function Deactivate()
    -energy cost could be based on the cost of the original skill
    -use the augmentation level to give skill levels
    -might be OP if one player gets lucky and finds the hacking augmentation in a race

NavigationPoint (children: PathNode, PatrolPoint, AmbushPoint, InventorySpot) for extra positions where items can be placed?

    - https://docs.unrealengine.com/udk/Three/CharactersTechnicalGuide.html#Pawns%20and%20Possession
    - Pawn class - native(518) final function Actor FindPathTo(vector aPoint, optional bool bSinglePath, 
												optional bool bClearPaths);
    - FindPathTo [aPoint] [MaxPathLength] [bReturnPartial] - This calculates a path to the navigation node closest to the given destination and returns the next node along that path.

    - Pawn class - native(517) final function Actor FindPathToward(actor anActor, optional bool bSinglePath, 
												optional bool bClearPaths);
    - FindPathToward [anActor] [bWeightDetours] [MaxPathLength] [bReturnPartial] - This calculates a path to the navigation node closest to the given actor and returns the next node along that path.
    PointReachable [aPoint] - This returns whether the specified location is directly reachable given the Pawn’s movement capabilities. This function can be expensive and should be avoided in favor of ActorReachable() if possible.
    ActorReachable [anActor] - This returns whether the specified Actor is directly reachable given the Pawn’s movement capabilities. Though potentially more optimized than PointReachable(), this function also can be expensive and should be used sparingly.
    I can use FindPath to determine if I can do a key swap? find path from key to path in question, walk through the NavigationPoints and see if the door is in between any of them?
    -what does this do? native(525) final function NavigationPoint FindRandomDest(optional bool bClearPaths);
        -FindRandomDest - This returns a random node on the navigation network. This can be good for creating a state where the character roams the world.
    -I could find all the NavigationPoints within a small radius of the door, and whichever ones are farther from the key than the door is are bad points that should indicate a failed path finding
        -should this be done in a preparation loop, or while doing the pathfinding?

native(724) final function bool GetBoundingBox(out vector MinVect, out vector MaxVect,
                                               optional bool bExact,
                                               optional vector testLocation,
                                               optional rotator testRotation);

//
// Trace a line and see what it collides with first.
// Takes this actor's collision properties into account.
// Returns first hit actor, Level if hit level, or None if hit nothing.
//
https://docs.unrealengine.com/udk/Two/ActorFunctions.html#Trace
native(277) final function Actor Trace
(
	out vector      HitLocation,
	out vector      HitNormal,
	vector          TraceEnd,
	optional vector TraceStart,
	optional bool   bTraceActors,
	optional vector Extent
);

TraceActors loop doesn't seem useful

native(533) final function bool CanSee(actor Other);

Keypoint, the base class of invisible actors which mark things.
    -LocationID - marks and names an area in a zone

// WarpZoneInfo. For making disjoint spaces appear as if they were connected;
// supports both in-level warp zones and cross-level warp zones.

track times per mission and overall (RTA or IGT?)

for v1.3.3.7====================

to generate the list of all actors, I used windows command prompt dir /B to list the files
I used this website to do quick regexes https://www.regexpal.com/?fam=97259
paste in the list output by dir /B then use this match regex
^(.*)\.uc$
then use this substitution regex
is_valid("$1", class'$1');

run the outputted code in Deus Ex with this function

function bool is_valid(string s, class<Object> o)
{
    local class<Actor> a;
    a = class<Actor>(o);
    if ( a == None ) return false;
    if ( a.default.bHidden ) return false;
    if ( a.default.Mesh == None ) return false;
    if ( a.default.DrawType != DT_Mesh ) return false;
    if ( a.default.Style != STY_Normal ) return false;

    log( "if ( r == i++ ) return class'" $ s $ "';" );
    i++;
    return true;
}

then paste the log output back into the website using this match regex
^(ScriptLog: )(.*)$
and this substitution regex
$2

the output from that will fill the meat of the GetRandomActorClass function


for v1.2========================

x autosave
- MenuScreenSaveGame
- DeusExSaveInfo
can I randomize computer skill requirements? I can randomize the EAccessLevel, but it doesn't do anything? gonna need my class injector to make this clean
I could also randomize how long it takes to hack, if it's long enough then you'll need higher computer skill to be able to do it

=============================

need a function for GiveRandomItem()
need a function for CloneNanoKey()
need to figure out how to modify conversations

AI hearing and vision adjustment, enemy health
actor class also has these:
    var const Actor           Base;          // Moving brush actor we're standing on.
    native(298) final function SetBase( actor NewBase );
    var const PointRegion     Region;        // Region this actor is in.
    var(Collision) const bool bCollideActors;   // Collides with other actors.
    var(Collision) bool       bCollideWorld;    // Collides with the world.
    var(Collision) bool       bBlockActors;	    // Blocks other nonplayer actors.
    var(Collision) bool       bBlockPlayers;    // Blocks other player actors.

bIsItemGoal?
should NanoKeys have buoyancy?

maybe I can rewrite this as a mutator?

https://wiki.beyondunreal.com/Legacy:Simulated_Function

http://www.hypercoop.tk/infobase/archive/unrealtech/Network.htm

https://wiki.beyondunreal.com/Legacy:Replication_Examples/Replication_Test

https://wiki.beyondunreal.com/What_happens_when_an_Actor_is_spawned

https://wiki.beyondunreal.com/Legacy:Simulated_Function

https://docs.unrealengine.com/udk/Two/UnrealScriptReference.html

https://web.archive.org/web/20190407081013/http://www.unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/unrealscript.html

https://web.archive.org/web/20181105143052/http://unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/actor-methods.html

https://web.archive.org/web/20201023054944/http://wiki.beyondunreal.com/Legacy:Compiler_Errors

http://www.unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/unrealscript.html

https://web.archive.org/web/20051025132508/http://mimesis.csc.ncsu.edu/Unreal/Syntax.htm

https://ut99.org/viewtopic.php?t=5985

https://www.dx-revision.com/dxtutorials/constructor/tutorials.htm

charisma setting/skill that disables random dialog options with low charisma?

https://forums.epicgames.com/unreal-tournament-3/unreal-tournament-3-programming-unrealscript/176322-decompile-u-files

https://ut99.org/viewtopic.php?t=12363

https://www.acordero.org/projects/unreal-tournament-package-tool/

https://www.oldunreal.com/wiki/index.php?title=UTPT

https://ut99.org/viewforum.php?f=58

https://ut99.org/viewtopic.php?t=6273

http://unreal.ut-files.com/3DEditing/Tutorials/unrealwiki-offline/ut-package-tool.html

https://www.dx-revision.com/dxtutorials/tack/

https://deusex.fandom.com/wiki/Datacube_transcripts_(DX)

https://gamefaqs.gamespot.com/pc/250533-deus-ex/faqs/51057

http://pierrelorenzi.fr/deusexdialogs/

https://www.ttlg.com/forums/showthread.php?t=130419
