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)))

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

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 ========================

else if (localURL == "10_PARIS_METRO")
	{
		// unhide GuntherHermann
		if (!flags.GetBool('MS_GuntherUnhidden') &&
			flags.GetBool('JockReady_Played'))
		{
			foreach AllActors(class'GuntherHermann', gunther)
				gunther.EnterWorld();

			flags.SetBool('MS_GuntherUnhidden', True,, 11);
		}

MapExit tag, DestMap
10_paris_metro MapExit ChopperExit 10_Paris_Chateau (-825.793274, 1976.029297, 176.545380), (0,0,-10944)
15_area51_final switch2 to 15_area51_entrance#elevator_shaft? (-5757.477539, -2082.639160, -1356.561035), (0,0,16384)

can I use something like this to right click an enum to go backwards? from MenuUIChoice.uc
function bool ButtonActivatedRight( Window buttonPressed )
{
	if (buttonPressed == btnAction)
	{
		CyclePreviousValue();
		return True;
	}
	else
	{
		return Super.ButtonActivated(buttonPressed);
	}
}

new game -> game mode choice -> difficulty? (max rando would skip difficulty choice? and maybe horde mode too?) -> rando options -> create character
combine medkits/biocells/lockpicks/multitools into just items drop rate?
should I add an option for "normal skill rando every 5 missions"?

```
function bool MoveWithTriggers(Actor a, vector loc)
{// I can use this to move the ambrosia barrel in 02_NYC_BATTERYPARK
    local Trigger t;
    local vector oldloc;

    oldloc = a.Location;
    if ( a.SetLocation(loc) == false ) return false;
    foreach RadiusActors(class'Trigger', t, 16, oldloc) {
        t.SetLocation(loc);
    }
    return true;
}
```

maybe add a list of unimportantMaps for DXREntranceRando? maybe chateau, freeclinic, nyc sewers, smuggler, gas station, graveyard?
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
paris and area51 have some one-way transfers that could maybe be fixed?
maybe I can add in the transfers from the chopper, they're one-way MapExits but they should work
teleporters have a bEnabled flag
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
fix dupes like:
DXREntranceRando: Found 06_HONGKONG_MJ12LAB.MapExit0 with destination 06_HongKong_Storage#basement, changed to 06_HONGKONG_HELIBASE#Helibase
DXREntranceRando: Found 06_HONGKONG_MJ12LAB.MapExit0 with destination 06_HongKong_Storage#basement, changed to 06_HONGKONG_WANCHAI_CANAL#Street

you cannot climb out of 03_NYC_AirfieldHeliBase#FromOcean


the code for attaching grenades to walls is interesting
from DeusExWeapon.uc `simulated function bool NearWallCheck()`
```
    // trace out one foot in front of the pawn
    StartTrace = Owner.Location;
    EndTrace = StartTrace + Vector(Pawn(Owner).ViewRotation) * 32;

    StartTrace.Z += Pawn(Owner).BaseEyeHeight;
    EndTrace.Z += Pawn(Owner).BaseEyeHeight;

    HitActor = Trace(HitLocation, HitNormal, EndTrace, StartTrace);
    if ((HitActor == Level) || ((HitActor != None) && HitActor.IsA('Mover')))
    {
        placeLocation = HitLocation;
        placeNormal = HitNormal;
        placeMover = Mover(HitActor);
        return True;
    }
```
and then from `function PlaceGrenade()`
```
    gren = ThrownProjectile(spawn(ProjectileClass, Owner,, placeLocation, Rotator(placeNormal)));
    if (gren != None)
    {
        gren.SetPhysics(PHYS_None);
        gren.bBounce = False;
        gren.bProximityTriggered = True;
        gren.bStuck = True;
        if (placeMover != None)
            gren.SetBase(placeMover);

        // up the damage based on the skill
        // returned value from GetWeaponSkill is negative, so negate it to make it positive
        // dmgX value ranges from 1.0 to 2.4 (max demo skill and max target aug)
        dmgX = -2.0 * GetWeaponSkill() + 1.0;
        gren.Damage *= dmgX;
```

experimental teleport to actor by name, probably better to make a subclass of Teleporter that sets a flag, and then in a DXR Module on AnyEntry read that flag and clear it
```
err( "GetLocalURL: " $ Level.GetLocalURL() );
    err( "GetAddressURL: " $ Level.GetAddressURL() );

    if(dxr.dxInfo.missionNumber == 1) {
        foreach AllActors(class'Teleporter', t) {
            //t.URL = "02_NYC_STREET#?toname=Teleporter19";
            t.URL = "15_area51_entrance#?toname=Light73";
        }
    } else {
        foreach AllActors(class'Teleporter', t) {
            //t.URL = "02_NYC_STREET#?toname=Teleporter19";
            if( t.URL != "" ) {
                t.URL = t.URL $ "?toname=";//otherwise toname will stay for the rest of the game
            }
        }
    }

    tonamestring = Level.game.ParseOption( "?" $ Level.GetLocalURL(), "toname" );
    err("tonamestring: " $ tonamestring);
    if( InStr(tonamestring, "#") >=0 ) {
        tonamestring = Left(tonamestring,InStr(tonamestring,"#"));
    }
    err("tonamestring: " $ tonamestring);
    if( tonamestring != "" ) {
        toname = dxr.Player.rootWindow.StringToName(tonamestring);
        err("toname: " $ toname);
        foreach AllActors(class'Actor', a) {
            if( a.Name == toname ) {
                err("found actor "$a);
                dxr.Player.SetLocation(a.Location);
            }
        }
    }
```

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

randomly remove/move medbots and repair bots?

add more tests? I should maybe make tests only run once per launch, maybe like on localURL == "DX" maybe the training area or liberty island cause some tests will need a world?
    -tests for ClassIsA, skill randomization, augs...

I can make more stuff data-driven
    -config to enable/disable modules? modules in a separate package?
    -DXRReduceItems could receive arguments/config for which classes of items to reduce and what %
    -each module should be in charge of their own flags and flagnames?
    -config value for enabling tests
    -I can display a crc hash of the configs and flags as a clientmessage, like how the seed is shown

split up the Swap function, support multiple classes for SwapAll? or just support NavigationPoints?

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.
//
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() (based on Engine.Pickup.SpawnCopy? no, that's for respawning items)
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.

exploded corpses drop keys?
bIsItemGoal?
should NanoKeys have buoyancy?

maybe I can rewrite this as a mutator?

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/20201023054944/http://wiki.beyondunreal.com/Legacy:Compiler_Errors

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

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/


    /*foreach AllActors(class'ScriptedPawn', p)
    {
        if( p.bIsPlayer ) continue;
        inv = spawn(class'WeaponAssaultGun');
        inv.GiveTo(p);
        inv.SetBase(p);

        inv.AmmoType = spawn(inv.AmmoName);
        inv.AmmoType.InitialState='Idle2';
        inv.AmmoType.GiveTo(p);
        inv.AmmoType.SetBase(p);

        p.SetupWeapon(false);
    }*/

    /*foreach AllActors(class'DeusExCarcass', c)
    {
        inv = spawn(class'WeaponAssaultGun', self);
        c.AddInventory(inv);
    }*/