diff --git a/.github/release_template.md b/.github/release_template.md index 2ac1eeae9..2caeaac82 100644 --- a/.github/release_template.md +++ b/.github/release_template.md @@ -1,6 +1,6 @@ Download `DXRandoInstaller.exe` in the Assets section under the changelog. It is safe to update in the middle of a playthrough. -For Nvidia users, setting ultra low latency mode for DXRando.exe can help performance. +For Nvidia users, setting ultra low latency mode for DXRando.exe can help performance. Use vanilla (optionally with Lay D Denton) to get all of the Randomizer's features and the most polished experience. Our installer has an option to install Lay D Denton for you automatically. If you're having an issue with the installer program: [Manual Installation Instructions for Vanilla, Lay D Denton, GMDX, Revision, HX co-op, and Vanilla? Madder.](https://github.com/Die4Ever/deus-ex-randomizer/wiki/Installation-Instructions-and-performance-tweaks) diff --git a/.github/run-tests/action.yml b/.github/run-tests/action.yml index 32ca9ceb3..447ffd9f0 100644 --- a/.github/run-tests/action.yml +++ b/.github/run-tests/action.yml @@ -2,7 +2,7 @@ runs: using: composite steps: # we don't really care what python version we have, but maybe in the future - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.8' cache: 'pip' # caching pip dependencies @@ -10,135 +10,6 @@ runs: - run: pip3 install -r installer/requirements.txt 2>&1 shell: bash - # download launchers - - run: mkdir installer/3rdParty - shell: bash - # https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/tree/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/Alternative%20EXEs - - run: >- - curl -Lo installer/3rdParty/KentieDeusExe.exe - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/Alternative%20EXEs/Kentie's%20DeusExe.exe" - shell: bash - - run: >- - curl -Lo installer/3rdParty/DeusExe.u - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/DeusExe.u" - shell: bash - - - run: >- - curl -Lo installer/3rdParty/Launch.exe - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/Alternative%20EXEs/Launch.exe" - shell: bash - - # download D3D9 - - run: >- - curl -Lo installer/3rdParty/D3D9Drv.dll - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.dll" - shell: bash - #- run: >- - # curl -Lo installer/3rdParty/D3D9Drv.hut - # "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.hut" - # shell: bash - #- run: >- - # curl -Lo installer/3rdParty/D3D9Drv.int - # "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.int" - # shell: bash - - # download and extract OpenGL 2.0 https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/tree/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/CommunityUpdateFileArchiveDXPC/OpenGL - - run: >- - curl -Lo dxglr21.zip - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/CommunityUpdateFileArchiveDXPC/OpenGL/dxglr21.zip" - shell: bash - - run: unzip dxglr21.zip - shell: bash - - run: cp OpenGLDrv.dll installer/3rdParty/OpenGLDrv.dll - shell: bash - - # download D3D10 stuff - - run: mkdir installer/3rdParty/d3d10drv - shell: bash - - - run: >- - curl -Lo installer/3rdParty/D3D10Drv.int - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D10Drv.int" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv.dll - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv.dll" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/common.fxh - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/common.fxh" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/complexsurface.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/complexsurface.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/finalpass.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/finalpass.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/firstpass.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/firstpass.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/fogsurface.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/fogsurface.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/gouraudpolygon.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/gouraudpolygon.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/hdr.original.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/hdr%20(original).fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/hdr.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/hdr.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/polyflags.fxh - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/polyflags.fxh" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/postprocessing.fxh - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/postprocessing.fxh" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/states.fxh - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/states.fxh" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/tile.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/tile.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/unreal_pom.fx - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/unreal_pom.fx" - shell: bash - - run: >- - curl -Lo installer/3rdParty/d3d10drv/unrealpool.fxh - "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/unrealpool.fxh" - shell: bash - - # LDDP minimal install - - run: >- - curl -Lo installer/3rdParty/FemJC.u - "https://github.com/LayDDentonProject/Lay-D-Denton-Project/releases/download/v1.1/FemJC.u" - shell: bash - - # download DXVK 32bit, the extracted folder has the version number in it like dxvk-2.3 - - run: >- - curl -Lo dxvk.tar.gz - "https://github.com/doitsujin/dxvk/releases/download/v2.3/dxvk-2.3.tar.gz" - shell: bash - - run: tar -xf dxvk.tar.gz - shell: bash - - run: mkdir installer/3rdParty/dxvk/ - shell: bash - - run: cp dxvk-*/x32/* installer/3rdParty/dxvk/ - shell: bash - # check syntax and run tests - run: python3 -m compileall -q . 2>&1 shell: bash @@ -146,42 +17,24 @@ runs: shell: bash - name: Build - run: pyinstaller --clean installer/installer.spec + run: python3 installer/build.py shell: bash - - run: du -ha dist + - run: du -ha installer/dist shell: bash - - run: cat build/installer/warn-installer.txt + - run: cat installer/build/installer/warn-installer.txt shell: bash # small test, use timeouts because on windows the GUI can catch errors and a dialog box will freeze the program - - run: timeout 30 ./dist/DXRandoInstaller --version --verbose 2>&1 + - run: timeout 30 ./installer/dist/DXRandoInstaller --version --verbose 2>&1 shell: bash - - run: timeout 30 ./dist/BingoViewer --version 2>&1 + - run: timeout 30 ./installer/dist/BingoViewer --version 2>&1 shell: bash - # zip it up - # - if: runner.os == 'Windows' - # run: Compress-Archive -Path ./* -Destination DXRando.zip - # working-directory: ./dist/DXRando/ - # shell: pwsh - # - if: runner.os == 'Windows' - # run: Compress-Archive -Path ./* -Destination BingoViewer.zip - # working-directory: ./dist/BingoViewer/ - # shell: pwsh - # - if: runner.os != 'Windows' - # run: zip -r9 DXRando.zip . - # working-directory: ./dist/DXRando - # shell: bash - # - if: runner.os != 'Windows' - # run: zip -r9 BingoViewer.zip . - # working-directory: ./dist/BingoViewer - # shell: bash - # make sure we got everything - run: find installer/3rdParty/ shell: bash - - run: find dist/ + - run: find installer/dist/ shell: bash - - run: ls -lah dist/ + - run: ls -lah installer/dist/ shell: bash diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml index b6094142e..7f193aa7e 100644 --- a/.github/workflows/commit.yml +++ b/.github/workflows/commit.yml @@ -8,27 +8,27 @@ jobs: runs-on: windows-latest steps: - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/run-tests - name: Upload Installer - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: DXRando - path: dist/DXRandoInstaller.exe + path: installer/dist/DXRandoInstaller.exe - name: Upload installer warnings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: installerwarnings.txt - path: build/installer/warn-installer.txt + path: installer/build/installer/warn-installer.txt - name: Upload Bingo Viewer - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: BingoViewer - path: dist/BingoViewer.exe + path: installer/dist/BingoViewer.exe linux: runs-on: ubuntu-latest @@ -37,7 +37,7 @@ jobs: shell: bash steps: - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: sudo apt-get update -y - run: sudo apt-get install -y python3-tk idle3 binutils @@ -45,19 +45,19 @@ jobs: - uses: ./.github/run-tests - name: Upload Installer - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: DXRando-linux - path: dist/DXRandoInstaller + path: installer/dist/DXRandoInstaller - name: Upload installer warnings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: installerwarningslinux.txt - path: build/installer/warn-installer.txt + path: installer/build/installer/warn-installer.txt - name: Upload Bingo Viewer - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: BingoViewer-linux - path: dist/BingoViewer + path: installer/dist/BingoViewer diff --git a/.github/workflows/release-installer.yml b/.github/workflows/release-installer.yml index 01f693855..a429bd7e9 100644 --- a/.github/workflows/release-installer.yml +++ b/.github/workflows/release-installer.yml @@ -9,7 +9,7 @@ jobs: runs-on: windows-latest steps: - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/run-tests @@ -18,7 +18,7 @@ jobs: uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: dist/DXRandoInstaller.exe + file: installer/dist/DXRandoInstaller.exe asset_name: DXRandoInstaller.exe tag: ${{ github.ref }} @@ -27,7 +27,7 @@ jobs: uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: dist/BingoViewer.exe + file: installer/dist/BingoViewer.exe asset_name: BingoViewer.exe tag: ${{ github.ref }} @@ -38,7 +38,7 @@ jobs: shell: bash steps: - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: sudo apt-get update -y - run: sudo apt-get install -y python3-tk idle3 binutils @@ -50,7 +50,7 @@ jobs: uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: dist/DXRandoInstaller + file: installer/dist/DXRandoInstaller asset_name: DXRandoInstaller-Linux tag: ${{ github.ref }} @@ -59,6 +59,6 @@ jobs: uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: dist/BingoViewer + file: installer/dist/BingoViewer asset_name: BingoViewer-Linux tag: ${{ github.ref }} diff --git a/DXRBalance/DeusEx/Classes/AugBallistic.uc b/DXRBalance/DeusEx/Classes/AugBallistic.uc new file mode 100644 index 000000000..950ee04e4 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugBallistic.uc @@ -0,0 +1,6 @@ +class DXRAugBallistic injects AugBallistic; + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugCombat.uc b/DXRBalance/DeusEx/Classes/AugCombat.uc new file mode 100644 index 000000000..9eedef63e --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugCombat.uc @@ -0,0 +1,29 @@ +class DXRAugCombat injects AugCombat; + +simulated function TickUse() +{ + local DeusExWeapon weapon; + local DeusExDecoration deco; + local DeusExMover mover; + + weapon = DeusExWeapon(Player.inHand); + if(weapon == None || !weapon.bHandToHand) + return; + if(weapon.GetStateName() != 'NormalFire') + return; + + deco = DeusExDecoration(Player.FrobTarget); + if(deco != None && deco.minDamageThreshold <=1 && deco.HitPoints <= 10) + return; + + mover = DeusExMover(Player.FrobTarget); + if(mover != None && mover.minDamageThreshold <= 1 && mover.doorStrength < 0.1) + return; + + Super.TickUse(); +} + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugDefense.uc b/DXRBalance/DeusEx/Classes/AugDefense.uc new file mode 100644 index 000000000..1209cb05d --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugDefense.uc @@ -0,0 +1,127 @@ +class DXRAugDefense injects AugDefense; + +// ------------------------------------------------------------------------------ +// FindNearestProjectile() +// DEUS_EX AMSD Exported to a function since it also needs to exist in the client +// TriggerDefenseAugHUD; +// DXRando: ignore bStuck projectiles, we can't do this in the super because we need it to return the 2nd closest projectile if there is a stuck one +// ------------------------------------------------------------------------------ + +simulated function DeusExProjectile FindNearestProjectile() +{ + local DeusExProjectile proj, minproj; + local float dist, mindist; + local bool bValidProj; + + minproj = None; + mindist = 999999; + foreach AllActors(class'DeusExProjectile', proj) + { + if (Level.NetMode != NM_Standalone) + bValidProj = !proj.bIgnoresNanoDefense; + else + bValidProj = (!proj.IsA('Cloud') && !proj.IsA('Tracer') && !proj.IsA('GreaselSpit') && !proj.IsA('GraySpit')); + + if (!bValidProj) continue; + if (proj.bStuck) continue; + + // make sure we don't own it + if (proj.Owner != Player) + { + // MBCODE : If team game, don't blow up teammates projectiles + if (!((TeamDMGame(Player.DXGame) != None) && (TeamDMGame(Player.DXGame).ArePlayersAllied(DeusExPlayer(proj.Owner),Player)))) + { + // make sure it's moving fast enough + if (VSize(proj.Velocity) > 100) + { + dist = VSize(Player.Location - proj.Location); + if (dist < mindist) + { + mindist = dist; + minproj = proj; + } + } + } + } + } + + if(minproj != None) { + TickUse(); + } + + return minproj; +} + +// DXRando: just reduce the volume on the sounds lol +state Active +{ + function Timer() + { + local DeusExProjectile minproj; + local float mindist; + + minproj = None; + + // DEUS_EX AMSD Multiplayer check + if (Player == None) + { + SetTimer(0.1,False); + return; + } + + // In multiplayer propagate a sound that will let others know their in an aggressive defense field + // with range slightly greater than the current level value of the aug + if ( (Level.NetMode != NM_Standalone) && ( Level.Timeseconds > defenseSoundTime )) + { + Player.PlaySound(Sound'AugDefenseOn', SLOT_Interact, 1.0, ,(LevelValues[CurrentLevel]*1.33), 0.75); + defenseSoundTime = Level.Timeseconds + defenseSoundDelay; + } + + //DEUS_EX AMSD Exported to function call for duplication in multiplayer. + minproj = FindNearestProjectile(); + + // if we have a valid projectile, send it to the aug display window + if (minproj != None) + { + bDefenseActive = True; + mindist = VSize(Player.Location - minproj.Location); + + // DEUS_EX AMSD In multiplayer, let the client turn his HUD on here. + // In singleplayer, turn it on normally. + if (Level.Netmode != NM_Standalone) + TriggerDefenseAugHUD(); + else + { + SetDefenseAugStatus(True,CurrentLevel,minproj); + } + + // play a warning sound + Player.PlaySound(sound'GEPGunLock', SLOT_None, 0.5,,, 2.0); + + if (mindist < LevelValues[CurrentLevel]) + { + minproj.bAggressiveExploded=True; + minproj.Explode(minproj.Location, vect(0,0,1)); + Player.PlaySound(sound'ProdFire', SLOT_None,,,, 2.0); + } + } + else + { + if ((Level.NetMode == NM_Standalone) || (bDefenseActive)) + SetDefenseAugStatus(False,CurrentLevel,None); + bDefenseActive = false; + } + } + +Begin: + SetTimer(0.1, True); +} + + +// vanilla is mpEnergyDrain=35, EnergyRate=10, vanilla AugBallistic is mpEnergyDrain=90, EnergyRate=60 +defaultproperties +{ + bAutomatic=true + mpEnergyDrain=60.000000 + EnergyRate=30.000000 +} diff --git a/DXRBalance/DeusEx/Classes/AugDisplayWindow.uc b/DXRBalance/DeusEx/Classes/AugDisplayWindow.uc index ff3049013..5bbbd8909 100644 --- a/DXRBalance/DeusEx/Classes/AugDisplayWindow.uc +++ b/DXRBalance/DeusEx/Classes/AugDisplayWindow.uc @@ -215,41 +215,50 @@ function DrawBlinder(GC gc, Actor A) } } -function #var(prefix)Teleporter TraceTeleporter(float checkDist, out vector HitLocation) +function Actor TraceHoverHint(float checkDist) { - local Actor target; - local Vector HitLoc, HitNormal, StartTrace, EndTrace; + local Actor target; + local Vector HitLoc, HitNormal, StartTrace, EndTrace; + local DXRHoverHint hoverHint; + local float dist; - target = None; + target = None; - // figure out how far ahead we should trace - StartTrace = Player.Location; - EndTrace = Player.Location + (Vector(Player.ViewRotation) * checkDist); + // figure out how far ahead we should trace + StartTrace = Player.Location; + EndTrace = Player.Location + (Vector(Player.ViewRotation) * checkDist); - // adjust for the eye height - StartTrace.Z += Player.BaseEyeHeight; - EndTrace.Z += Player.BaseEyeHeight; + // adjust for the eye height + StartTrace.Z += Player.BaseEyeHeight; + EndTrace.Z += Player.BaseEyeHeight; - // find the object that we are looking at - foreach Player.TraceActors(class'Actor', target, HitLoc, HitNormal, EndTrace, StartTrace){ + // find the object that we are looking at + foreach Player.TraceActors(class'Actor', target, HitLoc, HitNormal, EndTrace, StartTrace){ if (target == Player.CarriedDecoration){ continue; } else if (Player.IsFrobbable(target)){ return None; - } else if (target.bHidden){ + } else if (DXRHoverHint(target) != None){ + hoverHint = DXRHoverHint(target); + if (hoverHint.ShouldSelfDestruct()){ + hoverHint.Destroy(); + continue; + } + dist = VSize(player.Location-hoverHint.Location); + if (hoverHint.ShouldDisplay(dist)==False){ + continue; + } + break; + } else if (Teleporter(target) != None && !target.bHidden) { + break; + } else if (target.bHidden) { continue; } else { break; } } - if (#var(prefix)Teleporter(target)!=None) - { - HitLocation = HitLoc; - return #var(prefix)Teleporter(target); - } - - return None; + return target; } function string formatMapName(string mapName) @@ -282,12 +291,13 @@ function string formatMapName(string mapName) function DrawTargetAugmentation(GC gc) { local Weapon oldWeapon; + local Actor target; local #var(prefix)Teleporter tgtTeleporter; + local DXRHoverHint hoverHint; local vector AimLocation; local string str,teleDest; local float x,y,h,w, boxCX,boxCY; local DynamicTeleporter dynTele; - local int show_teleporters; gc.SetFont(Font'FontMenuSmall_DS'); //This font is so much better for everything @@ -298,9 +308,9 @@ function DrawTargetAugmentation(GC gc) Player.Weapon = oldWeapon; // check 500 feet in front of the player - show_teleporters = int(Player.ConsoleCommand("get #var(package).MenuChoice_ShowTeleporters show_teleporters")); - if(show_teleporters > 1) { - tgtTeleporter = TraceTeleporter(8000,AimLocation); + target = TraceHoverHint(8000); + if(class'MenuChoice_ShowTeleporters'.default.show_teleporters > 1) { + tgtTeleporter = #var(prefix)Teleporter(target); } // display teleporter destinations @@ -327,6 +337,20 @@ function DrawTargetAugmentation(GC gc) gc.DrawText(x, y, w, h, str); } + //Look for any hover hints + hoverHint = DXRHoverHint(target); + if (hoverHint!=None){ + ConvertVectorToCoordinates(hoverHint.Location, boxCX, boxCY); + + str = hoverHint.GetHintText(); + gc.SetTextColor(colWhite); + gc.GetTextExtent(0, w, h, str); + x = boxCX - w/2; + y=boxCY; + + gc.DrawText(x, y, w, h, str); + } + //Font is immediately changed after DrawTargetAugmentation gets called, //So not necessary to "change it back" to the old font diff --git a/DXRBalance/DeusEx/Classes/AugEMP.uc b/DXRBalance/DeusEx/Classes/AugEMP.uc new file mode 100644 index 000000000..ec52376f7 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugEMP.uc @@ -0,0 +1,6 @@ +class DXRAugEMP injects AugEMP; + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugEnviro.uc b/DXRBalance/DeusEx/Classes/AugEnviro.uc new file mode 100644 index 000000000..a2b5a1a68 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugEnviro.uc @@ -0,0 +1,6 @@ +class DXRAugEnviro injects AugEnviro; + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugHeartLung.uc b/DXRBalance/DeusEx/Classes/AugHeartLung.uc new file mode 100644 index 000000000..4df14a251 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugHeartLung.uc @@ -0,0 +1,6 @@ +class DXRAugHeartLung injects AugHeartLung; + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugPower.uc b/DXRBalance/DeusEx/Classes/AugPower.uc new file mode 100644 index 000000000..5c2539490 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugPower.uc @@ -0,0 +1,23 @@ +class DXRAugPower injects AugPower; + +simulated function SetAutomatic() +{ + Super.SetAutomatic(); + + // HACK: a little wonky if you change the setting mid-game, but otherwise works + energyRate = default.energyRate; + if(class'MenuChoice_AutoAugs'.default.enabled) { + bAlwaysActive = default.bAlwaysActive; + if(bAlwaysActive) { + energyRate = 0; + } + } + else { + bAlwaysActive = false; + } +} + +defaultproperties +{ + bAlwaysActive=true +} diff --git a/DXRBalance/DeusEx/Classes/AugShield.uc b/DXRBalance/DeusEx/Classes/AugShield.uc new file mode 100644 index 000000000..f3245b6c1 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugShield.uc @@ -0,0 +1,6 @@ +class DXRAugShield injects AugShield; + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugTarget.uc b/DXRBalance/DeusEx/Classes/AugTarget.uc new file mode 100644 index 000000000..3cff975e4 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/AugTarget.uc @@ -0,0 +1,16 @@ +class DXRAugTarget injects AugTarget; + +simulated function TickUse() +{ + if(DeusExRootWindow(Player.rootWindow).winCount > 0) + return; // don't tick while reading item descriptions + if (Player.inHand!=None && DeusExWeapon(Player.inHand)!=None && DeusExWeapon(Player.inHand).bHandToHand && (DeusExWeapon(Player.inHand).ProjectileClass == None)){ + return; // don't tick for melee + } + Super.TickUse(); +} + +defaultproperties +{ + bAutomatic=true +} diff --git a/DXRBalance/DeusEx/Classes/AugmentationManager.uc b/DXRBalance/DeusEx/Classes/AugmentationManager.uc index 46c45de7c..fa56ceaf2 100644 --- a/DXRBalance/DeusEx/Classes/AugmentationManager.uc +++ b/DXRBalance/DeusEx/Classes/AugmentationManager.uc @@ -8,12 +8,34 @@ function DeactivateAll() anAug = FirstAug; while(anAug != None) { - if (anAug.bIsActive && anAug.GetEnergyRate() > 0) + if (anAug.bIsActive && anAug.GetEnergyRate() > 0 && !anAug.bAutomatic && !anAug.bAlwaysActive) anAug.Deactivate(); anAug = anAug.next; } } +simulated function int NumAugsActive() +{ + local Augmentation anAug; + local int count; + + if (player == None) + return 0; + + count = 0; + for(anAug = FirstAug; anAug != None; anAug = anAug.next) + { + if (anAug.bHasIt && anAug.bIsActive && !anAug.bAlwaysActive) { + if(anAug.bAutomatic && !anAug.IsTicked()) { + continue; + } + count++; + } + } + + return count; +} + function Augmentation GetAugByKey(int keyNum) { local Augmentation anAug; @@ -47,3 +69,89 @@ simulated function Augmentation GetAug(class AugClass) return None; } + +// ---------------------------------------------------------------------- +// GetAugLevelValue() +// +// takes a class instead of being called by actual augmentation, modified for automatic augs +// ---------------------------------------------------------------------- + +simulated function float GetAugLevelValue(class AugClass) +{ + local Augmentation anAug; + local float retval; + + retval = 0; + + anAug = FirstAug; + while(anAug != None) + { + if (anAug.Class == augClass) + { + if (anAug.bHasIt && anAug.bIsActive) { + anAug.TickUse(); + if(Player.Energy <= 0 && anAug.bAutomatic) { + return -1.0; + } else { + return anAug.LevelValues[anAug.CurrentLevel]; + } + } + else + return -1.0; + } + + anAug = anAug.next; + } + + return -1.0; +} + +// ---------------------------------------------------------------------- +// CalcEnergyUse() +// +// Calculates energy use for all active augmentations, modified for automatic power recirc +// ---------------------------------------------------------------------- + +simulated function Float CalcEnergyUse(float deltaTime) +{ + local float f, energyUse, energyMult; + local Augmentation anAug, augBoost; + local bool bBoosting; + + energyUse = 0; + energyMult = 1.0; + + anAug = FirstAug; + while(anAug != None) + { + if (AugPower(anAug) != None && anAug.bHasIt) + energyMult = anAug.LevelValues[anAug.CurrentLevel]; + + if (anAug.bHasIt && anAug.bIsActive) + { + if (AugHeartLung(anAug) != None) { + augBoost = AnAug; + } + f = ((anAug.GetEnergyRate()/60) * deltaTime); + if(f > 0 && anAug.bBoosted) { + bBoosting = true; + } + energyUse += f; + } + anAug = anAug.next; + } + + if(bBoosting) { + f = (augBoost.GetEnergyRate()/60) * deltaTime;// check if it wasn't using energy yet + augBoost.TickUse(); + if(f == 0) { // add in its energy usage if this is the first tick + f = (augBoost.GetEnergyRate()/60) * deltaTime; + energyUse += f; + } + } + + // check for the power augmentation + energyUse *= energyMult; + + return energyUse; +} diff --git a/DXRBalance/DeusEx/Classes/BalancePlayer.uc b/DXRBalance/DeusEx/Classes/BalancePlayer.uc index 1b540bfad..da0e3ff3f 100644 --- a/DXRBalance/DeusEx/Classes/BalancePlayer.uc +++ b/DXRBalance/DeusEx/Classes/BalancePlayer.uc @@ -254,6 +254,10 @@ function bool DXReduceDamage(int Damage, name damageType, vector hitLocation, ou adjustedDamage = Int(newDamage);// adjustedDamage is our out param + if(damageType == 'TearGas' && adjustedDamage*2 >= HealthTorso) { + adjustedDamage = (HealthTorso - 1)/2; // TearGas can't kill you, torso takes *2 damage + } + return bReduced; } @@ -456,7 +460,7 @@ exec function ActivateAugmentation(int num) return; anAug = AugmentationSystem.GetAugByKey(num); - if (Energy == 0 && anAug.GetEnergyRate() > 0) + if (Energy == 0 && anAug.GetEnergyRate() > 0 && !anAug.bAutomatic) { ClientMessage(EnergyDepleted); PlaySound(AugmentationSystem.FirstAug.DeactivateSound, SLOT_None); diff --git a/DXRBalance/DeusEx/Classes/BalanceWeaponShuriken.uc b/DXRBalance/DeusEx/Classes/BalanceWeaponShuriken.uc index 76a3a7d28..e1898d513 100644 --- a/DXRBalance/DeusEx/Classes/BalanceWeaponShuriken.uc +++ b/DXRBalance/DeusEx/Classes/BalanceWeaponShuriken.uc @@ -61,7 +61,7 @@ function CheckSkill() player = DeusExPlayer(Owner); if( player != None ) { - ShotTime = default.ShotTime * (1+GetWeaponSkill()); + anim_speed = default.anim_speed * (1+GetWeaponSkill()); } } diff --git a/DXRBalance/DeusEx/Classes/DeusExMover.uc b/DXRBalance/DeusEx/Classes/DeusExMover.uc index 072c72831..02c4a78f1 100644 --- a/DXRBalance/DeusEx/Classes/DeusExMover.uc +++ b/DXRBalance/DeusEx/Classes/DeusExMover.uc @@ -77,7 +77,7 @@ function Frob(Actor Frobber, Inventory frobWith) { local bool show_keys; - show_keys = bool(DeusExPlayer(Frobber).ConsoleCommand("get DeusEx.MenuChoice_ShowKeys enabled")); + show_keys = class'MenuChoice_ShowKeys'.default.enabled; //If trying to lockpick a door that you have the key for... if (show_keys && !bDone && frobWith != None && KeyIDNeeded != '') diff --git a/DXRBalance/DeusEx/Classes/WeaponRifle.uc b/DXRBalance/DeusEx/Classes/WeaponRifle.uc new file mode 100644 index 000000000..16b4a36a6 --- /dev/null +++ b/DXRBalance/DeusEx/Classes/WeaponRifle.uc @@ -0,0 +1,10 @@ +class DXRWeaponRifle injects WeaponRifle; + +// vanilla is shottime=1.5, reloadcount=6, reloadtime=1 (inherited from DeusExWeapon), TODO: maybe bCanHaveModReloadCount=False? +defaultproperties +{ + ShotTime=1 + bHasMuzzleFlash=True + ReloadCount=1 + ReloadTime=1 +} diff --git a/DXRCore/DeusEx/Classes/DXRActorsBase.uc b/DXRCore/DeusEx/Classes/DXRActorsBase.uc index 10e8bbb1c..49af3c8bf 100644 --- a/DXRCore/DeusEx/Classes/DXRActorsBase.uc +++ b/DXRCore/DeusEx/Classes/DXRActorsBase.uc @@ -86,12 +86,41 @@ static function bool IsRobot(class a) return ClassIsChildOf(a, class'Robot'); } -static function bool IsCritter(Actor a) +static function bool IsCombatRobot(class a) { - if( #var(prefix)CleanerBot(a) != None ) return true; - if( #var(prefix)MedicalBot(a) != None || #var(prefix)RepairBot(a) != None || Merchant(a) != None ) return true; - if( #var(prefix)Animal(a) == None ) return false; - return #var(prefix)Doberman(a) == None && #var(prefix)Gray(a) == None && #var(prefix)Greasel(a) == None && #var(prefix)Karkian(a) == None; + return + IsRobot(a) && + !ClassIsChildOf(a, class'#var(prefix)MedicalBot') && + !ClassIsChildOf(a, class'#var(prefix)RepairBot') && + !ClassIsChildOf(a, class'#var(prefix)CleanerBot'); +} + +static function bool IsCombatAnimal(class a) +{ + return + ClassIsChildOf(a, class'#var(prefix)Animal') && ( + ClassIsChildOf(a, class'#var(prefix)Doberman') || + ClassIsChildOf(a, class'#var(prefix)Gray') || + ClassIsChildOf(a, class'#var(prefix)Greasel') || + ClassIsChildOf(a, class'#var(prefix)Karkian') + ); +} + +// Returns True if the class is an animal that never starts as an enemy +static function bool IsCritter(class a) +{ + return ClassIsChildOf(a, class'#var(prefix)Animal') && !IsCombatAnimal(a); +} + +// Returns True if the class ever starts as an enemy, even if some instances don't +static function bool IsCombatPawn(class a) +{ + return IsHuman(a) || IsCombatRobot(a) || IsCombatAnimal(a); +} + +static function bool IsRelevantPawn(class a) +{ + return IsCombatPawn(a) && !ClassIsChildOf(a, class'Merchant'); } function bool IsInitialEnemy(ScriptedPawn p) @@ -652,13 +681,21 @@ function Actor ReplaceActor(Actor oldactor, string newclassstring) function Conversation GetConversation(Name conName) { - local Conversation c; + local Conversation c, fallback; + local Name fallbackConName; + + fallbackConName=''; if (dxr.flagbase.GetBool('LDDPJCIsFemale')) { + fallbackConName=conName; conName = StringToName("FemJC"$string(conName)); } foreach AllObjects(class'Conversation', c) { if( c.conName == conName ) return c; + if( c.conName == fallbackConName ) fallback = c; } + + if (fallbackConName!='') return fallback; + return None; } @@ -964,6 +1001,12 @@ function bool CheckFreeSpace(out vector loc, float radius, float height) return true; } +function ZoneInfo GetZone(vector loc) +{ + SetLocation(loc); + return Region.Zone; +} + function vector GetRandomPosition(optional vector target, optional float mindist, optional float maxdist, optional bool allowWater, optional bool allowPain, optional bool allowSky) { local PathNode temp[4096]; diff --git a/DXRCore/DeusEx/Classes/DXRBase.uc b/DXRCore/DeusEx/Classes/DXRBase.uc index 4258159ef..5f7e46c80 100644 --- a/DXRCore/DeusEx/Classes/DXRBase.uc +++ b/DXRCore/DeusEx/Classes/DXRBase.uc @@ -99,17 +99,26 @@ simulated event Destroyed() simulated function int SetSeed(coerce string name) { - return dxr.SetSeed( dxr.Crc(dxr.seed $ dxr.localURL $ name) ); + local int oldseed; + oldseed = dxr.SetSeed( dxr.Crc(dxr.seed $ dxr.localURL $ name) ); + dxr.rngraw();// advance the rng + return oldseed; } simulated function int SetGlobalSeed(coerce string name) { - return dxr.SetSeed( dxr.seed + dxr.Crc(name) ); + local int oldseed; + oldseed = dxr.SetSeed( dxr.seed + dxr.Crc(name) ); + dxr.rngraw();// advance the rng + return oldseed; } simulated function int BranchSeed(coerce string name) { - return dxr.SetSeed( dxr.Crc(dxr.seed $ name $ dxr.tseed) ); + local int oldseed; + oldseed = dxr.SetSeed( dxr.Crc(dxr.seed $ name $ dxr.tseed) ); + dxr.rngraw();// advance the rng + return oldseed; } simulated function int ReapplySeed(int oldSeed) @@ -119,7 +128,11 @@ simulated function int ReapplySeed(int oldSeed) simulated function int rng(int max) { - return dxr.rng(max); + local float f; + // divide by 1 less than 0xFFFFFF, so that it's never the max and we don't have to worry about rounding + f = float(dxr.rngraw())/16777214.0; + f *= float(max); + return int(f); } simulated function bool rngb() @@ -128,9 +141,9 @@ simulated function bool rngb() } simulated function float rngf() -{// 0 to 1.0 +{// 0 to 1.0 inclusive local float f; - f = float(dxr.rng(100001))/100000.0; + f = float(dxr.rngraw())/16777215.0;// 0xFFFFFF because rngraw does a right shift by 8 bits //l("rngf() "$f); return f; } diff --git a/DXRCore/DeusEx/Classes/DXRInfo.uc b/DXRCore/DeusEx/Classes/DXRInfo.uc index 93e12a43e..929ef734e 100644 --- a/DXRCore/DeusEx/Classes/DXRInfo.uc +++ b/DXRCore/DeusEx/Classes/DXRInfo.uc @@ -176,7 +176,7 @@ static function int _SystemTime(LevelInfo Level) function bool IsAprilFools() { // April Fools! (and the 2nd, because of Jesus_On_Wheels' timezone, and the Randothon 2023 schedule) - return Level.Month == 4 && (Level.Day == 1 || Level.Day == 2); + return Level.Month == 4 && (Level.Day == 1 || Level.Day == 2) && class'MenuChoice_ToggleMemes'.default.enabled && !GetDXR().flags.IsReducedRando(); } final function int SystemTime() diff --git a/DXRCore/DeusEx/Classes/DXRMenuBase.uc b/DXRCore/DeusEx/Classes/DXRMenuBase.uc index a4022ef29..19d411ee3 100644 --- a/DXRCore/DeusEx/Classes/DXRMenuBase.uc +++ b/DXRCore/DeusEx/Classes/DXRMenuBase.uc @@ -20,9 +20,10 @@ var bool bHelpAlwaysOn; var int id; var bool writing; -//var int numwnds; + var Window wnds[128]; var String labels[128]; +var int hide_labels[128]; var String helptexts[128]; var DXRando dxr; @@ -96,26 +97,26 @@ event Init(DXRando d) StyleChanged(); } -function DXRFlags InitFlags() +function DXRFlags GetFlags() { if( flags != None ) return flags; - log(Self$".InitFlags calling InitDxr"); - InitDxr(); + log(Self$".GetFlags calling GetDxr"); + GetDxr(); return flags; } -function DXRando InitDxr() +function DXRando GetDxr() { if( dxr != None ) return dxr; - log("InitDxr has player "$player); + log("GetDxr has player "$player); #ifdef vmd // vmd loads a separate level for character creation foreach player.AllActors(class'DXRando', dxr) { break; } #else dxr = player.Spawn(class'DXRando', None); #endif - log("InitDxr got "$dxr); + log("GetDxr got "$dxr); dxr.CrcInit(); #ifdef hx //player() = HXHuman(player); @@ -130,7 +131,7 @@ function DXRando InitDxr() return dxr; } -function _InvokeNewGameScreen(float difficulty, DXRando dxr) +function _InvokeNewGameScreen(float difficulty) { local DXRMenuScreenNewGame newGame; #ifdef vmd @@ -150,10 +151,11 @@ function _InvokeNewGameScreen(float difficulty, DXRando dxr) } } -function NewMenuItem(string label, string helptext) +function NewMenuItem(string label, string helptext, optional bool hide_label) { id++; labels[id] = label; + hide_labels[id] = int(hide_label); helptexts[id] = helptext; log(Self @ label); } @@ -193,6 +195,7 @@ function NewGroup(string text) function bool EnumOption(string label, int value, optional out int output) { local int i; + local string s; if( writing ) { if( label == GetEnumValue(id) ) { @@ -211,7 +214,8 @@ function bool EnumOption(string label, int value, optional out int output) } } if ( enums[id].btn == None ) { - enums[id].btn = CreateEnum(id, labels[id], helptexts[id], enums[id]); + if(hide_labels[id]==0) s = labels[id]; + enums[id].btn = CreateEnum(id, s, helptexts[id], enums[id]); wnds[id] = enums[id].btn; } log(self$" EnumOption: "$label$" == "$value$" compared to default of "$output); @@ -226,6 +230,7 @@ function bool EnumOption(string label, int value, optional out int output) function bool EnumOptionString(string label, string value, optional out string output) { local int i; + local string s; if( writing ) { if( label == GetEnumValue(id) ) { @@ -244,7 +249,8 @@ function bool EnumOptionString(string label, string value, optional out string o } } if ( enums[id].btn == None ) { - enums[id].btn = CreateEnum(id, labels[id], helptexts[id], enums[id]); + if(hide_labels[id]==0) s = labels[id]; + enums[id].btn = CreateEnum(id, s, helptexts[id], enums[id]); wnds[id] = enums[id].btn; } log(self$" EnumOptionString: "$label$" == "$value$" compared to default of "$output); @@ -258,11 +264,14 @@ function bool EnumOptionString(string label, string value, optional out string o function string EditBox(string value, string pattern) { + local string s; + if( writing ) { return MenuUIEditWindow(wnds[id]).GetText(); } else { if ( wnds[id] == None ) { - wnds[id] = CreateEdit(id, labels[id], helptexts[id], pattern, value); + if(hide_labels[id]==0) s = labels[id]; + wnds[id] = CreateEdit(id, s, helptexts[id], pattern, value); } } return value; @@ -271,6 +280,8 @@ function string EditBox(string value, string pattern) function int Slider(out int value, int min, int max) { local int output; + local string s; + if( writing ) { output = GetSliderValue(MenuUIEditWindow(wnds[id])); output = Clamp(output, min, max); @@ -279,7 +290,8 @@ function int Slider(out int value, int min, int max) return value; } else { if ( wnds[id] == None ) { - wnds[id] = CreateSlider(id, labels[id], helptexts[id], value, min, max); + if(hide_labels[id]==0) s = labels[id]; + wnds[id] = CreateSlider(id, s, helptexts[id], value, min, max); } else { MenuUIEditWindow(wnds[id]).SetText(string(value)); } @@ -501,6 +513,7 @@ function MenuUIActionButtonWindow CreateBtn(int row, string label, string helpte if( label != "" ) CreateLabel(row, label); btn = MenuUIActionButtonWindow(controlsParent.NewChild(Class'MenuUIActionButtonWindow')); + btn.SetWordWrap(false); btn.SetButtonText(text); if( label == "" ) { coords = GetCoords(row, 0); @@ -570,41 +583,59 @@ function bool ButtonActivatedRight( Window buttonPressed ) function bool CheckClickEnum( Window buttonPressed, optional bool rightClick ) { - local EnumBtn e; local int i; for(i=0; i 5) { + list = DXREnumList(root.InvokeUIScreen(class'DXREnumList')); + list.Init(self, iEnum, labels[iEnum], helptexts[iEnum], e.values[e.value]); + for(i=0; i 0) { + EnumOption("Random", f.settings.starting_map, f.settings.starting_map); + } + else if(EnumOption("Random", -1)) { f.settings.starting_map = class'DXRStartMap'.static.ChooseRandomStartMap(f, 0); } @@ -145,7 +142,7 @@ function BindControls(optional string action) NewGroup("Doors and Keys"); - NewMenuItem("", "Which doors to provide additional options to get through."); + NewMenuItem("Doors To Change", "Which doors to provide additional options to get through.", true); doors_type = f.settings.doorsmode & 0xffffff00;// keep it in the high bytes doors_exclusivity = f.settings.doorsmode & 0xff;// just the low byte @@ -170,7 +167,7 @@ function BindControls(optional string action) doorsdestructible = f.settings.doorsdestructible * 100 / doors_probability; doorspickable = f.settings.doorspickable * 100 / doors_probability; doors_option = doors_exclusivity $ ";" $ doorsdestructible $ ";" $ doorspickable; - NewMenuItem("", "What to do with those doors."); + NewMenuItem("Door Adjustments", "What to do with those doors.", true); EnumOptionString("Breakable or Pickable", f.doormutuallyexclusive $";50;50", doors_option); EnumOptionString("Breakable & Pickable", f.doormutuallyinclusive $";100;100", doors_option); EnumOptionString("Breakable and/or Pickable", f.doorindependent $";100;100", doors_option); @@ -263,6 +260,7 @@ function BindControls(optional string action) EnumOption("Reroll Skill Costs Every Mission", 1, f.settings.skills_reroll_missions); EnumOption("Reroll Skill Costs Every 2 Missions", 2, f.settings.skills_reroll_missions); EnumOption("Reroll Skill Costs Every 3 Missions", 3, f.settings.skills_reroll_missions); + EnumOption("Reroll Skill Costs Every 4 Missions", 4, f.settings.skills_reroll_missions); EnumOption("Reroll Skill Costs Every 5 Missions", 5, f.settings.skills_reroll_missions); NewMenuItem("", "Predictability of skill level cost scaling."); @@ -358,13 +356,15 @@ function BindControls(optional string action) NewMenuItem("Weapons Removed", "Number of weapons removed per loop."); Slider(f.newgameplus_num_removed_weapons, 0, 18); - if( action == "NEXT" ) _InvokeNewGameScreen(combatDifficulty, InitDxr()); - if( action == "RANDOMIZE" ) RandomizeOptions(f); + if( action == "NEXT" ) _InvokeNewGameScreen(combatDifficulty); + if( action == "RANDOMIZE" ) RandomizeOptions(); } -function RandomizeOptions(DXRFlags f) +function RandomizeOptions() { local int scrollPos; + local DXRFlags f; + f = GetFlags(); scrollPos = winScroll.vScale.GetTickPosition(); diff --git a/DXRCore/DeusEx/Classes/DXRVersion.uc b/DXRCore/DeusEx/Classes/DXRVersion.uc index 824ae4420..9f7ae5d55 100644 --- a/DXRCore/DeusEx/Classes/DXRVersion.uc +++ b/DXRCore/DeusEx/Classes/DXRVersion.uc @@ -3,9 +3,14 @@ class DXRVersion extends Info; simulated static function CurrentVersion(optional out int major, optional out int minor, optional out int patch, optional out int build) { major=2; - minor=5; - patch=6; - build=6;//build can't be higher than 99 + minor=6; + patch=0; + build=3;//build can't be higher than 99 +} + +simulated static function bool VersionIsStable() +{ + return false; } simulated static function string VersionString(optional bool full) @@ -13,7 +18,7 @@ simulated static function string VersionString(optional bool full) local int major,minor,patch,build; local string status; - status = ""; + status = "Beta"; if(status!="") { status = " " $ status; @@ -23,6 +28,10 @@ simulated static function string VersionString(optional bool full) return VersionToString(major, minor, patch, build, full) $ status; } +////// +////// you probably don't need to touch the stuff below +////// + simulated static function int VersionToInt(int major, int minor, int patch, int build) { local int ret; @@ -55,10 +64,3 @@ simulated static function bool VersionOlderThan(int config_version, int major, i { return config_version < VersionToInt(major, minor, patch, build); } - -simulated static function bool VersionIsStable() -{ - local string v; - v = VersionString(); - return InStr(v, "Alpha")==-1 && InStr(v, "Beta")==-1; -} diff --git a/DXRCore/DeusEx/Classes/DXRando.uc b/DXRCore/DeusEx/Classes/DXRando.uc index 93485108b..25d9e3932 100644 --- a/DXRCore/DeusEx/Classes/DXRando.uc +++ b/DXRCore/DeusEx/Classes/DXRando.uc @@ -17,6 +17,7 @@ var transient int num_modules; var config string modules_to_load[47];// 1 less than the modules array, because we always load the DXRFlags module var config int config_version; +var config int rando_beaten; var transient bool runPostFirstEntry; var transient bool bTickEnabled;// bTickEnabled is just for DXRandoTests to inspect @@ -75,7 +76,6 @@ function SetdxInfo(DeusExLevelInfo i) CrcInit(); ClearModules(); LoadFlagsModule(); - CheckConfig(); Enable('Tick'); bTickEnabled = true; @@ -108,6 +108,7 @@ function DXRInit() } l("found flagbase: "$flagbase$", Player: "$Player); + CheckConfig(); flags.InitCoordsMult();// for some reason flags is loaded too early and doesn't have the new map url flags.LoadFlags(); LoadModules(); @@ -118,6 +119,11 @@ function CheckConfig() { local int i; + if( VersionOlderThan(config_version, 2,6,0,1) ) { + rando_beaten = 0; + player.bAskedToTrain = false; + player.SaveConfig(); + } if( VersionOlderThan(config_version, 2,5,4,2) ) { for(i=0; i < ArrayCount(modules_to_load); i++) { modules_to_load[i] = ""; @@ -409,6 +415,7 @@ function DXRTick(float deltaTime) } else if(runPostFirstEntry) { + SetSeed( Crc(seed $ localURL $ " PostFirstEntry") ); for(i=0; i>> is right shift and filling the left with 0s, >> shifts but keeps the sign // this means we don't need abs, which is a float function anyways return imod((tseed >>> 8), max); } +simulated final function int rngraw() +{ + tseed = gen1 * tseed * 5 + gen2 + (tseed/5) * 3; + // in unrealscript >>> is right shift and filling the left with 0s, >> shifts but keeps the sign + // this means we don't need abs, which is a float function anyways + return (tseed >>> 8); +} + // ============================================================================ // CrcInit https://web.archive.org/web/20181105143221/http://unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/crc32.html diff --git a/DXRFixes/DeusEx/Classes/ActorDisplayWindow.uc b/DXRFixes/DeusEx/Classes/ActorDisplayWindow.uc index a4a40a04f..1ef6303ee 100644 --- a/DXRFixes/DeusEx/Classes/ActorDisplayWindow.uc +++ b/DXRFixes/DeusEx/Classes/ActorDisplayWindow.uc @@ -4,6 +4,44 @@ var Font textfont; var bool bShowHidden; var bool bUserFriendlyNames; +var bool bShowCustom; +var string customAttrib; +var bool bShowInventory; +var string nameFilter; +var bool bLimitRadius; +var int actorRadius; +var bool bShowTagEvent; +var bool bShowTagConnections; +var bool bShowEventConnections; + +function SetActorRadius(string newRadius) +{ + actorRadius = int(newRadius); +} + +function int GetActorRadius(){ + return actorRadius; +} + +function LimitRadius(bool bLimit) +{ + bLimitRadius = bLimit; +} + +function Bool IsRadiusLimited() +{ + return bLimitRadius; +} + +function SetNameFilter(string newFilter) +{ + nameFilter = newFilter; +} + +function String GetNameFilter(){ + return nameFilter; +} + function SetViewClass(Class newViewClass) { Super.SetViewClass(newViewClass); @@ -18,6 +56,65 @@ function ShowLOS(bool bShow) bUserFriendlyNames = false; } +function ShowCustom(bool bShow) +{ + bShowCustom = bShow; +} + +function Bool IsCustomVisible() +{ + return bShowCustom; +} + +function SetCustomAttrib(string newCustomAttrib) +{ + customAttrib = newCustomAttrib; +} + +function String GetCustomAttrib(){ + return customAttrib; +} + +function bool IsInventoryVisible() +{ + return bShowInventory; +} + +function ShowInventory(bool bShow) +{ + bShowInventory = bShow; +} + +function bool IsTagEventVisible() +{ + return bShowTagEvent; +} + +function ShowTagEvent(bool bShow) +{ + bShowTagEvent = bShow; +} + +function bool IsTagConnsVisible() +{ + return bShowTagConnections; +} + +function ShowTagConns(bool bShow) +{ + bShowTagConnections = bShow; +} + +function bool IsEventConnsVisible() +{ + return bShowEventConnections; +} + +function ShowEventConns(bool bShow) +{ + bShowEventConnections = bShow; +} + function string GetActorName(Actor a) { local string str; @@ -49,6 +146,22 @@ function string GetActorName(Actor a) return str; } +function DrawColourLine(GC gc, vector point1, vector point2, int r, int g, int b) +{ + local float fromX, fromY; + local float toX, toY; + + gc.SetStyle(DSTY_Normal); + if (ConvertVectorToCoordinates(point1, fromX, fromY) && ConvertVectorToCoordinates(point2, toX, toY)) + { + gc.SetTileColorRGB(r, g, b); + DrawPoint(gc, fromX, fromY); + DrawPoint(gc, toX, toY); + gc.SetTileColorRGB(r, g, b); + Interpolate(gc, fromX, fromY, toX, toY, 8); + } +} + //I just want to change the font :( function DrawWindow(GC gc) { @@ -60,7 +173,8 @@ function DrawWindow(GC gc) local vector tVect; local vector cVect; local PlayerPawnExt player; - local Actor trackActor; + local Actor trackActor, otherActor; + local Dispatcher disp; local ScriptedPawn trackPawn; local bool bValid; local bool bPointValid; @@ -79,25 +193,45 @@ function DrawWindow(GC gc) local float barWidth; local DeusExMover dxMover; local vector minpos, maxpos; + local Inventory item; + local name filter; + local int radius; + local class classToShow; minpos = vect(999999, 999999, 999999); maxpos = vect(-999999, -999999, -999999); Super(Window).DrawWindow(gc); - if (viewClass == None) + if (viewClass == None && nameFilter=="") return; + classToShow = viewClass; + if (nameFilter!="" && classToShow==None){ + classToShow=class'Actor'; + } + player = GetPlayerPawn(); if (bShowMesh) gc.ClearZ(); - foreach player.AllActors(viewClass, trackActor) + if (nameFilter!="") + filter = StringToName(nameFilter); + + radius = 999999; + if (bLimitRadius){ + radius = actorRadius; + } + + foreach player.RadiusActors(classToShow, trackActor,radius,player.Location) { if(!bShowHidden && trackActor.bHidden) continue;// DXRando: for spoilers buttons + if (filter!='' && filter!=trackActor.Name) + continue; + dxMover = DeusExMover(trackActor); cVect.X = trackActor.CollisionRadius; cVect.Y = trackActor.CollisionRadius; @@ -246,10 +380,66 @@ function DrawWindow(GC gc) } str = ""; + if (bShowTagEvent || bShowData) + { + str = str $ "|cf50aff"; + str = str $ "Tag: "$trackActor.Tag $ CR(); + + disp = Dispatcher(trackActor); + + str = str $ "Event: "$trackActor.Event $ CR(); + if (disp!=None){ + for(i=0;iDeusExCarcass:item="$item ); - + //player.ClientMessage(self@"=> item="$item); nextItem = item.Inventory; + if(TryLootItem(player, item)) + bFoundSomething = true; + item = nextItem; + } + until ((item == None) || (item == startItem)); + } - bPickedItemUp = False; + //log(" bFoundSomething = " $ bFoundSomething); - if (item.IsA('Ammo')) - { - // Only let the player pick up ammo that's already in a weapon - DeleteInventory(item); - item.Destroy(); - item = None; - } - else if ( (item.IsA('DeusExWeapon')) ) - { - // Any weapons have their ammo set to a random number of rounds (1-4) - // unless it's a grenade, in which case we only want to dole out one. - // DEUS_EX AMSD In multiplayer, give everything away. - W = DeusExWeapon(item); - - // Grenades and LAMs always pickup 1 - if (W.IsA('WeaponNanoVirusGrenade') || - W.IsA('WeaponGasGrenade') || - W.IsA('WeaponEMPGrenade') || - W.IsA('WeaponLAM')) - W.PickupAmmoCount = 1; - } + if (!bFoundSomething) + P.ClientMessage(msgEmpty); - if(item == None) { - item = nextItem; - continue; - } + if ((player != None) && (Level.Netmode != NM_Standalone)) + { + player.ClientMessage(Sprintf(msgRecharged, 25)); - bFoundSomething = True; + PlaySound(sound'BioElectricHiss', SLOT_None,,, 256); - if (item.IsA('NanoKey')) - { - if (player != None) - { - player.PickupNanoKey(NanoKey(item)); - AddReceivedItem(player, item, 1); - DeleteInventory(item); - item.Destroy(); - item = None; - } - bPickedItemUp = True; - } - else if (item.IsA('Credits')) // I hate special cases - { - if (player != None) - { - AddReceivedItem(player, item, Credits(item).numCredits); - player.Credits += Credits(item).numCredits; - P.ClientMessage(Sprintf(Credits(item).msgCreditsAdded, Credits(item).numCredits)); - DeleteInventory(item); - item.Destroy(); - item = None; - } - bPickedItemUp = True; - } - else if (item.IsA('DeusExWeapon')) // I *really* hate special cases - { - // Okay, check to see if the player already has this weapon. If so, - // then just give the ammo and not the weapon. Otherwise give - // the weapon normally. - W = DeusExWeapon(player.FindInventoryType(item.Class)); - - // If the player already has this item in his inventory, piece of cake, - // we just give him the ammo. However, if the Weapon is *not* in the - // player's inventory, first check to see if there's room for it. If so, - // then we'll give it to him normally. If there's *NO* room, then we - // want to give the player the AMMO only (as if the player already had - // the weapon). - - if ((W != None) || ((W == None) && (!player.FindInventorySlot(item, True)))) - { - // Don't bother with this is there's no ammo - if ((Weapon(item).AmmoType != None) && (Weapon(item).AmmoType.AmmoAmount > 0)) - { - AmmoType = Ammo(player.FindInventoryType(Weapon(item).AmmoName)); - - if ((AmmoType != None) && (AmmoType.AmmoAmount < AmmoType.MaxAmmo)) - { - AmmoType.AddAmmo(Weapon(item).PickupAmmoCount); - AddReceivedItem(player, AmmoType, Weapon(item).PickupAmmoCount); - - // Update the ammo display on the object belt - player.UpdateAmmoBeltText(AmmoType); - - // if this is an illegal ammo type, use the weapon name to print the message - if (AmmoType.PickupViewMesh == Mesh'TestBox') - P.ClientMessage(item.PickupMessage @ item.itemArticle @ item.itemName, 'Pickup'); - else - P.ClientMessage(AmmoType.PickupMessage @ AmmoType.itemArticle @ AmmoType.itemName, 'Pickup'); - - // Mark it as 0 to prevent it from being added twice - Weapon(item).AmmoType.AmmoAmount = 0; - } - } + player.Energy += 25; + if (player.Energy > player.EnergyMax) + player.Energy = player.EnergyMax; + } - // Print a message "Cannot pickup blah blah blah" if inventory is full - // and the player can't pickup this weapon, so the player at least knows - // if he empties some inventory he can get something potentially cooler - // than he already has. - if ((W == None) && (!player.FindInventorySlot(item, True))){ - P.ClientMessage(Sprintf(Player.InventoryFull, item.itemName)); + Super(Carcass).Frob(Frobber, frobWith); - //Also toss the item out of the carcass - TossItem(item,player); - } + if ((Level.Netmode != NM_Standalone) && (Player != None)) + { + bQueuedDestroy = true; + Destroy(); + } +} - // Only destroy the weapon if the player already has it. - if (W != None) - { - // Destroy the weapon, baby! - DeleteInventory(item); - item.Destroy(); - item = None; - } +function bool TryLootItem(DeusExPlayer player, Inventory item) +{ + local ammo itemAmmo, playerAmmo, newAmmo; + local DeusExWeapon W; + local DeusExPickup invItem; + local int itemCount; + local int ammoAdded, ammoLeftover, ammoPrevious; - bPickedItemUp = True; - } - } + if (item.IsA('DeusExWeapon')) + { + // Any weapons have their ammo set to a random number of rounds (1-4) + // unless it's a grenade, in which case we only want to dole out one. + // DEUS_EX AMSD In multiplayer, give everything away. + W = DeusExWeapon(item); + + // Grenades and LAMs always pickup 1 + if (W.IsA('WeaponNanoVirusGrenade') || + W.IsA('WeaponGasGrenade') || + W.IsA('WeaponEMPGrenade') || + W.IsA('WeaponLAM')) + W.PickupAmmoCount = 1; + } - else if (item.IsA('DeusExAmmo')) - { - if (DeusExAmmo(item).AmmoAmount == 0) - bPickedItemUp = True; - } + if (item.IsA('NanoKey')) + { + player.PickupNanoKey(NanoKey(item)); + AddReceivedItem(player, item, 1); + DeleteInventory(item); + item.Destroy(); + return true; + } + + if (item.IsA('Credits')) // I hate special cases + { + AddReceivedItem(player, item, Credits(item).numCredits); + player.Credits += Credits(item).numCredits; + player.ClientMessage(Sprintf(Credits(item).msgCreditsAdded, Credits(item).numCredits)); + DeleteInventory(item); + item.Destroy(); + return true; + } - if (!bPickedItemUp) + if (item.IsA('DeusExWeapon')) // I *really* hate special cases + { + // Okay, check to see if the player already has this weapon. If so, + // then just give the ammo and not the weapon. Otherwise give + // the weapon normally. + W = DeusExWeapon(player.FindInventoryType(item.Class)); + + // If the player already has this item in his inventory, piece of cake, + // we just give him the ammo. However, if the Weapon is *not* in the + // player's inventory, first check to see if there's room for it. If so, + // then we'll give it to him normally. If there's *NO* room, then we + // want to give the player the AMMO only (as if the player already had + // the weapon). + + if (W != None || (W == None && !player.FindInventorySlot(item, True))) + { + // Don't bother with this if there's no ammo + if (Weapon(item).AmmoType != None && Weapon(item).PickupAmmoCount > 0) { - // Special case if this is a DeusExPickup(), it can have multiple copies - // and the player already has it. + playerAmmo = Ammo(player.FindInventoryType(Weapon(item).AmmoName)); - if ((item.IsA('DeusExPickup')) && (DeusExPickup(item).bCanHaveMultipleCopies) && (player.FindInventoryType(item.class) != None)) + if (playerAmmo != None && playerAmmo.AmmoAmount < playerAmmo.MaxAmmo) { - invItem = DeusExPickup(player.FindInventoryType(item.class)); - itemCount = DeusExPickup(item).numCopies; - - // Make sure the player doesn't have too many copies - if ((invItem.MaxCopies > 0) && (DeusExPickup(item).numCopies + invItem.numCopies > invItem.MaxCopies)) - { - // Give the player the max # - if ((invItem.MaxCopies - invItem.numCopies) > 0) - { - itemCount = (invItem.MaxCopies - invItem.numCopies); - DeusExPickup(item).numCopies -= itemCount; - invItem.numCopies = invItem.MaxCopies; - P.ClientMessage(invItem.PickupMessage @ invItem.itemArticle @ invItem.itemName, 'Pickup'); - AddReceivedItem(player, invItem, itemCount); - } - else - { - P.ClientMessage(Sprintf(msgCannotPickup, invItem.itemName)); - //Also toss the item out of the carcass - TossItem(item,player); + ammoAdded = Weapon(item).PickupAmmoCount; + ammoLeftover=0; + if (playerAmmo.AmmoAmount + ammoAdded > playerAmmo.MaxAmmo){ + ammoLeftover = (ammoAdded + playerAmmo.AmmoAmount) - playerAmmo.MaxAmmo; + ammoAdded = ammoAdded - ammoLeftover; + } + if (ammoLeftover > 0){ + if(playerAmmo.Default.Mesh!=LodMesh'DeusExItems.TestBox'){ + //Weapons with normal ammo that exists + newAmmo = Spawn(playerAmmo.Class,,,Location,Rotation); + newAmmo.ammoAmount = ammoLeftover; + newAmmo.Velocity = Velocity + VRand() * 280; } } + playerAmmo.AddAmmo(ammoAdded); + AddReceivedItem(player, playerAmmo, ammoAdded); + + // Update the ammo display on the object belt + player.UpdateAmmoBeltText(playerAmmo); + + // if this is an illegal ammo type, use the weapon name to print the message + if (playerAmmo.PickupViewMesh == Mesh'TestBox') + player.ClientMessage(item.PickupMessage @ item.itemArticle @ item.itemName, 'Pickup'); else - { - invItem.numCopies += itemCount; - DeleteInventory(item); + player.ClientMessage(playerAmmo.PickupMessage @ playerAmmo.itemArticle @ playerAmmo.itemName, 'Pickup'); - P.ClientMessage(invItem.PickupMessage @ invItem.itemArticle @ invItem.itemName, 'Pickup'); - AddReceivedItem(player, invItem, itemCount); - } + // Mark it as 0 to prevent it from being added twice + Weapon(item).AmmoType.AmmoAmount = 0; + Weapon(item).PickupAmmoCount = 0; } - else + else // Rando: toss the weapon just for the ammo { - // check if the pawn is allowed to pick this up - if ((P.Inventory == None) || (Level.Game.PickupQuery(P, item))) - { - DeusExPlayer(P).FrobTarget = item; - if (DeusExPlayer(P).HandleItemPickup(Item) != False) - { - DeleteInventory(item); - - // DEUS_EX AMSD Belt info isn't always getting cleaned up. Clean it up. - item.bInObjectBelt=False; - item.BeltPos=-1; - - item.SpawnCopy(P); - - // Show the item received in the ReceivedItems window and also - // display a line in the Log - AddReceivedItem(player, item, 1); - - P.ClientMessage(Item.PickupMessage @ Item.itemArticle @ Item.itemName, 'Pickup'); - PlaySound(Item.PickupSound); - } else { - TossItem(item,player); - } - } - else - { - DeleteInventory(item); - item.Destroy(); - item = None; - } + player.ClientMessage(Sprintf(player.InventoryFull, item.itemName)); + //Also toss the item out of the carcass + TossItem(item,player); + return true; } } - item = nextItem; + // Print a message "Cannot pickup blah blah blah" if inventory is full + // and the player can't pickup this weapon, so the player at least knows + // if he empties some inventory he can get something potentially cooler + // than he already has. + if (W == None && !player.FindInventorySlot(item, True)){ + player.ClientMessage(Sprintf(player.InventoryFull, item.itemName)); + + //Also toss the item out of the carcass + TossItem(item,player); + return true; + } + + // Only destroy the weapon if the player already has it + if (W != None) + { + // Destroy the weapon, baby! + DeleteInventory(item); + item.Destroy(); + } + + return true; } - until ((item == None) || (item == startItem)); } - //log(" bFoundSomething = " $ bFoundSomething); + if (item.IsA('Ammo')) + { + itemAmmo = Ammo(item); + if (!dropsAmmo || itemAmmo.AmmoAmount == 0) { + DeleteInventory(item); + item.Destroy(); + return false; + } - if (!bFoundSomething) - P.ClientMessage(msgEmpty); + playerAmmo = Ammo(player.FindInventoryType(item.class)); - if ((player != None) && (Level.Netmode != NM_Standalone)) + if (playerAmmo == None) { + ammoPrevious = 0; + } else { + ammoPrevious = playerAmmo.AmmoAmount; + } + ammoAdded = Min(itemAmmo.AmmoAmount, itemAmmo.MaxAmmo - ammoPrevious ); + ammoLeftover = itemAmmo.AmmoAmount - ammoAdded; + + if (ammoLeftover > 0) { + newAmmo = Spawn(itemAmmo.class,,, Location); + newAmmo.AmmoAmount = ammoLeftover; + newAmmo.Velocity = Velocity + VRand() * 280; // same as vanilla corpse drops + } + + if (playerAmmo == None) { + TryLootRegularItem(player, item); + } else { + playerAmmo.AddAmmo(ammoAdded); + + AddReceivedItem(player, itemAmmo, ammoAdded); + player.UpdateAmmoBeltText(playerAmmo); + if (playerAmmo.PickupViewMesh == Mesh'TestBox') { + player.ClientMessage(item.PickupMessage @ item.itemArticle @ item.itemName, 'Pickup'); + } else { + player.ClientMessage(playerAmmo.PickupMessage @ playerAmmo.itemArticle @ playerAmmo.itemName, 'Pickup'); + } + + DeleteInventory(item); + item.Destroy(); + } + + return true; + } + + // Special case if this is a DeusExPickup(), it can have multiple copies + // and the player already has it. + + if (item.IsA('DeusExPickup') && DeusExPickup(item).bCanHaveMultipleCopies && player.FindInventoryType(item.class) != None) { - player.ClientMessage(Sprintf(msgRecharged, 25)); + invItem = DeusExPickup(player.FindInventoryType(item.class)); + itemCount = DeusExPickup(item).numCopies; - PlaySound(sound'BioElectricHiss', SLOT_None,,, 256); + // Make sure the player doesn't have too many copies + if (invItem.MaxCopies > 0 && DeusExPickup(item).numCopies + invItem.numCopies > invItem.MaxCopies) + { + // Give the player the max # + if (invItem.MaxCopies - invItem.numCopies > 0) + { + itemCount = (invItem.MaxCopies - invItem.numCopies); + DeusExPickup(item).numCopies -= itemCount; + invItem.numCopies = invItem.MaxCopies; + player.ClientMessage(invItem.PickupMessage @ invItem.itemArticle @ invItem.itemName, 'Pickup'); + AddReceivedItem(player, invItem, itemCount); + } + else + { + player.ClientMessage(Sprintf(msgCannotPickup, invItem.itemName)); + //Also toss the item out of the carcass + TossItem(item,player); + } + } + else + { + invItem.numCopies += itemCount; + DeleteInventory(item); - player.Energy += 25; - if (player.Energy > player.EnergyMax) - player.Energy = player.EnergyMax; + player.ClientMessage(invItem.PickupMessage @ invItem.itemArticle @ invItem.itemName, 'Pickup'); + AddReceivedItem(player, invItem, itemCount); + } + return true; } - Super(Carcass).Frob(Frobber, frobWith); + return TryLootRegularItem(player, item); +} - if ((Level.Netmode != NM_Standalone) && (Player != None)) +function bool TryLootRegularItem(DeusExPlayer player, Inventory item) +{ + // check if the pawn is allowed to pick this up + if (player.Inventory == None || Level.Game.PickupQuery(player, item)) { - bQueuedDestroy = true; - Destroy(); + player.FrobTarget = item; + if (player.HandleItemPickup(Item) != False) + { + DeleteInventory(item); + + // DEUS_EX AMSD Belt info isn't always getting cleaned up. Clean it up. + item.bInObjectBelt=False; + item.BeltPos=-1; + + item.SpawnCopy(player); + + // Show the item received in the ReceivedItems window and also + // display a line in the Log + AddReceivedItem(player, item, 1); + + player.ClientMessage(Item.PickupMessage @ Item.itemArticle @ Item.itemName, 'Pickup'); + PlaySound(Item.PickupSound); + } else { + TossItem(item,player); + } + return true; + } + else + { + DeleteInventory(item); + item.Destroy(); + return false; } + + return false; } defaultproperties diff --git a/DXRFixes/DeusEx/Classes/DXRBartender.uc b/DXRFixes/DeusEx/Classes/DXRBartender.uc new file mode 100644 index 000000000..5655c8aa0 --- /dev/null +++ b/DXRFixes/DeusEx/Classes/DXRBartender.uc @@ -0,0 +1,16 @@ +class DXRBartender injects #var(prefix)Bartender; + +var float realLastConEndTime; + +function EndConversation() +{ + Super.EndConversation(); + realLastConEndTime = LastConEndTime; + LastConEndTime += 59.0; +} + +function Frob(actor Frobber, Inventory frobWith) +{ + LastConEndTime = realLastConEndTime; + Super.Frob(Frobber, frobWith); +} diff --git a/DXRFixes/DeusEx/Classes/DXRJordanShea.uc b/DXRFixes/DeusEx/Classes/DXRJordanShea.uc new file mode 100644 index 000000000..6b32b8089 --- /dev/null +++ b/DXRFixes/DeusEx/Classes/DXRJordanShea.uc @@ -0,0 +1,16 @@ +class DXRJordanShea injects #var(prefix)JordanShea; + +var float realLastConEndTime; + +function EndConversation() +{ + Super.EndConversation(); + realLastConEndTime = LastConEndTime; + LastConEndTime += 59.0; +} + +function Frob(actor Frobber, Inventory frobWith) +{ + LastConEndTime = realLastConEndTime; + Super.Frob(Frobber, frobWith); +} diff --git a/DXRFixes/DeusEx/Classes/FixSaveGameNegativeSpace.uc b/DXRFixes/DeusEx/Classes/FixSaveGameNegativeSpace.uc index 3fd03a84d..ed6807b6e 100644 --- a/DXRFixes/DeusEx/Classes/FixSaveGameNegativeSpace.uc +++ b/DXRFixes/DeusEx/Classes/FixSaveGameNegativeSpace.uc @@ -2,31 +2,31 @@ class FixSaveGameNegativeSpace injects MenuScreenSaveGame; function ConfirmSaveGame() { - // First check to see how much disk space we have. - // If < the minimum, then notify the user to clear some - // disk space. - if (((freeDiskSpace / 1024) < minFreeDiskSpace) && (freeDiskSpace>=0)) - { - msgBoxMode = MB_LowSpace; - root.MessageBox(DiskSpaceTitle, DiskSpaceMessage, 1, False, Self); - } - else - { + // First check to see how much disk space we have. + // If < the minimum, then notify the user to clear some + // disk space. + if (((freeDiskSpace / 1024) < minFreeDiskSpace) && (freeDiskSpace>=0)) + { + msgBoxMode = MB_LowSpace; + root.MessageBox(DiskSpaceTitle, DiskSpaceMessage, 1, False, Self); + } + else + { if (freeDiskSpace < 0) { + msgBoxMode = MB_LowSpace; + root.MessageBox(DiskSpaceTitle, "Disk Space is getting read as negative. You may want to install a launcher to fix that!", 1, False, Self); + } + + if (editRowId == newSaveRowId) + { + SaveGame(editRowId); + } + else + { + saveRowId = editRowId; msgBoxMode = MB_Overwrite; - root.MessageBox(DiskSpaceTitle, "Disk Space is getting read as negative. You may want to install a launcher to fix that!", 1, False, Self); - } else { - if (editRowId == newSaveRowId) - { - SaveGame(editRowId); - } - else - { - saveRowId = editRowId; - msgBoxMode = MB_Overwrite; - root.MessageBox( OverwriteTitle, OverwritePrompt, 0, False, Self); - } + root.MessageBox( OverwriteTitle, OverwritePrompt, 0, False, Self); } - } + } } diff --git a/DXRFixes/DeusEx/Classes/LaserTrigger.uc b/DXRFixes/DeusEx/Classes/LaserTrigger.uc new file mode 100644 index 000000000..6e5b11353 --- /dev/null +++ b/DXRFixes/DeusEx/Classes/LaserTrigger.uc @@ -0,0 +1,28 @@ +class DXRLaserTrigger injects LaserTrigger; + +function bool IsRelevant( actor Other ) +{ + if (TriggerType==TT_AnyProximity){ + if (ScriptedPawn(Other)!=None){ + return False; + } + } + return Super.IsRelevant(Other); +} + +function BeginAlarm() +{ + local Actor A; + + Super.BeginAlarm(); + + // Trigger event + if(Event != '') + foreach AllActors(class 'Actor', A, Event) + A.Trigger(Self, Pawn(emitter.HitActor)); +} + +defaultproperties +{ + bProjTarget=true +} diff --git a/DXRFixes/DeusEx/Classes/ScriptedPawn.uc b/DXRFixes/DeusEx/Classes/ScriptedPawn.uc index 68a728cc0..384ad195b 100644 --- a/DXRFixes/DeusEx/Classes/ScriptedPawn.uc +++ b/DXRFixes/DeusEx/Classes/ScriptedPawn.uc @@ -33,13 +33,12 @@ event Destroyed() function ThrowInventory(bool gibbed) { local Inventory item, nextItem; - local bool drop, melee, throw_melee; + local bool drop, melee; - throw_melee = bool(ConsoleCommand("get #var(package).MenuChoice_ThrowMelee enabled")); item = Inventory; while( item != None ) { nextItem = item.Inventory; - if(throw_melee) + if(class'MenuChoice_ThrowMelee'.default.enabled) melee = class'DXRActorsBase'.static.IsMeleeWeapon(item); drop = (item.IsA('NanoKey') && gibbed) || (melee && !gibbed) || (gibbed && item.bDisplayableInv); if( DeusExWeapon(item) != None && DeusExWeapon(item).bNativeAttack ) @@ -464,7 +463,7 @@ function UpdateFire() function Bool HasTwoHandedWeapon() { - if(bIsFemale || Mesh==LodMesh'DeusExCharacters.GM_DressShirt_S' || Mesh==LodMesh'DeusExCharacters.GM_Trench_F') + if(bIsFemale || Mesh==LodMesh'DeusExCharacters.GM_DressShirt_S' || Mesh==LodMesh'DeusExCharacters.GM_Trench_F' || Mesh==LodMesh'DeusExCharacters.GM_Scubasuit') return False; if ((Weapon != None) && (Weapon.Mass >= 30)) return True; @@ -521,8 +520,10 @@ function PrintAlliances() { local int i; log("PrintAlliances: "$alliance, name); - for(i=0; i npClass; + local DXRHoverHint hoverHint; npClass = class'#var(prefix)Newspaper'; #else local DXRInformationDevices np; @@ -41,10 +46,21 @@ function PreFirstEntryMapFixes() switch(dxr.localURL) { case "01_NYC_UNATCOISLAND": + foreach AllActors(class'#var(prefix)HarleyFilben', harley) { + harley.bImportant = true; + } //Move this Joe Greene article from inside HQ to outside on the island npClass.static.SpawnInfoDevice(self,class'#var(prefix)NewspaperOpen',vectm(7297,-3204.5,-373),rotm(0,0,0),'01_Newspaper06');//Forklift in bunker npClass.static.SpawnInfoDevice(self,class'#var(prefix)NewspaperOpen',vectm(3163,-1298,-207),rotm(0,0,0),'01_Newspaper06');//Backroom near jail + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)NYPoliceBoat',b) { + class'DXRTeleporterHoverHint'.static.Create(self, "", b.Location, b.CollisionRadius+5, b.CollisionHeight+5, exit); + break; + } + + class'GuntherWeaponMegaChoice'.static.Create(Player()); + Spawn(class'PlaceholderItem',,, vectm(2378.5,-10810.9,-857)); //Sunken Ship Spawn(class'PlaceholderItem',,, vectm(2436,-10709.4,-857)); //Sunken Ship Spawn(class'PlaceholderContainer',,, vectm(1376,-9952.5,-271)); //Harley's house @@ -95,6 +111,9 @@ function PreFirstEntryMapFixes() } } + //To change it so Manderley will brief you if you talked to Sam and Jaime (instead of actually getting equipment from Sam) + SetTimer(1.0, True); + //Spawn some placeholders for new item locations Spawn(class'PlaceholderItem',,, vectm(363.284149, 344.847, 50.32)); //Womens bathroom counter Spawn(class'PlaceholderItem',,, vectm(211.227, 348.46, 50.32)); //Mens bathroom counter @@ -110,6 +129,25 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-1187,-1154,-31)); //Behind Jail Desk Spawn(class'PlaceholderContainer',,, vectm(2384,1669,-95)); //MJ12 Door Spawn(class'PlaceholderContainer',,, vectm(-383.6,1376,273)); //JC's Office + + foreach AllActors(class'#var(prefix)HumanCivilian', hc, 'LDDPChet') { + // Chet's name is Chet + hc.bImportant = true; + } + + break; + } +} + +function TimerMapFixes() +{ + switch(dxr.localURL) + { + case "01_NYC_UNATCOHQ": + if (!dxr.flagbase.GetBool('M01ReadyForBriefing') && dxr.flagbase.GetBool('MeetCarter_Played') && dxr.flagbase.GetBool('MeetJaime_Played')){ + dxr.flagbase.SetBool('M01ReadyForBriefing',True,,999); + SetTimer(0,false); + } break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM02.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM02.uc index 1305f8c89..0c96c0827 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM02.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM02.uc @@ -14,6 +14,12 @@ function PreFirstEntryMapFixes() local #var(prefix)TAD tad; local #var(prefix)FishGenerator fg; local #var(prefix)PigeonGenerator pg; + local #var(prefix)Trigger trig; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local DXRButtonHoverHint buttonHint; + local #var(prefix)Button1 button; local bool RevisionMaps; local bool VanillaMaps; @@ -42,9 +48,11 @@ function PreFirstEntryMapFixes() t.SetCollisionSize(t.CollisionRadius*2, t.CollisionHeight*2); } } + foreach AllActors(class'#var(prefix)MapExit',exit,'Boat_Exit'){break;} foreach AllActors(class'NYPoliceBoat',b) { b.BindName = "NYPoliceBoat"; b.ConBindEvents(); + class'DXRTeleporterHoverHint'.static.Create(self, "", b.Location, b.CollisionRadius+5, b.CollisionHeight+5, exit); } foreach AllActors(class'DeusExMover', d) { if( d.Name == 'DeusExMover19' ) { @@ -83,12 +91,55 @@ function PreFirstEntryMapFixes() kp.bToggleLock=False; kp.Event='DoorToWarehouse'; + //Detach the trigger that opens the basement door when you get near it from inside + //Add a button instead + foreach AllActors(class'#var(prefix)Trigger',trig){ + if (trig.Event=='SecurityDoor'){ + trig.Event='DontDoAnything'; + break; + } + } + AddSwitch( vect(915.534,-1046.767,-117.347), rot(0, 16368, 0), 'SecurityDoor'); + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + foreach AllActors(class'#var(prefix)MapExit',exit,'ToStreet'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='ToStreet'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + class'PlaceholderEnemy'.static.Create(self,vectm(782,-1452,48)); class'PlaceholderEnemy'.static.Create(self,vectm(1508,-1373,256)); class'PlaceholderEnemy'.static.Create(self,vectm(1814,-1842,48)); class'PlaceholderEnemy'.static.Create(self,vectm(-31,-1485,48)); class'PlaceholderEnemy'.static.Create(self,vectm(1121,-1095,-144)); class'PlaceholderEnemy'.static.Create(self,vectm(467,-214,-144)); + class'PlaceholderEnemy'.static.Create(self,vectm(-1570,493,1183)); //rooftop + class'PlaceholderEnemy'.static.Create(self,vectm(681,1359,1424)); //rooftop window + class'PlaceholderEnemy'.static.Create(self,vectm(-1820,1248,1616)); //rooftop tower + class'PlaceholderEnemy'.static.Create(self,vectm(-635,1983,1768)); //rooftop chimneys + class'PlaceholderEnemy'.static.Create(self,vectm(-1847,1940,1800)); //rooftop building near elevator + class'PlaceholderEnemy'.static.Create(self,vectm(-972,765,1184)); //rooftop + class'PlaceholderEnemy'.static.Create(self,vectm(110,530,784)); //lower rooftop + class'PlaceholderEnemy'.static.Create(self,vectm(423,565,624)); //even lower rooftop + class'PlaceholderEnemy'.static.Create(self,vectm(875,712,464)); //lowest rooftop + class'PlaceholderEnemy'.static.Create(self,vectm(-5,1415,1192)); //apartment + class'PlaceholderEnemy'.static.Create(self,vectm(-2080,812,48)); //alley + class'PlaceholderEnemy'.static.Create(self,vectm(13,-718,-96)); //Warehouse sewer entrance + class'PlaceholderEnemy'.static.Create(self,vectm(-1555,2756,1584)); //Rooftops near elevator + class'PlaceholderEnemy'.static.Create(self,vectm(-1717,2177,2008)); //roof of rooftop building near elevator + class'PlaceholderEnemy'.static.Create(self,vectm(843,75,480)); //Warehouse garage roof + class'PlaceholderEnemy'.static.Create(self,vectm(1649,-1393,64),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1676,-1535,64),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1334,-1404,64),,'Shitting'); } break; case "02_NYC_HOTEL": @@ -124,6 +175,15 @@ function PreFirstEntryMapFixes() pg=Spawn(class'#var(prefix)PigeonGenerator',,, vectm(2404,-1318,-487));//Near Smuggler pg.MaxCount=3; + foreach AllActors(class'#var(prefix)MapExit',exit,'ToWarehouse'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='ToWarehouse'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + break; case "02_NYC_BAR": Spawn(class'BarDancer',,,vectm(-1475,-580,48),rotm(0,25000,0)); @@ -149,6 +209,10 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderItem',,, vectm(-3593,1620,-961)); //Schick Fume Hood Spawn(class'PlaceholderItem',,, vectm(-4264,982,-981)); //Barracks bed Spawn(class'PlaceholderItem',,, vectm(-173,850,-322)); //Guard Room Table + + class'PlaceholderEnemy'.static.Create(self,vectm(-4219,1236,-976),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-4059,976,-976),,'Sitting'); + break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc index 9f85a7ce1..bfe395e14 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc @@ -61,6 +61,11 @@ function PreFirstEntryMapFixes() local #var(prefix)WeaponModRecoil wmr; local #var(prefix)Terrorist terror; local #var(prefix)FishGenerator fg; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local #var(prefix)HumanCivilian hc; + local bool VanillaMaps; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -80,6 +85,10 @@ function PreFirstEntryMapFixes() } } + if(VanillaMaps) { + AddSwitch(vect(-4621.640137, 2902.651123, -650.285461), rot(0,0,0), 'ElevatorPhone'); + } + fg=Spawn(class'#var(prefix)FishGenerator',,, vectm(-1274,-3892,177));//Near Boat dock fg.ActiveArea=2000; @@ -155,6 +164,18 @@ function PreFirstEntryMapFixes() //Button to extend sewer platform from the other side AddSwitch( vect(-5233.946289,3601.383545,161.851822), rot(0, 16384, 0), 'MoveableBridge'); + + class'PlaceholderEnemy'.static.Create(self,vectm(1273,809,48),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1384,805,48),,'Shitting'); + + class'PlaceholderEnemy'.static.Create(self,vectm(-326,1494,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-422,1393,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(352,1510,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(451,1397,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1154,170,224),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1044,94,224),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(928,546,224),,'Sitting'); + } break; @@ -179,6 +200,14 @@ function PreFirstEntryMapFixes() tele.SetCollisionSize(tele.CollisionRadius, tele.CollisionHeight + 10); } } + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + class'PlaceholderEnemy'.static.Create(self,vectm(2994,3406,256),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2887,3410,256),,'Shitting'); } break; @@ -215,6 +244,9 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderItem',,, vectm(661,1000,107)); //other side pillar stairs Spawn(class'PlaceholderItem',,, vectm(-919,-94,11)); //Other side ramp Spawn(class'PlaceholderItem',,, vectm(1222,88,11)); //Near start, but bad side + + class'PlaceholderEnemy'.static.Create(self,vectm(4030,-2958,112),,'Shitting'); + } break; @@ -249,6 +281,12 @@ function PreFirstEntryMapFixes() unatco.UnfamiliarName = "Corporal Lloyd"; } } + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; case "03_NYC_UNATCOHQ": FixUNATCOCarterCloset(); @@ -283,6 +321,12 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-1187,-1154,-31)); //Behind Jail Desk Spawn(class'PlaceholderContainer',,, vectm(2384,1669,-95)); //MJ12 Door Spawn(class'PlaceholderContainer',,, vectm(-383.6,1376,273)); //JC's Office + + foreach AllActors(class'#var(prefix)HumanCivilian', hc, 'LDDPChet') { + // Chet's name is Chet + hc.bImportant = true; + } + break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc index c8f4e21af..7f2a39f8b 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc @@ -25,12 +25,13 @@ function PreTravelMapFixes() function PreFirstEntryMapFixes() { - local FlagTrigger ft; + local #var(prefix)FlagTrigger ft; + local #var(prefix)DatalinkTrigger dt; local OrdersTrigger ot; local SkillAwardTrigger st; local #var(prefix)BoxSmall b; local #var(prefix)HackableDevices hd; - local #var(prefix)UNATCOTroop lloyd; + local #var(prefix)UNATCOTroop lloyd, troop; local #var(prefix)AutoTurret turret; local #var(prefix)ControlPanel panel; local #var(prefix)LaserTrigger laser; @@ -41,7 +42,13 @@ function PreFirstEntryMapFixes() local #var(DeusExPrefix)Mover door; local #var(prefix)NanoKey key; local #var(prefix)PigeonGenerator pg; + local #var(prefix)GuntherHermann gunther; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local DXRMapVariants mapvariants; local bool VanillaMaps; + local #var(prefix)HumanCivilian hc; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -53,7 +60,7 @@ function PreFirstEntryMapFixes() if( ot.Orders == 'Leaving' ) ot.Orders = 'Seeking'; } - foreach AllActors(class'FlagTrigger', ft) { + foreach AllActors(class'#var(prefix)FlagTrigger', ft) { if( ft.Event == 'PaulOutaHere' ) ft.Destroy(); } @@ -69,6 +76,7 @@ function PreFirstEntryMapFixes() } } #endif + class'GilbertWeaponMegaChoice'.static.Create(Player()); if (VanillaMaps){ Spawn(class'#var(prefix)Binoculars',,, vectm(-610.374573,-3221.998779,94.160065)); //Paul's bedside table @@ -95,28 +103,33 @@ function PreFirstEntryMapFixes() break; case "04_NYC_NSFHQ": - foreach AllActors(class'#var(prefix)AutoTurret', turret) { - turret.Event = ''; - turret.Destroy(); - } - foreach AllActors(class'#var(prefix)ControlPanel', panel) { - panel.Event = ''; - panel.Destroy(); - } - foreach AllActors(class'#var(prefix)LaserTrigger', laser) { - laser.Event = ''; - laser.Destroy(); - } - foreach AllActors(class'#var(prefix)Containers', c) { - if(#var(prefix)BoxLarge(c) != None || #var(prefix)BoxSmall(c) != None - || #var(prefix)CrateUnbreakableLarge(c) != None || #var(prefix)CrateUnbreakableMed(c) != None) - { - c.Event = ''; - c.Destroy(); + if(!dxr.flags.IsReducedRando()) { + foreach AllActors(class'#var(prefix)AutoTurret', turret) { + turret.Event = ''; + turret.Destroy(); + } + foreach AllActors(class'#var(prefix)ControlPanel', panel) { + panel.Event = ''; + panel.Destroy(); + } + foreach AllActors(class'#var(prefix)LaserTrigger', laser) { + laser.Event = ''; + laser.Destroy(); + } + foreach AllActors(class'#var(prefix)Containers', c) { + if(#var(prefix)BoxLarge(c) != None || #var(prefix)BoxSmall(c) != None + || #var(prefix)CrateUnbreakableLarge(c) != None || #var(prefix)CrateUnbreakableMed(c) != None) + { + c.Event = ''; + c.Destroy(); + } + } + foreach AllActors(class'#var(prefix)HackableDevices', hd) { + hd.hackStrength /= 3.0; + } + foreach AllActors(class'#var(prefix)UNATCOTroop',troop,'UNATCOGateGuard'){ + troop.Destroy(); } - } - foreach AllActors(class'#var(prefix)HackableDevices', hd) { - hd.hackStrength /= 3.0; } foreach AllActors(class'#var(DeusExPrefix)Mover',door,'ExitDoor'){ @@ -134,15 +147,55 @@ function PreFirstEntryMapFixes() //Button to open basement hatch from inside AddSwitch( vect(-558.536499,-426.806915,-16.069786), rot(0, 0, 0), 'BasementHatch'); + foreach AllActors(class'#var(prefix)UNATCOTroop', troop) { + if (troop.BindName=="UNATCOGateGuard" || + troop.BindName=="TrooperTalking1" || + troop.BindName=="TrooperTalking2" ) + { + troop.bIsSecretGoal=True; + } + } + if (VanillaMaps){ //One window on the roof doesn't have a FlagTrigger to make UNATCO hate you. Add it back. - ft = Spawn(class'FlagTrigger',,,vectm(233.9,693.64,1016.1)); + ft = Spawn(class'#var(prefix)FlagTrigger',, 'SendingSignal3',vectm(233.9,693.64,1016.1)); ft.SetCollisionSize(128,40); ft.bSetFlag=False; ft.bTrigger=True; ft.FlagName='NSFSignalSent'; ft.flagValue=True; ft.Event='UNATCOHatesPlayer'; + + Spawn(class'PlaceholderItem',,, vectm(110.869766, 337.987732, 1034.306885)); // next to vanilla transmitter computer + class'PlaceholderEnemy'.static.Create(self,vectm(485,1286,64),,'Shitting',,'UNATCO',1); + class'PlaceholderEnemy'.static.Create(self,vectm(672,1268,64),,'Shitting',,'UNATCO',1); + class'PlaceholderEnemy'.static.Create(self,vectm(-435,9,-208),,,,'UNATCO',1); + class'PlaceholderEnemy'.static.Create(self,vectm(1486,1375,-208),,,,'UNATCO',1); + class'PlaceholderEnemy'.static.Create(self,vectm(-438,1120,544),,,,'UNATCO',1); + class'PlaceholderEnemy'.static.Create(self,vectm(-89,1261,304),,,,'UNATCO',1); + } + + if(VanillaMaps && dxr.flags.settings.goals > 0) { + foreach AllActors(class'#var(prefix)DatalinkTrigger', dt, 'DataLinkTrigger') { + if(dt.datalinkTag != 'DL_SimonsPissed') continue; + dt.Tag = 'SendingSignal3'; + break; + } + + foreach AllActors(class'#var(prefix)FlagTrigger', ft, 'SendingSignal') { + ft.Tag = 'SendingSignal2'; + ft.Event = 'SendingSignal3'; + ft.bTrigger = true; + // spawn intermediate trigger to check flag + ft = Spawn(class'#var(prefix)FlagTrigger',, 'SendingSignal', ft.Location+vect(10,10,10)); + ft.SetCollision(false,false,false); + ft.bSetFlag=False; + ft.bTrigger=True; + ft.FlagName='CanSendSignal'; + ft.flagValue=True; + ft.Event='SendingSignal2'; + break; + } } break; @@ -156,6 +209,13 @@ function PreFirstEntryMapFixes() lloyd.bImportant = true; } } + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; case "04_NYC_UNATCOHQ": FixUNATCOCarterCloset(); @@ -183,6 +243,12 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-1187,-1154,-31)); //Behind Jail Desk Spawn(class'PlaceholderContainer',,, vectm(2384,1669,-95)); //MJ12 Door Spawn(class'PlaceholderContainer',,, vectm(-383.6,1376,273)); //JC's Office + + foreach AllActors(class'#var(prefix)HumanCivilian', hc, 'LDDPChet') { + // Chet's name is Chet + hc.bImportant = true; + } + break; case "04_NYC_BATTERYPARK": @@ -194,6 +260,12 @@ function PreFirstEntryMapFixes() //Let the player free! It's already possible to break outside of them, so just get rid of them. bp.bBlockPlayers=false; } + foreach AllActors(class'DXRMapVariants', mapvariants) { break; } + foreach AllActors(class'#var(prefix)GuntherHermann', gunther) { + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, class'DXRMapInfo'.static.GetTeleporterName(mapvariants.VaryMap("05_NYC_UNATCOMJ12Lab"),""), gunther.Location, gunther.CollisionRadius+5, gunther.CollisionHeight+5); + hoverHint.SetBaseActor(gunther); + } + break; case "04_NYC_BAR": Spawn(class'BarDancer',,,vectm(-1440,340,48),rotm(0,-16348,0)); @@ -201,25 +273,21 @@ function PreFirstEntryMapFixes() case "04_NYC_STREET": pg=Spawn(class'#var(prefix)PigeonGenerator',,, vectm(-1849,286,-487));//Near free clinic pg.MaxCount=3; + + foreach AllActors(class'#var(prefix)FlagTrigger', ft) { + if (ft.event == 'MainGates') { + // Increase the radius to extend around the corner for NSFHQ starts + ft.SetCollisionSize(7000.0, ft.CollisionHeight); + } + } + break; } } function PostFirstEntryMapFixes() { - local DeusExMover m; - FixUNATCORetinalScanner(); - - switch(dxr.localURL) { - case "04_NYC_NSFHQ": - // no cheating! - foreach AllActors(class'DeusExMover', m, 'SignalComputerDoorOpen') { - m.bBreakable = false; - m.bPickable = false; - } - break; - } } function AnyEntryMapFixes() @@ -336,7 +404,7 @@ function NYC_04_CheckPaulRaid() foreach AllActors(class'ScriptedPawn', p) { if( PaulDenton(p) != None ) continue; - if( IsCritter(p) ) continue; + if( !IsRelevantPawn(p.class) ) continue; if( p.bHidden ) continue; if( p.GetAllianceType('Player') != ALLIANCE_Hostile ) continue; p.bStasis = false; diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc index 634d2d194..d8f38a900 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc @@ -35,6 +35,12 @@ function PreFirstEntryMapFixes() local #var(prefix)RatGenerator rg; local #var(prefix)PigeonGenerator pg; local #var(prefix)NanoKey k; + local #var(prefix)AnnaNavarre anna; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local #var(prefix)HumanCivilian hc; + local DXREnemies dxre; local int i; local bool VanillaMaps; @@ -73,6 +79,13 @@ function PreFirstEntryMapFixes() mj12.BindName = "MJ12CellguardRick"; } + //Anna hates weapons (why?) in Revision, but can't hurt to set it for all mods + //If she sees you pull out a weapon with this set, she goes hostile and starts + //running around + foreach AllActors(class'#var(prefix)AnnaNavarre',anna){ + anna.bHateWeapon=False; + } + if (VanillaMaps){ foreach AllActors(class'DeusExMover',dxm){ if (dxm.Name=='DeusExMover34'){ @@ -81,6 +94,12 @@ function PreFirstEntryMapFixes() dxm.KeyIDNeeded='Cabinet'; } } + + class'PlaceholderEnemy'.static.Create(self,vectm(-5066,1368,208),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-4981,1521,208),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-3417,1369,208),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(479,3502,-144),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1439,1162,-144),,'Sitting'); } break; @@ -137,6 +156,22 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-1187,-1154,-31)); //Behind Jail Desk Spawn(class'PlaceholderContainer',,, vectm(2384,1669,-95)); //MJ12 Door Spawn(class'PlaceholderContainer',,, vectm(-383.6,1376,273)); //JC's Office + + class'PlaceholderEnemy'.static.Create(self,vectm(144,176,40),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(229,1828,288),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-1451,654,608),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-1662,786,608),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(164,-424,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-16,-609,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-182,-859,-16),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1153,1024,-16),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1885,-279,-16),,'Sitting'); + + } + + foreach AllActors(class'#var(prefix)HumanCivilian', hc, 'LDDPChet') { + // Chet's name is Chet + hc.bImportant = true; } break; @@ -168,6 +203,12 @@ function PreFirstEntryMapFixes() pg=Spawn(class'#var(prefix)PigeonGenerator',,, vectm(-4685,2875,-124));//Outside the front door pg.MaxCount=3; + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc index 14edda5ad..a512593d4 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc @@ -43,6 +43,14 @@ function PreFirstEntryMapFixes() local #var(prefix)FlagTrigger ft; local #var(prefix)OrdersTrigger ot; local #var(prefix)TriadRedArrow bouncer; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local #var(prefix)Button1 button; + local #var(prefix)BeamTrigger bt; + local #var(prefix)LaserTrigger lt; + local DXRButtonHoverHint buttonHint; + local DXRHoverHint hoverHint; + local bool VanillaMaps; #ifdef injections @@ -83,10 +91,21 @@ function PreFirstEntryMapFixes() break; } + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + class'PlaceholderEnemy'.static.Create(self,vectm(769,-520,144)); class'PlaceholderEnemy'.static.Create(self,vectm(1620,-87,144)); class'PlaceholderEnemy'.static.Create(self,vectm(-844,-359,816)); class'PlaceholderEnemy'.static.Create(self,vectm(2036,122,816)); + class'PlaceholderEnemy'.static.Create(self,vectm(755,-364,144),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(877,-360,144),,'Shitting'); } break; @@ -110,6 +129,11 @@ function PreFirstEntryMapFixes() } break; case "06_HONGKONG_WANCHAI_MARKET": + if (VanillaMaps) { + // button to get out of Tong's base + AddSwitch( vect(1433.658936, 273.360352, -167.364777), rot(0, 16384, 0), 'Basement_door' ); + } + // fallthrough case "06_HONGKONG_WANCHAI_COMPOUND": foreach AllActors(class'Actor', a) { @@ -143,6 +167,45 @@ function PreFirstEntryMapFixes() break; } } + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'outro_trigger'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + if (VanillaMaps){ + //Elevator to Versalife + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors01'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors01'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + //Elevator to Helibase + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + } + + foreach AllActors(class'#var(prefix)ScriptedPawn',p){ + if (p.BindName=="MarketKid"){ + p.Tag = 'MarketKid'; + } + } + + foreach AllActors(class'#var(prefix)OrdersTrigger',ot){ + if (ot.Tag=='KidWanders' || ot.Tag=='KidGoesToNewsStand' || ot.Tag=='KidGoesToLumPath'){ + ot.Event='MarketKid'; + } + } break; case "06_HONGKONG_WANCHAI_STREET": @@ -212,15 +275,40 @@ function PreFirstEntryMapFixes() pad.bHidden = False; } - foreach AllActors(class'#var(prefix)Greasel',g){ + foreach AllActors(class'#var(prefix)Greasel', g){ g.bImportant = True; - g.BindName="JerryTheVentGreasel"; - g.FamiliarName = "Jerry the Vent Greasel"; - g.UnfamiliarName = "Jerry the Vent Greasel"; + g.BindName = "BoringLabGreasel"; + //The other ones are tagged as Dogs + if (Tag=='Greasel'){ + g.BindName="JerryTheVentGreasel"; + g.FamiliarName = "Jerry the Vent Greasel"; + g.UnfamiliarName = "Jerry the Vent Greasel"; + } } SpawnDatacubeImage(vectm(-1194.700195,-789.460266,-750.628357), rotm(0,0,0),Class'DeusEx.Image15_GrayDisection'); + //Elevator to Versalife + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors01'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors01'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + //Elevator to Level 2 + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + Spawn(class'PlaceholderItem',,, vectm(-1.95,1223.1,810.3)); //Table over entrance Spawn(class'PlaceholderItem',,, vectm(1022.24,-1344.15,450.3)); //Bathroom counter Spawn(class'PlaceholderItem',,, vectm(1519.6,-1251,442.3)); //Conference room side table @@ -249,6 +337,21 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-894,1465,-607)); //Barracks empty side lower Spawn(class'PlaceholderContainer',,, vectm(-442,-494,-607)); //Near vanilla ROM encoding computer + class'PlaceholderEnemy'.static.Create(self,vectm(903,-1363,432),,'Shitting',, 'security', 1); + class'PlaceholderEnemy'.static.Create(self,vectm(709,-1378,432),,'Shitting',, 'security', 1); + class'PlaceholderEnemy'.static.Create(self,vectm(-1101,2364,-592),,'Shitting',, 'security', 1); + class'PlaceholderEnemy'.static.Create(self,vectm(-1368,2350,-592),,'Shitting',, 'security', 1); + class'PlaceholderEnemy'.static.Create(self,vectm(85,1351,816),,'Sitting',, 'security', 1); //Upper lookout room + class'PlaceholderEnemy'.static.Create(self,vectm(53,1173,816),,'Sitting',, 'security', 1); //Upper Lookout room + class'PlaceholderEnemy'.static.Create(self,vectm(-1470,-540,-80),,,, 'security', 1); //Catwalk to level 2 lab elevator + class'PlaceholderEnemy'.static.Create(self,vectm(-1121,-185,-752),,,, 'security', 1); //Between zappy things in lab + class'PlaceholderEnemy'.static.Create(self,vectm(-829,2811,-592),,,, 'security', 1); //In the shower + class'PlaceholderEnemy'.static.Create(self,vectm(626,-632,-80),,,, 'security', 1); //Upper level of ROM encoding room + class'PlaceholderEnemy'.static.Create(self,vectm(-33,155,176),,,, 'security', 1); //Main hall + class'PlaceholderEnemy'.static.Create(self,vectm(-8,-715,176),,,, 'security', 1); //Main hall + class'PlaceholderEnemy'.static.Create(self,vectm(1345,-1092,431),,,, 'security', 1); //Conference room + class'PlaceholderEnemy'.static.Create(self,vectm(-629,1718,-592),,,, 'security', 1); //Barracks + break; case "06_HONGKONG_WANCHAI_UNDERWORLD": @@ -356,6 +459,27 @@ function PreFirstEntryMapFixes() } } + //Elevator to Market + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors01'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors01'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + //Elevator to MJ12 Lab + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + Spawn(class'PlaceholderItem',,, vectm(12.36,1556.5,-51)); //1st floor front cube Spawn(class'PlaceholderItem',,, vectm(643.5,2139.7,-51.7)); //1st floor back cube Spawn(class'PlaceholderItem',,, vectm(210.94,2062.23,204.3)); //2nd floor front cube @@ -366,6 +490,37 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderItem',,, vectm(-836.9,850.3,-9.7)); //Reception desk back break; case "06_HONGKONG_STORAGE": + //Make sure Maggie always has her MaggieChowShowdown conversation with you if she's here. + //Mark her as having Fled as you enter the lower section of the UC (This prevents her conversations from the apartment from playing) + //Remove the requirement for M07Briefing_Played for the conversation (Done in AnyEntry) + ft= Spawn(class'#var(prefix)FlagTrigger',,, vectm(-2.5,-3,-848)); + ft.SetCollisionSize(1000,5); + ft.FlagName='MaggieFled'; + ft.bTrigger=False; + ft.bSetFlag=True; + ft.flagValue=True; + ft.flagExpiration=8; + + //Elevator to MJ12 Lab + foreach AllActors(class'#var(prefix)MapExit',exit,'change_floors'){break;} + foreach AllActors(class'#var(prefix)Button1',button){ + if (button.Event=='change_floors'){ + break; + } + } + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, exit)); + buttonHint.SetBaseActor(button); + + //Swap BeamTriggers to LaserTrigger, since these lasers set off an alarm + foreach AllActors(class'#var(prefix)BeamTrigger',bt){ + lt = #var(prefix)LaserTrigger(SpawnReplacement(bt,class'#var(prefix)LaserTrigger')); + lt.TriggerType=bt.TriggerType; + lt.bTriggerOnceOnly = bt.bTriggerOnceOnly; + lt.bDynamicLight = bt.bDynamicLight; + lt.bIsOn = bt.bIsOn; + bt.Destroy(); + } + Spawn(class'PlaceholderItem',,, vectm(-39.86,-542.35,570.3)); //Computer desk Spawn(class'PlaceholderItem',,, vectm(339.25,-2111.46,506.3)); //Near lasers Spawn(class'PlaceholderItem',,, vectm(1169,-1490,459)); //Water pool @@ -424,6 +579,15 @@ function PostFirstEntryMapFixes() } } +function FixMaggieMoveSpeed() +{ + local #var(prefix)MaggieChow maggie; + foreach AllActors(class'#var(prefix)MaggieChow',maggie){ + maggie.GroundSpeed = 180; + maggie.walkAnimMult = 1; + } +} + function AnyEntryMapFixes() { local Actor a; @@ -550,6 +714,7 @@ function AnyEntryMapFixes() m.bHighlight = true; } HandleJohnSmithDeath(); + FixMaggieMoveSpeed(); break; case "06_HONGKONG_WANCHAI_CANAL": @@ -619,6 +784,13 @@ function AnyEntryMapFixes() ce = ce.nextEvent; } + break; + case "06_HONGKONG_STORAGE": + //Make sure Maggie always has her MaggieChowShowdown conversation with you if she's here. + //Mark her as having Fled as you enter the lower section of the UC (This prevents her conversations from the apartment from playing) - Done in PreFirstEntry + //Remove the requirement for M07Briefing_Played for the conversation (This allows the conversation to trigger if you went out of order - maybe normally, maybe entrance rando) + DeleteConversationFlag(GetConversation('MaggieChowShowdown'), 'M07Briefing_Played', true); + FixMaggieMoveSpeed(); break; default: break; diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc index 17820d350..9b04d65f0 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc @@ -16,6 +16,8 @@ function AnyEntryMapFixes() RemoveReactions(s); } Player().StartDataLinkTransmission("DL_Entry"); + RearrangeMJ12ConvergingInfolink(); + RearrangeJockExitDialog(); break; case "08_NYC_SMUG": @@ -26,10 +28,80 @@ function AnyEntryMapFixes() } } +function RearrangeJockExitDialog() +{ + local Conversation c; + local ConEvent ce,prev; + local ConEventSpeech ces; + local ConEventAddSkillPoints ceasp; + local ConEventAddGoal ceag,goalComplete; + + c = GetConversation('M08JockExit'); + + ce = c.eventList; + prev=None; + while (ce!=None){ + if (ce.eventType==ET_AddGoal){ + ceag = ConEventAddGoal(ce); + if (ceag.goalName=='GetBackToRoof'){ + //Pull this goal out of the list + goalComplete = ceag; + prev.nextEvent = goalComplete.nextEvent; + } + } else if (ce.eventType==ET_AddSkillPoints){ + ceasp = ConEventAddSkillPoints(ce); + } + prev=ce; + ce = ce.nextEvent; + } + + if (ceasp!=None && goalComplete!=None){ + //The "GetBackToRoof" goal normally only gets marked as complete if you have a LAM + //Move it to get completed when you head out with Jock + goalComplete.nextEvent = ceasp.nextEvent; + ceasp.nextEvent = goalComplete; + } + + +} + +function RearrangeMJ12ConvergingInfolink() +{ + local Conversation c; + local ConEvent ce; + local ConEventSpeech ces; + local ConEventSetFlag cesf; + + c = GetConversation('DL_Exit'); + + ce = c.eventList; + while (ce!=None){ + if (ce.eventType==ET_Speech){ + ces = ConEventSpeech(ce); + } else if (ce.eventType==ET_SetFlag){ + cesf = ConEventSetFlag(ce); + } + ce = ce.nextEvent; + } + + if (ces!=None && cesf!=None){ + //The conversation is typically: + //Speech -> SetFlag -> End + //but I want it to be + //SetFlag -> Speech -> End + + ces.nextEvent = cesf.nextEvent; + cesf.nextEvent = ces; + c.eventList = cesf; + } + +} + function TimerMapFixes() { local BlackHelicopter chopper; local bool VanillaMaps; + local DeusExGoal newGoal; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -42,6 +114,16 @@ function TimerMapFixes() chopper.EnterWorld(); dxr.flagbase.SetBool('MS_Helicopter_Unhidden', True,, 9); } + + if (dxr.flagbase.GetBool('MS_Helicopter_Unhidden') && player().FindGoal('GetBackToRoof')==None){ + newGoal=player().AddGoal('GetBackToRoof',True); + if(dxr.flags.settings.goals > 0) { + newGoal.SetText("Find Jock and take the helicopter to Brooklyn Naval Shipyard.|nRando: Jock could be anywhere in the streets."); + } else { + newGoal.SetText("Find Jock and take the helicopter to Brooklyn Naval Shipyard."); + } + } + break; } } @@ -51,6 +133,9 @@ function PreFirstEntryMapFixes() local DataLinkTrigger dlt; local #var(prefix)NanoKey k; local #var(prefix)PigeonGenerator pg; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; local bool VanillaMaps; #ifdef injections @@ -68,8 +153,6 @@ function PreFirstEntryMapFixes() switch(dxr.localURL) { case "08_NYC_STREET": - AdjustRaidStartLocation(); - //Since we always spawn the helicopter on the roof immediately after the conversation, //the ambush should also always happen immediately after the conversation (instead of //after getting explosives) @@ -82,6 +165,13 @@ function PreFirstEntryMapFixes() pg=Spawn(class'#var(prefix)PigeonGenerator',,, vectm(-2102,1942,-503));//In park pg.MaxCount=3; + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; case "08_NYC_HOTEL": if (VanillaMaps){ @@ -115,38 +205,3 @@ function PreFirstEntryMapFixes() break; } } - -//GOTY edition has the attack force spawn in weird spots within line of sight. -//Revert their starting locations to where they were in the original release. -function AdjustRaidStartLocation() -{ - local MJ12Troop t; - local vector locations[10]; - local int i; - - i=0; - - //In theory we could add more starting locations for the raids (basketball court, hotel) - - //Alley 1 (Sandra Renton) - Vanilla Non-GOTY - locations[i++]=vectm(-2086,-706,-426); - locations[i++]=vectm(-2041,-761,-426); - locations[i++]=vectm(-1886,-719,-426); - locations[i++]=vectm(-1849,-779,-426); - locations[i++]=vectm(-1692,-695,-426); - - //Alley 2 (Road to NSF HQ) - Vanilla Non-GOTY - locations[i++]=vectm(-1907,-1534,-434); - locations[i++]=vectm(-1856,-1584,-434); - locations[i++]=vectm(-1817,-1497,-441); - locations[i++]=vectm(-1693,-1494,-452); - locations[i++]=vectm(-1577,-1585,-438); - - - //Ambush guys are tagged with MJ12AttackForce and start out of world - i=0; - foreach AllActors(class'MJ12Troop',t,'MJ12AttackForce'){ - t.WorldPosition = locations[i]; - t.SetLocation(locations[i++]+vectm(0,0,20000)); - } -} diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM09.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM09.uc index 50d523bef..bd4aff432 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM09.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM09.uc @@ -38,6 +38,11 @@ function PreFirstEntryMapFixes() local #var(prefix)BeamTrigger beam; local OnceOnlyTrigger oot; local #var(prefix)PigeonGenerator pg; + local #var(prefix)Trigger trig; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local bool VanillaMaps; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -64,6 +69,13 @@ function PreFirstEntryMapFixes() //A button *behind* the elevator that sends it up, since it's possible to fall back there and live... AddSwitch( vect(2905.517578,-1641.676270,-430.253693), rot(0,0,0), 'Elevator01_top', "Ramisme's Escape Button"); + //Detach the triggers that opens the op room doors when you get near them from inside + foreach AllActors(class'#var(prefix)Trigger',trig){ + if (trig.Event=='SecDoor1' || trig.Event=='SecDoor2'){ + trig.Event='DontDoAnything'; + } + } + rg=Spawn(class'#var(prefix)RatGenerator',,, vectm(-738,-1412,-474));//Near sewer grate rg.MaxCount=1; @@ -93,6 +105,10 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderContainer',,, vectm(-1248,-1248,-460)); //Shipyard dock near sewer entrance Spawn(class'PlaceholderContainer',,, vectm(-1185,-1175,-460)); //Shipyard dock near sewer entrance Spawn(class'PlaceholderContainer',,, vectm(3172,-1248,-460)); //Shipyard dock near maintenance ladder + + class'PlaceholderEnemy'.static.Create(self,vectm(2639,-1817,-220),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2805,-1824,-220),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2005,-68,512),,'Shitting'); } break; @@ -184,6 +200,12 @@ function PreFirstEntryMapFixes() oot=Spawn(class'OnceOnlyTrigger'); oot.Event='BotDrop'; oot.Tag='BotDropOnce'; + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'ToGraveyard'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); } //They put the key ID in the tag for some reason @@ -237,6 +259,10 @@ function PreFirstEntryMapFixes() class'PlaceholderEnemy'.static.Create(self,vectm(4610,6714,1408)); class'PlaceholderEnemy'.static.Create(self,vectm(3209,2333,48)); + class'PlaceholderEnemy'.static.Create(self,vectm(1475,3249,48),,'Shitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2435,2271,48),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1038,3391,48),,'Sitting'); + break; case "09_NYC_SHIPFAN": @@ -285,6 +311,13 @@ function PreFirstEntryMapFixes() foreach RadiusActors(class'BlockPlayer', bp, 150, vectm(255.896591, 976.539551, 291.541748)) { bp.bBlockPlayers = false; } + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'CopterCam'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc index a63db1a4e..81d741071 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc @@ -61,6 +61,9 @@ function PreFirstEntryMapFixes_Bunker() local Switch2 s2; local SequenceTrigger st; local DataLinkTrigger dlt; + local Dispatcher disp; + local OnceOnlyTrigger oot; + local Trigger trig; local #var(prefix)RatGenerator rg; // doors_lower is for backtracking @@ -111,6 +114,33 @@ function PreFirstEntryMapFixes_Bunker() d.minDamageThreshold=25; d.doorStrength = 0.20; //It's just grating on top of the vent, so it's not that strong + //Make it only possible to turn the power on, make it impossible to turn the power off again + foreach AllActors(class'Dispatcher',disp,'power_dispatcher'){ + disp.Tag = 'power_dispatcher_real'; + break; + } + + oot = Spawn(class'OnceOnlyTrigger'); + oot.Event='power_dispatcher_real'; + oot.Tag='power_dispatcher'; + + //Make sure the power turns on if you get to the bottom + trig = Spawn(class'Trigger',,,vectm(4414,-1035,-7543)); + trig.SetCollisionSize(180,40); + trig.event = 'power_dispatcher'; + + //Make the movers way faster + foreach AllActors(class'DeusExMover',d){ + switch(d.Tag){ + case 'upper_elevator_sw': + case 'upper_elevator_sw_works': + case 'lower_elevator_sw': + case 'lower_elevator_sw_works': + d.MoveTime=0.01; //So fast it just looks like the buttons and stuff swapped instantly, even if you're looking + break; + } + } + //Button to open blast doors from inside AddSwitch( vect(2015.894653,1390.463867,-839.793091), rot(0, -16328, 0), 'blast_door'); @@ -129,6 +159,8 @@ function PreFirstEntryMapFixes_Bunker() class'PlaceholderEnemy'.static.Create(self,vectm(-2237,3225,-192)); class'PlaceholderEnemy'.static.Create(self,vectm(4234,3569,-736)); class'PlaceholderEnemy'.static.Create(self,vectm(3744,-1030,-7481)); + class'PlaceholderEnemy'.static.Create(self,vectm(1341,3154,-464),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(1191,3035,-464),,'Sitting'); rg=Spawn(class'#var(prefix)RatGenerator',,, vectm(1658,2544,-522));//Behind Command 24 rg.MaxCount=1; @@ -264,8 +296,21 @@ function PreFirstEntryMapFixes_Entrance() Spawn(class'PlaceholderItem',,, vectm(-1712.9,191.25,26)); //In front of ambush elevator class'PlaceholderEnemy'.static.Create(self,vectm(4623,210,-176)); - class'PlaceholderEnemy'.static.Create(self,vectm(3314,2196,-176)); + class'PlaceholderEnemy'.static.Create(self,vectm(3314,2276,-176)); class'PlaceholderEnemy'.static.Create(self,vectm(-190,-694,-180)); + class'PlaceholderEnemy'.static.Create(self,vectm(-444,-171,-16)); + class'PlaceholderEnemy'.static.Create(self,vectm(-394,516,-16)); + class'PlaceholderEnemy'.static.Create(self,vectm(-105,769,-176)); + class'PlaceholderEnemy'.static.Create(self,vectm(-116,432,-176)); + class'PlaceholderEnemy'.static.Create(self,vectm(-63,-147,-176)); + class'PlaceholderEnemy'.static.Create(self,vectm(-578,313,-16)); + + class'PlaceholderEnemy'.static.Create(self,vectm(3286,2750,-176),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(3316,2527,-176),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(3297,2079,-176),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2930,2106,-176),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(2977,2306,-176),,'Sitting'); + } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupParis.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupParis.uc index b0a3be0b1..4b7bca582 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupParis.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupParis.uc @@ -8,10 +8,17 @@ function PreFirstEntryMapFixes() local Dispatcher d; local ScriptedPawn sp; local Conversation c; + local #var(prefix)TobyAtanwe toby; local #var(prefix)DataLinkTrigger dlt; local #var(prefix)JaimeReyes j; local #var(prefix)DamageTrigger dt; local #var(prefix)ComputerSecurity cs; + local #var(prefix)AutoTurret at; + local #var(prefix)WIB wib; + local DXRMapVariants mapvariants; + local DXRHoverHint hoverHint; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; local bool VanillaMaps; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -51,9 +58,22 @@ function PreFirstEntryMapFixes() if( t.Event == 'MJ12CommandoSpecial' ) t.Touch(player());// make this guy patrol instead of t-pose + foreach AllActors(class'#var(prefix)WIB',wib){ + wib.UnfamiliarName="Agent Hela"; + } AddSwitch( vect(897.238892, -120.852928, -9.965580), rot(0,0,0), 'catacombs_blastdoor02' ); AddSwitch( vect(-2190.893799, 1203.199097, -6.663990), rot(0,0,0), 'catacombs_blastdoorB' ); + foreach AllActors(class'ScriptedPawn',sp){ + if(sp.BindName=="bums"){ + sp.bImportant=True; + sp.UnfamiliarName="Dr. Kit"; + sp.FamiliarName="Dr. Mehdi Kit"; + break; + } + } + + class'PlaceholderEnemy'.static.Create(self,vectm(-362,-3444,-32)); class'PlaceholderEnemy'.static.Create(self,vectm(-743,677,-256)); class'PlaceholderEnemy'.static.Create(self,vectm(-1573,-113,-64)); @@ -106,6 +126,13 @@ function PreFirstEntryMapFixes() // make the apartment stairs less hidden, not safe to have stairs without a light! CandleabraLight(vect(1825.758057, 1481.900024, 576.077698), rot(0, 16384, 0)); CandleabraLight(vect(1162.240112, 1481.900024, 879.068848), rot(0, 16384, 0)); + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'ChopperExit'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + } break; @@ -125,6 +152,12 @@ function PreFirstEntryMapFixes() Spawn(class'PlaceholderItem',,, vectm(-2093.7,-293,-161)); //Club back room break; case "11_PARIS_UNDERGROUND": + foreach AllActors(class'DXRMapVariants', mapvariants) { break; } + foreach AllActors(class'#var(prefix)TobyAtanwe', toby) { + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, class'DXRMapInfo'.static.GetTeleporterName(mapvariants.VaryMap("11_PARIS_EVERETT"),"Entrance"), toby.Location, toby.CollisionRadius+5, toby.CollisionHeight+5); + hoverHint.SetBaseActor(toby); + } + Spawn(class'PlaceholderItem',,, vectm(2268.5,-563.7,-101)); //Near ATM Spawn(class'PlaceholderItem',,, vectm(408.3,768.7,-37)); //Near Mechanic Spawn(class'PlaceholderItem',,, vectm(-729,809.5,-1061)); //Bench at subway @@ -143,6 +176,11 @@ function PreFirstEntryMapFixes() dt.DamageType='Flamed'; } } + //Restore default damage to this one turret. The only one in the whole + //game with non-standard damage (10 instead of 5). It doesn't need it. + foreach AllActors(class'#var(prefix)AutoTurret',at,'vault_turret'){ + at.gunDamage=class'#var(prefix)AutoTurret'.Default.gunDamage; + } break; case "11_PARIS_EVERETT": foreach AllActors(class'#var(prefix)ComputerSecurity',cs){ @@ -156,6 +194,13 @@ function PreFirstEntryMapFixes() cs.specialOptions[1].TriggerText=""; } } + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'CalledByDispatcher'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + break; } } @@ -235,33 +280,43 @@ function AnyEntryMapFixes() case "11_PARIS_UNDERGROUND": //Add a flag change to Toby's conversation so it sets MS_PlayerTeleported to false if you choose the "take me with you" option //This will let you choose to stay or go. + foreach AllActors(class'TobyAtanwe', toby) { + //Rebind his events to make sure his conversation is loaded if + //you travelled from mission 10 to 11 Underground directly. + //This would really only happen in Entrance Rando. + toby.ConBindEvents(); + } c = GetConversation('MeetTobyAtanwe'); - ce = c.eventList; - cePrev=ce; - while(ce!=None){ - if (ce.eventType==ET_Speech){ - ces = ConEventSpeech(ce); - if (InStr(ces.conSpeech.speech,"Step a little closer")!=-1){ - //Spawn a ConEventSetFlag to set "MS_LetTobyTakeYou_Rando", insert it between this and it's next event - cesf = new(c) class'ConEventSetFlag'; - cesf.eventType=ET_SetFlag; - cesf.label="LetTobyTakeYou"; - cesf.flagRef = new(c) class'ConFlagRef'; - cesf.flagRef.flagName='MS_LetTobyTakeYou_Rando'; - cesf.flagRef.value=True; - cesf.flagRef.expiration=12; - cesf.nextEvent = ces.nextEvent; - ces.nextEvent = cesf; + if (c==None){ + player().ClientMessage("Failed to find conversation for Toby Atanwe! Report this to the devs!"); + } else { + ce = c.eventList; + cePrev=ce; + while(ce!=None){ + if (ce.eventType==ET_Speech){ + ces = ConEventSpeech(ce); + if (InStr(ces.conSpeech.speech,"Step a little closer")!=-1){ + //Spawn a ConEventSetFlag to set "MS_LetTobyTakeYou_Rando", insert it between this and it's next event + cesf = new(c) class'ConEventSetFlag'; + cesf.eventType=ET_SetFlag; + cesf.label="LetTobyTakeYou"; + cesf.flagRef = new(c) class'ConFlagRef'; + cesf.flagRef.flagName='MS_LetTobyTakeYou_Rando'; + cesf.flagRef.value=True; + cesf.flagRef.expiration=12; + cesf.nextEvent = ces.nextEvent; + ces.nextEvent = cesf; + } + } else if (ce.eventType==ET_AddSkillPoints){ + ceasp = ConEventAddSkillPoints(ce); + cePrev.nextEvent = ce.nextEvent; //Remove the event from its current position + ce.nextEvent=None; + ce=cePrev; } - } else if (ce.eventType==ET_AddSkillPoints){ - ceasp = ConEventAddSkillPoints(ce); - cePrev.nextEvent = ce.nextEvent; //Remove the event from its current position - ce.nextEvent=None; - ce=cePrev; - } - cePrev=ce; - ce=ce.nextEvent; + cePrev=ce; + ce=ce.nextEvent; + } } //Assuming we found both the "correct" conversation ending and the skill point trigger, @@ -282,9 +337,18 @@ function AnyEntryMapFixes() function PostFirstEntryMapFixes() { + local #var(prefix)WIB wib; + switch(dxr.localURL) { case "11_PARIS_CATHEDRAL": AddBox(class'#var(prefix)CrateUnbreakableSmall', vectm(-3570.950684, 2238.034668, -783.901367));// right at the start + + //We don't need her to be unshuffled or special, but we want her name to be set + foreach AllActors(class'#var(prefix)WIB',wib){ + wib.UnfamiliarName="Adept 34501"; + wib.FamiliarName="Adept 34501"; + } + break; } } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc index fded0bfdc..bc07f1e51 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc @@ -2,16 +2,16 @@ class DXRFixupVandenberg extends DXRFixup; var bool M14GaryNotDone; var bool M12GaryHostageBriefing; +var int storedBotCount;// MJ12 bots in CMD function PreFirstEntryMapFixes() { local ElevatorMover e; - local Button1 b; local ComputerSecurity comp; local KarkianBaby kb; local DataLinkTrigger dlt; local FlagTrigger ft; - local HowardStrong hs; + local #var(prefix)HowardStrong hs; local #var(DeusExPrefix)Mover door; local DXREnemies dxre; local #var(prefix)TracerTong tt; @@ -22,10 +22,23 @@ function PreFirstEntryMapFixes() local #var(prefix)NanoKey key; local #var(prefix)DamageTrigger dt; local #var(prefix)BeamTrigger bt; + local #var(prefix)LaserTrigger lt; local OnceOnlyTrigger oot; local Actor a; local #var(prefix)PigeonGenerator pg; local #var(prefix)FishGenerator fg; + local #var(prefix)MapExit exit; + local #var(prefix)BlackHelicopter jock; + local DXRHoverHint hoverHint; + local ScriptedPawn pawn; + local #var(prefix)ScriptedPawn sp; + local #var(prefix)Robot bot; + local #var(prefix)TiffanySavage tiffany; + local #var(prefix)SecurityCamera sc; + local Dispatcher d; + local string botName; + local int securityBotNum, militaryBotNum; + local bool VanillaMaps; VanillaMaps = class'DXRMapVariants'.static.IsVanillaMaps(player()); @@ -45,6 +58,11 @@ function PreFirstEntryMapFixes() class'PlaceholderEnemy'.static.Create(self,vectm(2512,6140,-2162)); class'PlaceholderEnemy'.static.Create(self,vectm(2267,643,-2000)); + class'PlaceholderEnemy'.static.Create(self,vectm(-1702,1839,-2000),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-1623,1826,-2000),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-1456,1806,-2000),,'Sitting'); + class'PlaceholderEnemy'.static.Create(self,vectm(-1354,1813,-2000),,'Sitting'); + sl = #var(prefix)ShopLight(AddActor(class'#var(prefix)ShopLight', vect(1.125000, 938.399963, -1025), rot(0, 16384, 0))); sl.bInvincible = true; sl.bCanBeBase = true; @@ -73,6 +91,8 @@ function PreFirstEntryMapFixes() foreach AllActors(class'#var(DeusExPrefix)Mover',door){ if (door.Name=='DeusExMover28'){ door.KeyIDNeeded='TimsClosetKey'; + door.Tag = 'TimsDoor'; + AddSwitch( vect(-1782.48,1597.85,-1969), rot(0, 0, 0), 'TimsDoor'); } } @@ -88,7 +108,36 @@ function PreFirstEntryMapFixes() } } AddSwitch( vect(-278.854828,657.390503,-1977.144531), rot(0, 16384, 0), 'CmdBackDoor'); + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'mission_done'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'Helicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + FixCmdElevator(); + } + + foreach AllActors(class'#var(prefix)Robot',bot,'enemy_bot') { + if (#var(prefix)SecurityBot2(bot) != None) { + botName = "MJ12 Security Bot " $ ++securityBotNum; + } else if (#var(prefix)MilitaryBot(bot) != None) { + botName = "MJ12 Military Bot " $ ++militaryBotNum; + } else { + botName = "MJ12 Bot"; + } + + hoverHint = class'DXRHoverHint'.static.Create(self, botName, bot.Location, bot.CollisionRadius*1.11, bot.CollisionHeight*1.11, bot); + hoverHint.SetBaseActor(bot); + hoverHint.VisibleDistance = 15000; + } + + //There are 3 cameras in CMD that have 20 memoryTime instead of the default 5 + //These are the only ones with non-default in the whole game. Revert them. + foreach AllActors(class'#var(prefix)SecurityCamera',sc){ + sc.memoryTime = sc.Default.memoryTime; } + break; case "12_VANDENBERG_TUNNELS": @@ -98,11 +147,41 @@ function PreFirstEntryMapFixes() e.BumpEvent = 'SC_Door3_opened'; } AddSwitch( vect(-396.634888, 2295, -2542.310547), rot(0, -16384, 0), 'SC_Door3_opened').bCollideWorld = false; - foreach AllActors(class'Button1', b) { - if( b.Event == 'Top' || b.Event == 'middle' || b.Event == 'Bottom' ) { - AddDelay(b, 5); + //Duplicate the dispatcher for both ends of the radioactive room that sets off the alarms and explosion + d = Spawn(class'Dispatcher',, 'SC_Door3_opened' ); + d.OutEvents[0]='Warning'; + d.OutDelays[0]=0; + d.OutEvents[1]='tnt'; + d.OutDelays[1]=3; + d.OutEvents[2]='Warning'; + d.OutDelays[2]=2; + + //Swap the beam triggers that set off this turret to LaserTrigger for clarity + foreach AllActors(class'#var(prefix)BeamTrigger',bt){ + if (bt.Tag=='Turret_beam'){ + lt = #var(prefix)LaserTrigger(SpawnReplacement(bt,class'#var(prefix)LaserTrigger')); + lt.TriggerType=bt.TriggerType; + lt.bTriggerOnceOnly = bt.bTriggerOnceOnly; + lt.bDynamicLight = bt.bDynamicLight; + lt.bIsOn = bt.bIsOn; + bt.Destroy(); } } + + Spawn(class'PlaceholderItem',,, vectm(-2227,4220,-2519)); //on top of generator + Spawn(class'PlaceholderItem',,, vectm(-1421,5119,-2534)); //on top of boxes near start + Spawn(class'PlaceholderItem',,, vectm(-1205,5271,-2534)); //on top of boxes near start + Spawn(class'PlaceholderItem',,, vectm(-2676,3649,-2599)); //stairwell down to flooded area + Spawn(class'PlaceholderItem',,, vectm(-3227,3679,-2599)); //floor near stairwell down to flooded area + Spawn(class'PlaceholderItem',,, vectm(-1590,2796,-2599)); //airlock after spiderbot trap + + Spawn(class'PlaceholderContainer',,, vectm(-2250,4586,-2577)); //across from generator + Spawn(class'PlaceholderContainer',,, vectm(-2414,4329,-2577)); //near generator + Spawn(class'PlaceholderContainer',,, vectm(-3175,3194,-2577)); //near stairwell to flooded area + Spawn(class'PlaceholderContainer',,, vectm(-1399,4950,-2565)); //near boxes near start + Spawn(class'PlaceholderContainer',,, vectm(-3083,2798,-2577)); //near corner near spiderbot trap + Spawn(class'PlaceholderContainer',,, vectm(-325,1386,-2577)); //after the pit + } break; @@ -147,6 +226,12 @@ function PreFirstEntryMapFixes() fg=Spawn(class'#var(prefix)FishGenerator',,, vectm(5657,-1847,-1377));//Near tunnel to sub bay fg.ActiveArea=20000; //Long line of sight on this one... Want it to trigger early + + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'ChopperExit'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); } break; @@ -227,7 +312,7 @@ function PreFirstEntryMapFixes() case "14_Oceanlab_silo": if (VanillaMaps){ if(!dxr.flags.IsReducedRando()) { - foreach AllActors(class'HowardStrong', hs) { + foreach AllActors(class'#var(prefix)HowardStrong', hs) { hs.ChangeAlly('', 1, true); hs.ChangeAlly('mj12', 1, true); hs.ChangeAlly('spider', 1, true); @@ -247,6 +332,8 @@ function PreFirstEntryMapFixes() if(!#defined(vmd)) {// vmd allows AI to equip armor, so maybe he doesn't need the health boost? SetPawnHealth(hs, 200); } + + hs.LeaveWorld(); } } @@ -260,6 +347,13 @@ function PreFirstEntryMapFixes() } } + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'ExitPath'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'BlackHelicopter'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + class'PlaceholderEnemy'.static.Create(self,vectm(-264,-6991,-553)); class'PlaceholderEnemy'.static.Create(self,vectm(-312,-6886,327)); class'PlaceholderEnemy'.static.Create(self,vectm(270,-6601,1500)); @@ -290,25 +384,152 @@ function PreFirstEntryMapFixes() case "12_VANDENBERG_GAS": if (VanillaMaps){ class'PlaceholderEnemy'.static.Create(self,vectm(635,488,-930)); + class'PlaceholderEnemy'.static.Create(self,vectm(1351,582,-930),,'Shitting'); rg=Spawn(class'#var(prefix)RatGenerator',,, vectm(1000,745,-972));//Gas Station back room rg.MaxCount=1; rg=Spawn(class'#var(prefix)RatGenerator',,, vectm(-2375,-644,-993));//Under trailer near Jock rg.MaxCount=1; + //Add teleporter hint text to Jock + foreach AllActors(class'#var(prefix)MapExit',exit,'UN_BlackHeli'){break;} + foreach AllActors(class'#var(prefix)BlackHelicopter',jock,'Heli'){break;} + hoverHint = class'DXRTeleporterHoverHint'.static.Create(self, "", jock.Location, jock.CollisionRadius+5, jock.CollisionHeight+5, exit); + hoverHint.SetBaseActor(jock); + + foreach AllActors(class'#var(prefix)ScriptedPawn',sp,'guard2'){ + SetOutsideGuyReactions(sp); + } + foreach AllActors(class'#var(prefix)ScriptedPawn',sp,'mib_garage'){ + SetOutsideGuyReactions(sp); + } + + //Make Tiffany actually move like a useful human being + foreach AllActors(class'#var(prefix)TiffanySavage',tiffany){ + tiffany.GroundSpeed = 180; + tiffany.walkAnimMult = 1; + } + Spawn(class'PlaceholderItem',,, vectm(-366,-2276,-1553)); //Under collapsed bridge Spawn(class'PlaceholderItem',,, vectm(-394,-1645,-1565)); //Near bridge pillar Spawn(class'PlaceholderItem',,, vectm(-88,-2087,-1553)); //Collapsed bridge road surface Spawn(class'PlaceholderItem',,, vectm(909,-2474,-1551)); //Wrecked car Spawn(class'PlaceholderItem',,, vectm(-3152,-2780,-1364)); //Ledge near original key + } break; } } +//Add a new button in the elevator to open the doors +function FixCmdElevator() +{ + local #var(prefix)Button1 doorButton,butt; + local Dispatcher d; + local Trigger t; + local Vector loc; + local Rotator rot; + local Mover eleDoor; + + //Find the middle elevator button + foreach AllActors(class'#var(prefix)Button1',butt){ + if (butt.Event=='delay_floor2'){ + break; + } + } + + rot = butt.Rotation; + loc = butt.Location; + loc.Z += 7; //Three buttons are 7 apart from each other on Y axis, so put this one equally above + + doorButton = Spawn(class'#var(prefix)Button1',,,loc,rot); + doorButton.moverTag = butt.moverTag; + doorButton.ButtonType=BT_Blank; + doorButton.Event='all_doors_button'; + doorButton.BeginPlay(); + + //Doors are 'door1', 'door2', and 'door3' + d = Spawn(class'Dispatcher',, 'all_doors_button' ); + d.OutEvents[0]='door1'; + d.OutDelays[0]=0; + d.OutEvents[1]='door2'; + d.OutDelays[1]=0; + d.OutEvents[2]='door3'; + d.OutDelays[2]=0; + + //Disable the proximity triggers on the doors + foreach AllActors(class'Trigger',t){ + switch(t.Event){ + case 'door1': + case 'door2': + case 'door3': + t.Event=''; + t.Destroy(); + break; + } + } + + foreach AllActors(class'Mover',eleDoor){ + switch(eleDoor.tag){ + case 'door1': + case 'door2': + case 'door3': + eleDoor.MoverEncroachType=ME_IgnoreWhenEncroach; + break; + } + } +} + +function SetGarageGuyReactions(#var(prefix)ScriptedPawn sp) +{ + sp.RaiseAlarm=RAISEALARM_BeforeAttacking; + sp.bReactAlarm=True; //The various reactions on the normal garage guard + sp.bReactCarcass=False; + sp.bReactDistress=True; + sp.bReactFutz=False; + sp.bReactLoudNoise=True; + sp.bReactPresence=True; + sp.bReactProjectiles=True; + sp.bReactShot=True; + sp.bHateCarcass=False; + sp.bHateDistress=True; + sp.bHateHacking=False; + sp.bHateIndirectInjury=False; + sp.bHateInjury=True; + sp.bHateShot=True; + sp.bHateWeapon=True; + sp.MaxProvocations=1; + sp.ResetReactions(); +} + +function SetOutsideGuyReactions(#var(prefix)ScriptedPawn sp) +{ + sp.RaiseAlarm=RAISEALARM_BeforeFleeing; + sp.bReactAlarm=True; + sp.bReactCarcass=False; + sp.bReactDistress=False; + sp.bReactFutz=False; + sp.bReactLoudNoise=False; + sp.bReactPresence=True; + sp.bReactProjectiles=True; + sp.bReactShot=False; + sp.bHateCarcass=False; + sp.bHateDistress=False; + sp.bHateHacking=False; + sp.bHateIndirectInjury=False; + sp.bHateInjury=True; + sp.bHateShot=True; + sp.bHateWeapon=False; + sp.MaxProvocations=1; + sp.ResetReactions(); +} + function PostFirstEntryMapFixes() { local #var(prefix)CrateUnbreakableLarge c; local Actor a; + local #var(prefix)ScriptedPawn sp; + local #var(prefix)AlarmUnit alarm; + local #var(DeusExPrefix)Mover door; local bool RevisionMaps; RevisionMaps = class'DXRMapVariants'.static.IsRevisionMaps(player()); @@ -328,12 +549,39 @@ function PostFirstEntryMapFixes() a.SetPhysics(PHYS_None); l("PostFirstEntryMapFixes spawned "$ActorToString(a)); break; + case "12_VANDENBERG_GAS": + foreach AllActors(class'#var(prefix)ScriptedPawn',sp,'guard2'){ + SetGarageGuyReactions(sp); + } + foreach AllActors(class'#var(prefix)ScriptedPawn',sp,'mib_garage'){ + SetGarageGuyReactions(sp); + sp.Tag = 'guard2'; // + } + foreach AllActors(class'#var(prefix)ScriptedPawn',sp,'guard2'){ + if (#var(prefix)Animal(sp)!=None){ + //player().ClientMessage("Spawning doggy alarm for "$sp); + alarm=Spawn(class'#var(prefix)AlarmUnit',,, vectm(-7.312059,933.707886,-985),rotm(0,-16408,0)); //Dog Height Alarm + alarm.Event='guardattack'; + alarm.Tag='alarm1'; //Same as the original alarm + + //a dog can't open a door, so trigger it from the alarm panel + foreach RadiusActors(class'#var(DeusExPrefix)Mover',door,100,alarm.Location){ + if (door.KeyIDNeeded=='pipe'){ + door.Tag='guardattack'; + break; + } + } + break; + } + + } + break; } } function AnyEntryMapFixes() { - local MIB mib; + local #var(prefix)ScriptedPawn sp; local NanoKey key; local #var(prefix)HowardStrong hs; @@ -344,15 +592,18 @@ function AnyEntryMapFixes() switch(dxr.localURL) { case "12_Vandenberg_gas": - foreach AllActors(class'MIB', mib, 'mib_garage') { - key = NanoKey(mib.FindInventoryType(class'NanoKey')); - l(mib$" has key "$key$", "$key.KeyID$", "$key.Description); - if(key == None) continue; - if(key.KeyID != '') continue; - l("fixing "$key$" to garage_entrance"); - key.KeyID = 'garage_entrance'; - key.Description = "Garage Door"; - key.Timer();// make sure to fix the ItemName in vanilla + foreach AllActors(class'#var(prefix)ScriptedPawn', sp) { + //We switch the tag for mib_garage to guard2 for safety purposes + if (sp.Tag== 'mib_garage' || sp.Tag=='guard2'){ + key = NanoKey(sp.FindInventoryType(class'NanoKey')); + if(key == None) continue; + l(sp$" has key "$key$", "$key.KeyID$", "$key.Description); + if(key.KeyID != '') continue; + l("fixing "$key$" to garage_entrance"); + key.KeyID = 'garage_entrance'; + key.Description = "Garage Door"; + key.Timer();// make sure to fix the ItemName in vanilla + } } break; @@ -369,12 +620,17 @@ function AnyEntryMapFixes() hs.MinHealth = 0; } Player().StartDataLinkTransmission("DL_FrontGate"); + SetTimer(1, true); break; case "12_VANDENBERG_COMPUTER": SetTimer(1, true); break; case "12_VANDENBERG_CMD": Player().StartDataLinkTransmission("DL_no_carla"); + + // timer to count the MJ12 Bots + SetTimer(1, True); + break; } } @@ -407,6 +663,9 @@ function FixSavageSkillPointsDupe() function TimerMapFixes() { local #var(prefix)GarySavage gary; + local #var(prefix)HowardStrong hs; + local bool prevMapsDone; + switch(dxr.localURL) { case "14_VANDENBERG_SUB": @@ -428,5 +687,73 @@ function TimerMapFixes() } } break; + case "12_VANDENBERG_CMD": + CountMJ12Bots(); + break; + + case "14_Oceanlab_silo": + prevMapsDone = dxr.flagbase.GetBool('Heliosborn') && //Finished Vandenberg, mission 12 + dxr.flagbase.GetBool('schematic_downloaded'); //Finished Ocean Lab, mission 14, + prevMapsDone = prevMapsDone || !#defined(injections); + + if(prevMapsDone + && dxr.flagbase.GetBool('missile_launched') //Redirected the missile in Silo, mission 14 + && !dxr.flagbase.GetBool('MS_HowardStrongUnhidden')) + { + foreach AllActors(class'#var(prefix)HowardStrong', hs) { + hs.EnterWorld(); + } + dxr.flagbase.SetBool('MS_HowardStrongUnhidden', True,, 15); + } + break; } } + +function CountMJ12Bots() +{ + local int newCount; + local #var(prefix)Robot bot; + + newCount = 0; + + foreach AllActors(class'#var(prefix)Robot',bot,'enemy_bot') { + if (bot.EMPHitPoints>0){ + newCount++; + } + } + + if (newCount!=storedBotCount){ + // A bot has been destroyed or disabled! + if (UpdateBotGoal(newCount)==True){ + storedBotCount = newCount; //only update the stored count if the goal updated + if(newCount==0){ + SetTimer(0, False); // Disable the timer now that all bots are destroyed + } + } + } +} + +function bool UpdateBotGoal(int count) +{ + local string goalText; + local DeusExGoal goal; + local int bracketPos; + goal = player().FindGoal('DestroyBots'); + + if (goal!=None){ + goalText = goal.text; + bracketPos = InStr(goalText,"["); + + if (bracketPos>0){ //If the extra text is already there, strip it. + goalText = Mid(goalText,0,bracketPos-1); + } + + goalText = goalText$" ["$count$" remaining]"; + + goal.SetText(goalText); + + return True; + } + return False; +} + diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM01.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM01.uc index 3c1b50201..5b5d24df0 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM01.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM01.uc @@ -2,16 +2,17 @@ class DXRMissionsM01 extends DXRMissions; function int InitGoals(int mission, string map) { - local int goal, goal2, loc, loc2; + local int goal, goal2, loc, loc2, loc3; goal = AddGoal("01_NYC_UNATCOISLAND", "Terrorist Commander", NORMAL_GOAL, 'TerroristCommander0', PHYS_Falling); AddGoalActor(goal, 1, 'DataLinkTrigger12', PHYS_None); + AddGoalActor(goal, 2, 'SkillAwardTrigger6', PHYS_None); goal2 = AddGoal("01_NYC_UNATCOISLAND", "Police Boat", GOAL_TYPE1, 'NYPoliceBoat0', PHYS_None); loc = AddGoalLocation("01_NYC_UNATCOISLAND", "UNATCO HQ", START_LOCATION, vect(-6348.445313, 1912.637207, -111.428482), rot(0, 0, 0)); - loc2 = AddGoalLocation("01_NYC_UNATCOISLAND", "Dock", NORMAL_GOAL | VANILLA_START, vect(-4760.569824, 10430.811523, -280.674988), rot(0, -7040, 0)); + loc2 = AddGoalLocation("01_NYC_UNATCOISLAND", "South Dock", NORMAL_GOAL | VANILLA_START, vect(-4760.569824, 10430.811523, -280.674988), rot(0, -7040, 0)); AddMutualExclusion(loc, loc2); - AddMapMarker(class'Image01_LibertyIsland',156,364,"L","Terrorist Commander", loc2,"Leo Gold, the terrorist commander, can be located on the south dock. This is the location you would normally start the game."); + AddMapMarker(class'Image01_LibertyIsland',156,364,"L","Terrorist Commander", loc2,"Leo Gold, the terrorist commander, can be located on the South dock. This is the location you would normally start the game."); loc2 = AddGoalLocation("01_NYC_UNATCOISLAND", "Hut", NORMAL_GOAL, vect(-2407.206787, 205.915558, -128.899979), rot(0, 30472, 0)); AddMutualExclusion(loc, loc2); @@ -22,6 +23,11 @@ function int InitGoals(int mission, string map) AddMutualExclusion(loc, loc2); AddMapMarker(class'Image01_LibertyIsland',318,140,"L","Terrorist Commander",loc2,"Leo Gold, the terrorist commander, can be located in the back of the small bunker next to the statue. He would be behind the malfunctioning electrical box."); + loc3 = AddGoalLocation("01_NYC_UNATCOISLAND", "North Dock", NORMAL_GOAL, vect(4018,-10308,-256), rot(0, 22520, 0)); + AddMutualExclusion(loc, loc3); + AddMutualExclusion(loc3, loc2); + AddMapMarker(class'Image01_LibertyIsland',239,15,"L","Terrorist Commander",loc3,"Leo Gold, the terrorist commander, can be located on the North dock on the opposite side from the hut."); + loc=AddGoalLocation("01_NYC_UNATCOISLAND", "Jail", NORMAL_GOAL | START_LOCATION, vect(2127.692139, -1774.869141, -149.140366), rot(0, 0, 0)); AddMapMarker(class'Image01_LibertyIsland',235,147,"L","Terrorist Commander", loc,"Leo Gold, the terrorist commander, can be located inside the jail cell where Gunther is locked up."); @@ -80,6 +86,7 @@ function PreFirstEntryMapFixes() { local #var(prefix)DataLinkTrigger dlt; local #var(prefix)OrdersTrigger ot; + local #var(prefix)SkillAwardTrigger sat; if( dxr.localURL == "01_NYC_UNATCOISLAND" ) { dxr.flags.f.SetBool('PaulGaveWeapon', true,, 2); @@ -103,6 +110,16 @@ function PreFirstEntryMapFixes() dlt.Destroy(); } } + + //Increase the radius of the 750 points for reaching the top of the statue + //This gets moved with Leo and needs to be bigger than his conversation trigger + //which has a 140 invocation radius. + foreach AllActors(class'#var(prefix)SkillAwardTrigger',sat){ + if (sat.skillPointsAdded==750){ //Reward for reaching top of statue + sat.SetCollisionSize(250,sat.CollisionHeight); + break; + } + } } } @@ -110,8 +127,8 @@ function MissionTimer() { switch(dxr.localURL) { case "01_NYC_UNATCOHQ": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('GetToDock', "The boat could be anywhere."); + UpdateGoalWithRandoInfo('GetToDock', "The boat could be anywhere."); + break; } } diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM02.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM02.uc index d00ab9b56..94a49f42c 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM02.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM02.uc @@ -25,6 +25,12 @@ function int InitGoals(int mission, string map) AddGoalLocation("02_NYC_BATTERYPARK", "Walkway by the water", NORMAL_GOAL, vect(-420.000000, -2222.000000, -400), rot(0, 0, 0)); AddGoalLocation("02_NYC_BATTERYPARK", "Subway stairs", NORMAL_GOAL, vect(-5106.205078, 1813.453003, -82.239639), rot(0, 0, 0)); AddGoalLocation("02_NYC_BATTERYPARK", "Subway", NORMAL_GOAL, vect(-4727.703613, 3116.336670, -321.900604), rot(0, 0, 0)); + + if (dxr.flags.settings.starting_map > 20) + { + skip_rando_start = True; + } + return 21; case "02_NYC_WAREHOUSE": @@ -88,6 +94,12 @@ function int InitGoalsRev(int mission, string map) AddGoalLocation("02_NYC_BATTERYPARK", "Walkway by the water", NORMAL_GOAL, vect(-420.000000, -2222.000000, -400), rot(0, 0, 0)); AddGoalLocation("02_NYC_BATTERYPARK", "Subway stairs", NORMAL_GOAL, vect(-5106.205078, 1813.453003, -82.239639), rot(0, 0, 0)); AddGoalLocation("02_NYC_BATTERYPARK", "Subway", NORMAL_GOAL, vect(-4727.703613, 3116.336670, -321.900604), rot(0, 0, 0)); + + if (dxr.flags.settings.starting_map > 20) + { + skip_rando_start = True; + } + return 21; case "02_NYC_WAREHOUSE": @@ -220,8 +232,11 @@ function MissionTimer() { switch(dxr.localURL) { case "02_NYC_BATTERYPARK": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('FindAmbrosia', "The Ambrosia could be anywhere in Battery Park."); + UpdateGoalWithRandoInfo('FindAmbrosia', "The Ambrosia could be anywhere in Battery Park."); + break; + case "02_NYC_STREET": + UpdateGoalWithRandoInfo('DestroyGenerator', "The generator could be anywhere in the warehouse district. It looks like a large yellow cylinder."); + break; } } @@ -232,11 +247,16 @@ function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) local #var(prefix)ComputerPersonal cp; local DXRPasswords passwords; + if (g.name=="Generator"){ + class'DXRHoverHint'.static.Create(self, "NSF Generator", Loc.positions[0].pos, 175, 140, g.actors[0].a); + } + if(g.name == "Generator" && Loc.name != "Warehouse") { a = AddBox(class'#var(prefix)CrateUnbreakableLarge', vectm(505.710449, -605, 162.091278), rotm(16384,0,0)); a.SetCollisionSize(a.CollisionRadius * 4, a.CollisionHeight * 4); a.bMovable = false; a.DrawScale = 4; + class'DXRHoverHint'.static.Create(self, "This is not the generator", a.Location, a.CollisionRadius+5, a.CollisionHeight+5); a = AddBox(class'#var(prefix)CrateUnbreakableLarge', vectm(677.174988, -809.484558, 114.097824), rotm(0,0,0)); a.SetCollisionSize(a.CollisionRadius * 2, a.CollisionHeight * 2); a.bMovable = false; diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc index 5a9879e4d..8907edef4 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc @@ -28,6 +28,12 @@ function int InitGoals(int mission, string map) loc = AddGoalLocation("03_NYC_BATTERYPARK", "Subway", NORMAL_GOAL | VANILLA_GOAL | START_LOCATION, vect(-4819.345215,3478.138916,-304.225006), rot(0,0,0)); AddActorLocation(loc, 1, vect(-4739.345215, 3578.138916, -306), rot(0,0,0)); + + if (dxr.flags.settings.starting_map > 32) + { + skip_rando_start = True; + } + return 31; case "03_NYC_BROOKLYNBRIDGESTATION": @@ -143,6 +149,12 @@ function int InitGoalsRev(int mission, string map) loc = AddGoalLocation("03_NYC_BATTERYPARK", "Subway", NORMAL_GOAL | VANILLA_GOAL | START_LOCATION, vect(-4819.345215,3478.138916,-304.225006), rot(0,0,0)); AddActorLocation(loc, 1, vect(-4739.345215, 3578.138916, -306), rot(0,0,0)); + + if (dxr.flags.settings.starting_map > 32) + { + skip_rando_start = True; + } + return 31; case "03_NYC_BROOKLYNBRIDGESTATION": @@ -292,6 +304,16 @@ function MissionTimer() } } break; + case "03_NYC_AIRFIELDHELIBASE": + UpdateGoalWithRandoInfo('FindAmbrosiaBarrels', "The Ambrosia could be anywhere in the helibase or airfield."); + break; + case "03_NYC_AIRFIELD": + UpdateGoalWithRandoInfo('LastBarrel747', "The last barrel of Ambrosia could be in the hangar or somewhere on the 747."); + break; + case "03_NYC_BROOKLYNBRIDGESTATION": + UpdateGoalWithRandoInfo('TalkToCharlie', "Charlie could be anywhere in the station"); + UpdateGoalWithRandoInfo('KillDealer', "Rock could be anywhere in the station"); + break; } } diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM04.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM04.uc index 2dd5babc0..1db0cc83d 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM04.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM04.uc @@ -5,23 +5,26 @@ function int InitGoals(int mission, string map) { local int goal, loc, loc2; - // GOAL_TYPE1 for the computer, 2 for Anna - AddGoal("04_NYC_NSFHQ", "Computer", GOAL_TYPE1, 'ComputerPersonal3', PHYS_Falling); - AddGoalLocation("04_NYC_NSFHQ", "Third Floor", GOAL_TYPE1, vect(-460.091187, 1011.083496, 551.367859), rot(0, 16672, 0)); - AddGoalLocation("04_NYC_NSFHQ", "Second Floor", GOAL_TYPE1, vect(206.654617, 1340.000000, 311.652832), rot(0, 0, 0)); - AddGoalLocation("04_NYC_NSFHQ", "Garage", GOAL_TYPE1, vect(381.117371, -696.875671, 63.615902), rot(0, 32768, 0)); - AddGoalLocation("04_NYC_NSFHQ", "Break Room", GOAL_TYPE1, vect(42.340145, 1104.667480, 73.610352), rot(0, 0, 0)); - AddGoalLocation("04_NYC_NSFHQ", "Basement Exit", GOAL_TYPE1, vect(1290.299927, 1385.000000, -185.000000), rot(0, 16384, 0)); - AddGoalLocation("04_NYC_NSFHQ", "Basement Entrance", GOAL_TYPE1, vect(-617.888855, 141.699875, -208.000000), rot(0, 16384, 0)); + // GOAL_TYPE1 for the dish computer, 2 for transmitter, 3 for Anna + AddGoal("04_NYC_NSFHQ", "Dish Alignment Computer", GOAL_TYPE1, 'ComputerPersonal3', PHYS_Falling); + AddGoalLocation("04_NYC_NSFHQ", "Third Floor", GOAL_TYPE1 | GOAL_TYPE2, vect(-460.091187, 1011.083496, 551.367859), rot(0, 16672, 0)); + AddGoalLocation("04_NYC_NSFHQ", "Second Floor", GOAL_TYPE1 | GOAL_TYPE2, vect(206.654617, 1340.000000, 311.652832), rot(0, 0, 0)); + AddGoalLocation("04_NYC_NSFHQ", "Garage", GOAL_TYPE1 | GOAL_TYPE2, vect(381.117371, -696.875671, 63.615902), rot(0, 32768, 0)); + AddGoalLocation("04_NYC_NSFHQ", "Break Room", GOAL_TYPE1 | GOAL_TYPE2, vect(42.340145, 1104.667480, 73.610352), rot(0, 0, 0)); + AddGoalLocation("04_NYC_NSFHQ", "Basement Exit", GOAL_TYPE1 | GOAL_TYPE2, vect(1290.299927, 1385.000000, -185.000000), rot(0, 16384, 0)); + AddGoalLocation("04_NYC_NSFHQ", "Basement Entrance", GOAL_TYPE1 | GOAL_TYPE2, vect(-617.888855, 141.699875, -208.000000), rot(0, 16384, 0)); AddGoalLocation("04_NYC_NSFHQ", "Rooftop", GOAL_TYPE1 | VANILLA_GOAL, vect(187.265259,315.583862,1032.054199), rot(0,16672,0)); - goal = AddGoal("04_NYC_BatteryPark", "Anna Navarre", GOAL_TYPE2, 'AnnaNavarre0', PHYS_Falling); + AddGoal("04_NYC_NSFHQ", "Transmitter Computer", GOAL_TYPE2, 'ComputerPersonal4', PHYS_Falling); + //AddGoalLocation("04_NYC_NSFHQ", "Rooftop Secure Room", GOAL_TYPE2 | VANILLA_GOAL, vect(116.650787, 400.400024, 1032.054199), rot(0,49384,0)); + + goal = AddGoal("04_NYC_BatteryPark", "Anna Navarre", GOAL_TYPE3, 'AnnaNavarre0', PHYS_Falling); AddGoalActor(goal, 1, 'AllianceTrigger11', PHYS_None); //AnnaAttacksJC - AddGoalLocation("04_NYC_BatteryPark", "Battery Park Subway", GOAL_TYPE2 | VANILLA_GOAL, vect(-4981.514648,2416.581787,-304.599060), rot(0,-49328,0)); - AddGoalLocation("04_NYC_Street", "Street Barricade", GOAL_TYPE2, vect(-6353.232422,899.716797,-480.599030), rot(0,25000,0)); - AddGoalLocation("04_NYC_Street", "Hell's Kitchen Subway", GOAL_TYPE2, vect(1370.337646,-1819.429688,-464.602142), rot(0,32768,0)); - AddGoalLocation("04_NYC_Street", "Outside Free Clinic", GOAL_TYPE2, vect(-1500.715332,891.878662,-464.603424), rot(0,0,0)); - AddGoalLocation("04_NYC_Hotel", "Hotel", GOAL_TYPE2, vect(30.716736,-65.753799,-16.600384), rot(0,40000,0)); + AddGoalLocation("04_NYC_BatteryPark", "Battery Park Subway", GOAL_TYPE3 | VANILLA_GOAL, vect(-4981.514648,2416.581787,-304.599060), rot(0,-49328,0)); + AddGoalLocation("04_NYC_Street", "Street Barricade", GOAL_TYPE3, vect(-6353.232422,899.716797,-480.599030), rot(0,25000,0)); + AddGoalLocation("04_NYC_Street", "Hell's Kitchen Subway", GOAL_TYPE3, vect(1370.337646,-1819.429688,-464.602142), rot(0,32768,0)); + AddGoalLocation("04_NYC_Street", "Outside Free Clinic", GOAL_TYPE3, vect(-1500.715332,891.878662,-464.603424), rot(0,0,0)); + AddGoalLocation("04_NYC_Hotel", "Hotel", GOAL_TYPE3, vect(30.716736,-65.753799,-16.600384), rot(0,40000,0)); return mission; } @@ -29,7 +32,7 @@ function int InitGoalsRev(int mission, string map) { local int goal, loc, loc2; - // GOAL_TYPE1 for the computer, 2 for Anna + // GOAL_TYPE1 for the computer, 3 for Anna AddGoal("04_NYC_NSFHQ", "Computer", GOAL_TYPE1, 'ComputerPersonal3', PHYS_Falling); AddGoalLocation("04_NYC_NSFHQ", "Third Floor", GOAL_TYPE1, vect(-460.091187, 1011.083496, 551.367859), rot(0, 16672, 0)); AddGoalLocation("04_NYC_NSFHQ", "Second Floor", GOAL_TYPE1, vect(206.654617, 1340.000000, 311.652832), rot(0, 0, 0)); @@ -39,13 +42,13 @@ function int InitGoalsRev(int mission, string map) AddGoalLocation("04_NYC_NSFHQ", "Basement Entrance", GOAL_TYPE1, vect(-617.888855, 141.699875, -208.000000), rot(0, 16384, 0)); AddGoalLocation("04_NYC_NSFHQ", "Rooftop", GOAL_TYPE1 | VANILLA_GOAL, vect(187.265259,315.583862,1032.054199), rot(0,16672,0)); - goal = AddGoal("04_NYC_BatteryPark", "Anna Navarre", GOAL_TYPE2, 'AnnaNavarre0', PHYS_Falling); + goal = AddGoal("04_NYC_BatteryPark", "Anna Navarre", GOAL_TYPE3, 'AnnaNavarre0', PHYS_Falling); AddGoalActor(goal, 1, 'AllianceTrigger11', PHYS_None); //AnnaAttacksJC - AddGoalLocation("04_NYC_BatteryPark", "Battery Park Subway", GOAL_TYPE2 | VANILLA_GOAL, vect(-4980.514648,1696.581787,-60.599060), rot(0,-49328,0)); - AddGoalLocation("04_NYC_Street", "Street Barricade", GOAL_TYPE2, vect(-367.627167,-3320.272461,-464.599823), rot(0,30000,0)); - AddGoalLocation("04_NYC_Street", "Hell's Kitchen Subway", GOAL_TYPE2, vect(3325.658447,-404.416199,-1144.588501), rot(0,-16384,0)); - AddGoalLocation("04_NYC_Street", "Outside Free Clinic", GOAL_TYPE2, vect(-1500.715332,891.878662,-464.603424), rot(0,0,0)); - AddGoalLocation("04_NYC_Hotel", "Hotel", GOAL_TYPE2, vect(30.716736,-65.753799,-16.600384), rot(0,40000,0)); + AddGoalLocation("04_NYC_BatteryPark", "Battery Park Subway", GOAL_TYPE3 | VANILLA_GOAL, vect(-4980.514648,1696.581787,-60.599060), rot(0,-49328,0)); + AddGoalLocation("04_NYC_Street", "Street Barricade", GOAL_TYPE3, vect(-367.627167,-3320.272461,-464.599823), rot(0,30000,0)); + AddGoalLocation("04_NYC_Street", "Hell's Kitchen Subway", GOAL_TYPE3, vect(3325.658447,-404.416199,-1144.588501), rot(0,-16384,0)); + AddGoalLocation("04_NYC_Street", "Outside Free Clinic", GOAL_TYPE3, vect(-1500.715332,891.878662,-464.603424), rot(0,0,0)); + AddGoalLocation("04_NYC_Hotel", "Hotel", GOAL_TYPE3, vect(30.716736,-65.753799,-16.600384), rot(0,40000,0)); return mission; } @@ -86,3 +89,12 @@ function CreateGoal(out Goal g, GoalLocation Loc) break; } } + +function MissionTimer() +{ + switch(dxr.localURL) { + case "04_NYC_NSFHQ": + UpdateGoalWithRandoInfo('SendSignal', "The computers to align the dishes and send the signal could be anywhere in NSF HQ."); + break; + } +} diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM05.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM05.uc index 51adf98ab..de81ec8ea 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM05.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM05.uc @@ -38,7 +38,11 @@ function int InitGoals(int mission, string map) AddGoalLocation("05_NYC_UNATCOHQ", "Jail", NORMAL_GOAL, vect(-2478.156738, -1123.645874, -16.399887), rot(0, 0, 0)); AddGoalLocation("05_NYC_UNATCOHQ", "Bathroom", NORMAL_GOAL, vect(121.921074, 287.711243, 39.599487), rot(0, 0, 0)); - AddGoalLocation("05_NYC_UNATCOHQ", "Manderley's Bathroom", NORMAL_GOAL, vect(261.019775, -403.939575, 287.600586), rot(0, 0, 0)); + if (IsAprilFools()){ + AddGoalLocation("05_NYC_UNATCOHQ", "Manderley's Bathroom", NORMAL_GOAL | SITTING_GOAL, vect(261.019775, -403.939575, 287.600586), rot(0, 0, 0)); + } else { + AddGoalLocation("05_NYC_UNATCOHQ", "Manderley's Bathroom", NORMAL_GOAL, vect(261.019775, -403.939575, 287.600586), rot(0, 0, 0)); + } AddGoalLocation("05_NYC_UNATCOHQ", "Break Room", NORMAL_GOAL, vect(718.820068, 1411.137451, 287.598999), rot(0, 0, 0)); AddGoalLocation("05_NYC_UNATCOHQ", "West Office", NORMAL_GOAL, vect(-666.268066, -460.813965, 463.598083), rot(0, 0, 0)); AddGoalLocation("05_NYC_UNATCOHQ", "Computer Ops", NORMAL_GOAL | VANILLA_GOAL, vect(2001.611206,-801.088379,-16.225000), rot(0,23776,0)); @@ -157,7 +161,7 @@ function AfterShuffleGoals(int goalsToLocations[32]) SpawnDatacubePlaintext(vectm(243.288742, -104.183029, 289.368256), rotm(0,0,0), dctext, true); } - } else if (dxr.localURL == "05_NYC_UNATCOMJ12LAB" && #defined(revision)){ + } else if (dxr.localURL == "05_NYC_UNATCOMJ12LAB" && #defined(revision)){ //For some reason shuffling Paul's body stops it from being destroyed by the mission script if (!player().flagbase.GetBool('PaulDenton_Dead')){ foreach AllActors(class'PaulDentonCarcass',paulbody){ @@ -293,3 +297,13 @@ function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) } } } + +function MissionTimer() +{ + switch(dxr.localURL) { + case "05_NYC_UNATCOMJ12LAB": + UpdateGoalWithRandoInfo('FindPaul', "Paul could be located anywhere in the lab. A security computer in the command center will be connected to a camera monitoring him."); + UpdateGoalWithRandoInfo('FindEquipment', "Your equipment could be in either the armory or the surgery bay."); + break; + } +} diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM06.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM06.uc index fe9cb7761..1a6d412cd 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM06.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM06.uc @@ -70,7 +70,11 @@ function int InitGoals(int mission, string map) AddActorLocation(loc, 1, vect(488.291809, -2581.964355, -336.402618), rot(0,32620,0)); AddActorLocation(loc, 2, vect(484.913330,-2345.247559,-336.401306), rot(0,32620,0)); - loc=AddGoalLocation("06_HONGKONG_WANCHAI_UNDERWORLD","Bathroom",GOAL_TYPE1,vect(-1725.911133,-565.364746,-339),rot(0,16368,0)); + if (IsAprilFools()){ + loc=AddGoalLocation("06_HONGKONG_WANCHAI_UNDERWORLD","Bathroom",GOAL_TYPE1 | SITTING_GOAL,vect(-1561,-671,-339),rot(0,16368,0)); + } else { + loc=AddGoalLocation("06_HONGKONG_WANCHAI_UNDERWORLD","Bathroom",GOAL_TYPE1,vect(-1725.911133,-565.364746,-339),rot(0,16368,0)); + } AddActorLocation(loc, 1, vect(-1794.911133,-572.364746,-339), rot(0,16368,0)); AddActorLocation(loc, 2, vect(-1658.911133,-568.364746,-339), rot(0,16368,0)); @@ -181,10 +185,11 @@ function MissionTimer() switch(dxr.localURL) { case "06_HONGKONG_WANCHAI_MARKET": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('InvestigateMaggieChow', "The sword may not be in Maggie's apartment, instead there will be a Datacube with a hint."); + UpdateGoalWithRandoInfo('InvestigateMaggieChow', "The sword may not be in Maggie's apartment, instead there will be a Datacube with a hint."); break; case "06_HONGKONG_TONGBASE": + UpdateGoalWithRandoInfo('GetROM', "The computer with the ROM-encoding could be anywhere in the lab."); + //Immediately start M08Briefing after M07Briefing, if possible ready_for_m08 = !M08Briefing && dxr.flagbase.GetBool('M07Briefing_played') && !dxr.flagbase.GetBool('M08Briefing_played'); ready_for_m08 = ready_for_m08 && dxr.flagbase.GetBool('TriadCeremony_Played') && dxr.flagbase.GetBool('VL_UC_Destroyed') && dxr.flagbase.GetBool('VL_Got_Schematic'); @@ -205,6 +210,10 @@ function MissionTimer() } break; } + + //Rando can give you this goal in a bunch of maps (Tonnochi Road, Canal, Market, Lucky Money) + //just update it whenever + UpdateGoalWithRandoInfo('ConvinceRedArrow', "Max Chen could be anywhere in the Lucky Money."); } function DeleteGoal(Goal g, GoalLocation Loc) diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM08.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM08.uc index 491533822..e871a21bd 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM08.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM08.uc @@ -1,25 +1,43 @@ class DXRMissionsM08 extends DXRMissions; + var vector assaultLocations[10]; + var int numAssaultLocations; + function int InitGoals(int mission, string map) { local int goal, loc, loc2; - AddGoal("08_NYC_Bar", "Harley Filben", NORMAL_GOAL, 'HarleyFilben0', PHYS_Falling); - goal = AddGoal("08_NYC_Bar", "Vinny", NORMAL_GOAL, 'NathanMadison0', PHYS_Falling); + AddGoal("08_NYC_Bar", "Harley Filben", GOAL_TYPE1, 'HarleyFilben0', PHYS_Falling); + goal = AddGoal("08_NYC_Bar", "Vinny", GOAL_TYPE1, 'NathanMadison0', PHYS_Falling); //AddGoalActor(goal, 1, 'SandraRenton0', PHYS_Falling); TODO: move Sandra with Vinny? //AddGoalActor(goal, 2, 'CoffeeTable0', PHYS_Falling); - AddGoal("08_NYC_FreeClinic", "Joe Greene", NORMAL_GOAL, 'JoeGreene0', PHYS_Falling); - - AddGoalLocation("08_NYC_Street", "Hotel Roof", START_LOCATION | VANILLA_START | NORMAL_GOAL, vect(-354.250427, 795.071594, 594.411743), rot(0, -18600, 0)); - AddGoalLocation("08_NYC_Bar", "Bar Table", NORMAL_GOAL | VANILLA_GOAL | SITTING_GOAL, vect(-1689.125122, 337.159912, 63.599533), rot(0,-10144,0)); - AddGoalLocation("08_NYC_Bar", "Bar", NORMAL_GOAL | VANILLA_GOAL, vect(-931.038086, -488.537109, 47.600464), rot(0,9536,0)); - AddGoalLocation("08_NYC_FreeClinic", "Clinic", NORMAL_GOAL | VANILLA_GOAL, vect(904.356262, -1229.045166, -272.399506), rot(0,31640,0)); - AddGoalLocation("08_NYC_Underground", "Sewers", NORMAL_GOAL, vect(591.048462, -152.517639, -560.397888), rot(0,32768,0)); - AddGoalLocation("08_NYC_Hotel", "Hotel", NORMAL_GOAL | SITTING_GOAL, vect(-108.541245, -2709.490479, 111.600838), rot(0,20000,0)); - AddGoalLocation("08_NYC_Street", "Basketball Court", NORMAL_GOAL | START_LOCATION, vect(2694.934082, -2792.844971, -448.396637), rot(0,32768,0)); - - if (dxr.flags.settings.starting_map == 81) //Mission 8 Smuggler + AddGoal("08_NYC_FreeClinic", "Joe Greene", GOAL_TYPE1, 'JoeGreene0', PHYS_Falling); + + AddGoalLocation("08_NYC_Street", "Hotel Roof", START_LOCATION | VANILLA_START | GOAL_TYPE1, vect(-354.250427, 795.071594, 594.411743), rot(0, -18600, 0)); + AddGoalLocation("08_NYC_Bar", "Bar Table", GOAL_TYPE1 | VANILLA_GOAL | SITTING_GOAL, vect(-1689.125122, 337.159912, 63.599533), rot(0,-10144,0)); + AddGoalLocation("08_NYC_Bar", "Bar", GOAL_TYPE1 | VANILLA_GOAL, vect(-931.038086, -488.537109, 47.600464), rot(0,9536,0)); + AddGoalLocation("08_NYC_FreeClinic", "Clinic", GOAL_TYPE1 | VANILLA_GOAL, vect(904.356262, -1229.045166, -272.399506), rot(0,31640,0)); + AddGoalLocation("08_NYC_Underground", "Sewers", GOAL_TYPE1, vect(591.048462, -152.517639, -560.397888), rot(0,32768,0)); + AddGoalLocation("08_NYC_Hotel", "Hotel", GOAL_TYPE1 | SITTING_GOAL, vect(-108.541245, -2709.490479, 111.600838), rot(0,20000,0)); + AddGoalLocation("08_NYC_Street", "Basketball Court", GOAL_TYPE1 | START_LOCATION, vect(2694.934082, -2792.844971, -448.396637), rot(0,32768,0)); + + AddGoal("08_NYC_Street", "Jock", GOAL_TYPE2, 'BlackHelicopter0', PHYS_None); + AddGoalLocation("08_NYC_Street", "Hotel Roof", GOAL_TYPE2 | VANILLA_GOAL, vect(75,965,755), rot(0, 22824, 0)); + AddGoalLocation("08_NYC_Street", "Bar Entrance", GOAL_TYPE2, vect(-180,-1675,-325), rot(0, 0, 0)); + AddGoalLocation("08_NYC_Street", "Smuggler Back Entrance", GOAL_TYPE2, vect(3010,-4285,-470), rot(0, 23416, 0)); + AddGoalLocation("08_NYC_Street", "Alley", GOAL_TYPE2, vect(-2222,-770,-390), rot(0, 0, 0)); + + //The MJ12 assault squads now get randomized as two squads of 5 (as they were split in non-GOTY) + AddGoal("08_NYC_StreetFake", "MJ12 Assault Squad 1", GOAL_TYPE3, 'Van0', PHYS_None); //CreateGoal only runs if the goal map doesn't match + AddGoal("08_NYC_StreetFake", "MJ12 Assault Squad 2", GOAL_TYPE3, 'Van1', PHYS_None); //CreateGoal only runs if the goal map doesn't match + AddGoalLocation("08_NYC_Street", "Alley", GOAL_TYPE3 | VANILLA_GOAL, vect(-1893.816406,-614.223816,-445.429260), rot(0, -32616, 0)); + AddGoalLocation("08_NYC_Street", "Road to NSF HQ", GOAL_TYPE3 | VANILLA_GOAL, vect(-1758.505249,-1704.474976,-445.434998), rot(0, 32832, 0)); + AddGoalLocation("08_NYC_Street", "Basketball Court", GOAL_TYPE3, vect(2914,-3000,-429), rot(0, 7200, 0)); + AddGoalLocation("08_NYC_Street", "Smuggler Front Door", GOAL_TYPE3, vect(2292.625977,-1448.627441,-445.429016), rot(0, 0, 0)); + AddGoalLocation("08_NYC_Street", "Hotel", GOAL_TYPE3, vect(1005.300781,201.109436,-445.432312), rot(0, -16240, 0)); + + if (dxr.flags.settings.starting_map >= 81) //Mission 8 Smuggler { skip_rando_start = True; } @@ -45,7 +63,7 @@ function int InitGoalsRev(int mission, string map) AddGoalLocation("08_NYC_Hotel", "Hotel", NORMAL_GOAL | SITTING_GOAL, vect(316,-3439,111), rot(0,0,0)); AddGoalLocation("08_NYC_Street", "Basketball Court", NORMAL_GOAL | START_LOCATION, vect(2683.1,-1977.77,-448), rot(0,-16390,0)); - if (dxr.flags.settings.starting_map == 81) //Mission 8 Smuggler + if (dxr.flags.settings.starting_map >= 81) //Mission 8 Smuggler { skip_rando_start = True; } @@ -56,6 +74,7 @@ function int InitGoalsRev(int mission, string map) function CreateGoal(out Goal g, GoalLocation Loc) { local #var(prefix)ScriptedPawn sp; + local #var(prefix)Van van; switch(g.name) { case "Harley Filben": @@ -86,6 +105,37 @@ function CreateGoal(out Goal g, GoalLocation Loc) sp.SetOrders('Standing'); sp.ConBindEvents(); break; + + case "MJ12 Assault Squad 1": + case "MJ12 Assault Squad 2": + van = #var(prefix)Van(Spawnm(class'#var(prefix)Van',, 'DXRMissions', Loc.positions[0].pos,Loc.positions[0].rot)); + g.actors[0].a = van; + van.FamiliarName=PickSurveillanceVanName(); + van.UnfamiliarName=van.FamiliarName; + van.bIsSecretGoal=True; + break; + } +} + +function String PickSurveillanceVanName() +{ + switch(Rand(8)){ + case 0: + return "Flower Delivery Van"; + case 1: + return "Ice Cream Truck"; + case 2: + return "Pest Control Van"; + case 3: + return "Phone Company Van"; + case 4: + return "The Cleaners"; + case 5: + return "Milk Delivery Truck"; + case 6: + return "Ordinary Van"; + case 7: + return "Black Van Pizza"; } } @@ -94,11 +144,94 @@ function MissionTimer() switch(dxr.localURL) { case "08_NYC_STREET": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('FindHarleyFilben', "Harley could be anywhere in Hell's Kitchen"); + UpdateGoalWithRandoInfo('FindHarleyFilben', "Harley could be anywhere in Hell's Kitchen"); break; } - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('KillGreene', "Joe Greene could be anywhere."); + UpdateGoalWithRandoInfo('KillGreene', "Joe Greene could be anywhere."); +} + +function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) +{ + if (g.name=="Jock") { + if(Loc.name=="Smuggler Back Entrance" || Loc.name=="Alley") { + g.actors[0].a.DrawScale = 0.5; + g.actors[0].a.SetCollisionSize(200, 50); + } else { + g.actors[0].a.DrawScale = 1; + g.actors[0].a.SetCollisionSize(320, 87); + } + } +} + +function AfterShuffleGoals(int goalsToLocations[32]) +{ + local int g; + local bool RevisionMaps; + + RevisionMaps = class'DXRMapVariants'.static.IsRevisionMaps(player()); + + if (dxr.localURL == "08_NYC_STREET" && !RevisionMaps){ + numAssaultLocations=0; + for(g=0; g 0) { + switch(dxr.localURL) + { + case "09_NYC_GRAVEYARD": + UpdateGoalWithRandoInfo('EliminateField', "The EM generator could be anywhere in the graveyard."); + break; + default: UpdateGoalWithRandoInfo('Escape', "Jock could be anywhere at the dockyard."); UpdateGoalWithRandoInfo('ScuttleShip', "Check the map in your Images section to see where the weld points can be."); } diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc index eac9d54d8..1d8e89b6a 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc @@ -37,6 +37,11 @@ function int InitGoals(int mission, string map) AddGoalLocation("15_AREA51_BUNKER", "the hangar", GOAL_TYPE1, vect(1062.942261,-2496.865723,-443.252533), rot(0, 16384, 0)); AddGoalLocation("15_AREA51_BUNKER", "the supply shed", GOAL_TYPE1, vect(-1527.608521,3280.824219,-158.588562), rot(0, -16384, 0)); + if (dxr.flags.settings.starting_map > 150) + { + skip_rando_start = True; + } + return 151; } @@ -78,6 +83,11 @@ function int InitGoalsRev(int mission, string map) AddGoalLocation("15_AREA51_BUNKER", "the hangar", GOAL_TYPE1, vect(1397.388672,-2498.310059,-441.741699), rot(0, 16384, 0)); AddGoalLocation("15_AREA51_BUNKER", "the supply shed", GOAL_TYPE1, vect(-1860.243530,2902.310059,-151.812180), rot(0, -16384, 0)); + if (dxr.flags.settings.starting_map > 150) + { + skip_rando_start = True; + } + return 151; } diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc b/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc index e9335dee4..aa64b0268 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc @@ -153,10 +153,10 @@ function MissionTimer() switch(dxr.localURL) { case "10_PARIS_METRO": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('MeetJaime', "Jaime could be anywhere in Paris."); - UpdateGoalWithRandoInfo('GetCrack', "The zyme can be anywhere.");// not actually depedent on goals rando - + UpdateGoalWithRandoInfo('MeetJaime', "Jaime could be anywhere in Paris."); + if(dxr.flags.settings.swapitems > 0) { + UpdateGoalWithRandoInfo('GetCrack', "The zyme can be anywhere.",True);// dependent on swap items, not on goals rando + } if (f.GetBool('MeetNicolette_Played') && !f.GetBool('NicoletteLeftClub')) { @@ -185,8 +185,13 @@ function MissionTimer() break; case "10_PARIS_CATACOMBS_TUNNELS": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('FindNicolette', "Nicolette could be anywhere in the city"); + UpdateGoalWithRandoInfo('FindNicolette', "Nicolette could be anywhere in the city."); + break; + case "10_PARIS_CHATEAU": + UpdateGoalWithRandoInfo('AccessTemplarComputer', "The computer could be anywhere in the cathedral."); + break; + case "10_PARIS_CATACOMBS": + UpdateGoalWithRandoInfo('KillGreasels', "The greasels could be anywhere in the area."); break; } } diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsVandenberg.uc b/DXRMissions/DeusEx/Classes/DXRMissionsVandenberg.uc index e90db0142..9acc978ce 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsVandenberg.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsVandenberg.uc @@ -48,6 +48,11 @@ function int InitGoals(int mission, string map) loc = AddGoalLocation("12_VANDENBERG_CMD", "Sniper Tower", GOAL_TYPE1, vect(-946.215820, 80.315643, -1359.704102), rot(0,32768,0)); AddActorLocation(loc, 1, vect(-1033.543579, 265.367859, -1569.458740), rot(0,-30000,0)); + if (dxr.flags.settings.starting_map > 120) + { + skip_rando_start = True; + } + return 121; case "14_VANDENBERG_SUB": @@ -143,6 +148,11 @@ function int InitGoalsRev(int mission, string map) loc = AddGoalLocation("12_VANDENBERG_CMD", "Sniper Tower", GOAL_TYPE1, vect(-946.215820, 80.315643, -1359.704102), rot(0,32768,0)); AddActorLocation(loc, 1, vect(-1033.543579, 265.367859, -1569.458740), rot(0,-30000,0)); + if (dxr.flags.settings.starting_map > 120) + { + skip_rando_start = True; + } + return 121; case "14_VANDENBERG_SUB": @@ -209,8 +219,8 @@ function MissionTimer() switch(dxr.localURL) { case "12_VANDENBERG_CMD": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('FindJock', "Jock could be anywhere around the Command Center."); + UpdateGoalWithRandoInfo('FindJock', "Jock could be anywhere around the Command Center."); + UpdateGoalWithRandoInfo('ActivatePower', "The keypads can be anywhere around the Command Center."); break; case "14_VANDENBERG_SUB": @@ -226,8 +236,7 @@ function MissionTimer() break; case "14_OCEANLAB_SILO": - if(dxr.flags.settings.goals > 0) - UpdateGoalWithRandoInfo('MeetJock', "Jock could be anywhere around the silo."); + UpdateGoalWithRandoInfo('MeetJock', "Jock could be anywhere around the silo."); break; } } diff --git a/DXRModules/DeusEx/Classes/DXRAugmentations.uc b/DXRModules/DeusEx/Classes/DXRAugmentations.uc index affc9d2af..a03f033b9 100644 --- a/DXRModules/DeusEx/Classes/DXRAugmentations.uc +++ b/DXRModules/DeusEx/Classes/DXRAugmentations.uc @@ -122,6 +122,20 @@ static function RemoveAug(DeusExPlayer player, Augmentation aug) } +static function RedrawAugMenu(DeusExPlayer player) +{ +#ifdef injections + local #var(injectsprefix)PersonaScreenAugmentations augScreen; + + if (DeusExRootWindow(player.rootWindow)==None) return; + + augScreen = #var(injectsprefix)PersonaScreenAugmentations(DeusExRootWindow(player.rootWindow).GetTopWindow()); + if (augScreen==None) return; + + augScreen.RedrawAugmentations(); +#endif +} + function RandomizeAugCannisters() { local #var(prefix)AugmentationCannister a; diff --git a/DXRModules/DeusEx/Classes/DXRAutosave.uc b/DXRModules/DeusEx/Classes/DXRAutosave.uc index 7630fd556..56d69f2c2 100644 --- a/DXRModules/DeusEx/Classes/DXRAutosave.uc +++ b/DXRModules/DeusEx/Classes/DXRAutosave.uc @@ -22,7 +22,7 @@ function CheckConfig() save_delay = 0.1; } Super.CheckConfig(); - autosave_combat = int(ConsoleCommand("get #var(package).MenuChoice_AutosaveCombat autosave_combat")); + autosave_combat = class'MenuChoice_AutosaveCombat'.default.autosave_combat; } function BeginPlay() @@ -35,6 +35,7 @@ function PreFirstEntry() { Super.PreFirstEntry(); l("PreFirstEntry() " $ dxr.dxInfo.MissionNumber); + if(dxr.flags.IsHordeMode()) return; if( dxr.dxInfo != None && dxr.dxInfo.MissionNumber > 0 && dxr.dxInfo.MissionNumber < 98 && dxr.flags.autosave > 0 ) { NeedSave(); } @@ -44,6 +45,7 @@ function ReEntry(bool IsTravel) { Super.ReEntry(IsTravel); l("ReEntry() " $ dxr.dxInfo.MissionNumber); + if(dxr.flags.IsHordeMode()) return; if( dxr.dxInfo != None && dxr.dxInfo.MissionNumber > 0 && dxr.dxInfo.MissionNumber < 98 && dxr.flags.autosave>=EveryEntry && dxr.flags.autosave != Hardcore && IsTravel ) { NeedSave(); } @@ -145,6 +147,11 @@ static function bool AllowManualSaves(DeusExPlayer player) if( f == None ) return true; if( f.autosave == Hardcore ) return false; if( f.IsHordeMode() ) return false; + + if(player.dataLinkPlay != None) { + player.dataLinkPlay.FastForward(); + } + return true; } diff --git a/DXRModules/DeusEx/Classes/DXRBacktracking.uc b/DXRModules/DeusEx/Classes/DXRBacktracking.uc index 93b19816b..c9142217c 100644 --- a/DXRModules/DeusEx/Classes/DXRBacktracking.uc +++ b/DXRModules/DeusEx/Classes/DXRBacktracking.uc @@ -8,6 +8,8 @@ function PreFirstEntry() local BlockPlayer bp; local MapExit exit; local FlagTrigger ft; + local DeusExDecoration button; + local DXRButtonHoverHint buttonHint; Super.PreFirstEntry(); @@ -32,7 +34,9 @@ function PreFirstEntry() SetDestination(dt, "10_PARIS_CATACOMBS_TUNNELS", 'AmbientSound10'); dt.SetCollisionSize(160,dt.CollisionHeight); if(!dxr.flags.IsZeroRando()) { - AddSwitch(vect(1602.826904, -4318.841309, -250.365067), rot(0, 16384, 0), 'sewers_backtrack'); + button=AddSwitch(vect(1602.826904, -4318.841309, -250.365067), rot(0, 16384, 0), 'sewers_backtrack'); + buttonHint = DXRButtonHoverHint(class'DXRButtonHoverHint'.static.Create(self, "", button.Location, button.CollisionRadius+5, button.CollisionHeight+5, dt)); + buttonHint.SetBaseActor(button); } foreach AllActors(class'MapExit', exit, 'ChopperExit') { @@ -58,6 +62,11 @@ function PreFirstEntry() foreach AllActors(class'MapExit', exit, 'mission_done') { SetDestination(exit, "12_Vandenberg_gas", '', "gas_start"); } + FixTunnelsTeleporters(); + break; + + case "12_VANDENBERG_TUNNELS": + FixTunnelsTeleporters(); break; case "12_VANDENBERG_GAS": @@ -109,6 +118,45 @@ function PreFirstEntry() } } +function FixTunnelsTeleporters() +{ + local MapExit exit; + local DynamicTeleporter dt; + + //Remove the original MapExits + foreach AllActors(class'MapExit',exit){ + switch(exit.DestMap){ + case "12_vandenberg_tunnels#end": + case "12_vandenberg_tunnels#start": + case "12_vandenberg_cmd#commstat": + case "12_vandenberg_cmd#storage": + exit.Destroy(); + break; + } + } + + //Replace with new DynamicTeleporters + switch(dxr.localURL) + { + case "12_VANDENBERG_CMD": + dt = Spawn(class'DynamicTeleporter',,,vectm(813,1257,-2163)); //Inside CMD + dt.SetCollisionSize(30,15); + SetDestination(dt, "12_vandenberg_tunnels",'',"end"); + dt = Spawn(class'DynamicTeleporter',,,vectm(-1592,4570,-2297)); //Outside building + dt.SetCollisionSize(30,15); + SetDestination(dt, "12_vandenberg_tunnels",'',"start"); + break; + case "12_VANDENBERG_TUNNELS": + dt = Spawn(class'DynamicTeleporter',,,vectm(-1625,5743,-2364)); //Start + dt.SetCollisionSize(30,15); + SetDestination(dt, "12_vandenberg_cmd",'',"commstat"); + dt = Spawn(class'DynamicTeleporter',,,vectm(398,1164,-2356)); //End + dt.SetCollisionSize(30,15); + SetDestination(dt, "12_vandenberg_cmd",'',"storage"); + break; + } +} + simulated function PlayerAnyEntry(#var(PlayerPawn) p) { Super.PlayerAnyEntry(p); @@ -262,6 +310,7 @@ function ParisMetroAnyEntry() local NicoletteDuClare nicolette; local FlagBase flags; local MapExit exit; + local Vehicles chopper; flags = dxr.flagbase; @@ -285,7 +334,10 @@ function ParisMetroAnyEntry() RemoveChoppers(); - SpawnChopper( 'BlackHelicopter', 'choppertrack', "Jock", vectm(3134.682373, 1101.204956, 304.756897), rotm(0, -24944, 0) ); + chopper=SpawnChopper( 'BlackHelicopter', 'choppertrack', "Jock", vectm(3134.682373, 1101.204956, 304.756897), rotm(0, -24944, 0) ); + + RebindChopperHoverHint('ChopperExit',chopper); + } /*if( flags.GetBool('ClubComplete') ) { @@ -341,6 +393,7 @@ function VandCmdAnyEntry() { RemoveChoppers('Helicopter'); chopper = SpawnChopper( 'Helicopter', 'helicopter_path', "Jock", vectm(7014.185059, 7540.296875, -2884.704102), rotm(0, -19840, 0) ); + RebindChopperHoverHint('mission_done',chopper); missions = DXRMissions(dxr.FindModule(class'DXRMissions')); if(missions != None) { missions.UpdateLocation(chopper); @@ -385,7 +438,8 @@ function VandGasAnyEntry() if( flags.GetBool('MS_ChopperGasUnhidden') ) { RemoveChoppers('Heli'); - SpawnChopper( 'Heli', 'UN_BlackHeli', "Jock", vectm(-3207.999756, 135.342285, -905.545044), rotm(0, -63104, 0) ); + chopper=BlackHelicopter(SpawnChopper( 'Heli', 'UN_BlackHeli', "Jock", vectm(-3207.999756, 135.342285, -905.545044), rotm(0, -63104, 0) )); + RebindChopperHoverHint('UN_BlackHeli',chopper); foreach AllActors(Class'DeusExMover', M, 'junkyard_doors') M.BlowItUp(None); @@ -411,6 +465,7 @@ function VandSubAnyEntry() local Conversation c; local ConEvent e, nextEvent; local MapExit exit; + local Vehicles chopper,sub; if(dxr.flags.IsReducedRando()) return; @@ -463,6 +518,10 @@ function VandSubAnyEntry() break; } } + + foreach AllActors(class'Vehicles',sub,'MiniSub'){break;} //Actually finding a minisub, but the variable already exists... + RebindChopperHoverHint('reallysubexit',sub); + // TODO: there are unused InterpolationPoints for the submarine // repeat flights to silo @@ -471,7 +530,8 @@ function VandSubAnyEntry() if( flags.GetBool('DL_downloaded_Played') || dxr.flags.IsWaltonWare() ) { RemoveChoppers('BlackHelicopter'); - SpawnChopper( 'BlackHelicopter', 'Jockpath', "Jock", vectm(2104.722168, 3647.967773, 896.197144), rotm(0, 0, 0) ); + chopper=SpawnChopper( 'BlackHelicopter', 'Jockpath', "Jock", vectm(2104.722168, 3647.967773, 896.197144), rotm(0, 0, 0) ); + RebindChopperHoverHint('ChopperExit',chopper); } // don't need to talk to Gary @@ -570,6 +630,7 @@ function VandOceanLabAnyEntry() s.SetRotation(rotm(0, -16408, 0)); s.DesiredRotation = rotm(0, -16408, 0); s.origRot = rotm(0, -16408, 0); + RebindChopperHoverHint('reallysubexit2',s); foreach AllActors(class'DataLinkTrigger', dlt) { if( dlt.datalinkTag != 'dl_seconddoors' ) continue; @@ -670,18 +731,46 @@ function Vehicles BacktrackChopper(Name event, Name ChopperTag, Name PathTag, st chopper = SpawnChopper(ChopperTag, PathTag, BindName, loc, rot); - foreach AllActors(class'MapExit', exit, event) + foreach AllActors(class'MapExit', exit, event){ + RebindChopperHoverHint(event,chopper); return chopper; + } exit = Spawn(class'MapExit',, event, loc ); exit.SetCollision(false,false,false); SetDestination(exit, DestMap, DestName, DestTag); exit.bPlayTransition = true; exit.cameraPathTag = CameraPath; + + RebindChopperHoverHint(event,chopper); + info("BacktrackChopper spawned "$exit); return chopper; } +function RebindChopperHoverHint(name ExitTag, Vehicles chopper) +{ + local #var(prefix)MapExit exit; + local DXRTeleporterHoverHint hoverHint; + local bool foundHint; + + foreach AllActors(class'#var(prefix)MapExit',exit,ExitTag){ + break; + } + + foundHint=False; + foreach AllActors(class'DXRTeleporterHoverHint',hoverHint){ + if (hoverHint.target==exit){ + foundHint=True; + break; + } + } + if (!foundHint){ + hoverHint = DXRTeleporterHoverHint(class'DXRTeleporterHoverHint'.static.Create(self, "", chopper.Location, chopper.CollisionRadius+5, chopper.CollisionHeight+5, exit)); + } + hoverHint.SetBaseActor(chopper); +} + function CreateInterpolationPoints(Name PathTag, vector loc) { local InterpolationPoint p; diff --git a/DXRModules/DeusEx/Classes/DXRBrightness.uc b/DXRModules/DeusEx/Classes/DXRBrightness.uc index d8ec6070a..8af2b5489 100644 --- a/DXRModules/DeusEx/Classes/DXRBrightness.uc +++ b/DXRModules/DeusEx/Classes/DXRBrightness.uc @@ -9,7 +9,7 @@ var ZoneBrightnessData zone_brightness[32]; function int GetSavedBrightnessBoost() { - return int(player().ConsoleCommand("get #var(package).MenuChoice_BrightnessBoost BrightnessBoost")); + return class'MenuChoice_BrightnessBoost'.default.BrightnessBoost; } function PreFirstEntry() diff --git a/DXRModules/DeusEx/Classes/DXRCrowdControl.uc b/DXRModules/DeusEx/Classes/DXRCrowdControl.uc index f18e98fe3..c9db8e5c9 100644 --- a/DXRModules/DeusEx/Classes/DXRCrowdControl.uc +++ b/DXRModules/DeusEx/Classes/DXRCrowdControl.uc @@ -24,13 +24,20 @@ var config int numStupidQuestions; var config stupidQuestionSave StupidQuestions[50]; var stupidQuestion _StupidQuestions[50]; var int curStupidQuestion; +var DataStorage datastorage; function Init(DXRando tdxr) { local bool anon, offline, online; Super.Init(tdxr); - curStupidQuestion = Rand(numStupidQuestions); + datastorage = class'DataStorage'.static.GetObjFromPlayer(self); + if (datastorage.GetConfigKey('cc_StupidQuestionNumber')==""){ + curStupidQuestion = Rand(numStupidQuestions); + datastorage.SetConfig('cc_StupidQuestionNumber',curStupidQuestion, 3600*12); + } else { + curStupidQuestion = int(datastorage.GetConfigKey('cc_StupidQuestionNumber')); + } if (tdxr.flags.crowdcontrol != 0) { link = Spawn(class'DXRandoCrowdControlLink'); @@ -282,6 +289,9 @@ function getRandomQuestion(out string question, out int numAnswers, curStupidQuestion++; curStupidQuestion = curStupidQuestion % numStupidQuestions; + datastorage = class'DataStorage'.static.GetObjFromPlayer(self); + datastorage.SetConfig('cc_StupidQuestionNumber',curStupidQuestion, 3600*12); + question = _StupidQuestions[curStupidQuestion].question; numAnswers = _StupidQuestions[curStupidQuestion].numAnswers; ansOne = _StupidQuestions[curStupidQuestion].answers[0]; diff --git a/DXRModules/DeusEx/Classes/DXRDatacubes.uc b/DXRModules/DeusEx/Classes/DXRDatacubes.uc index 16fee1385..b745c0eec 100644 --- a/DXRModules/DeusEx/Classes/DXRDatacubes.uc +++ b/DXRModules/DeusEx/Classes/DXRDatacubes.uc @@ -217,7 +217,14 @@ function vanilla_datacubes_rules() break; case "04_NYC_NSFHQ": - // datacube with the password for sending the signal + // don't allow either datacube in the room with the vanilla transmitter computer + // datacube with the password for sending the signal, allowed almost anywhere + datacubes_rules[i].item_name = '04_Datacube01'; + datacubes_rules[i].min_pos = vect(100, 329, 1010); + datacubes_rules[i].max_pos = vect(116, 345, 1050); + datacubes_rules[i].allow = false; + i++; + datacubes_rules[i].item_name = '04_Datacube01'; datacubes_rules[i].min_pos = vect(-99999, -99999, -99999); datacubes_rules[i].max_pos = vect(99999, 99999, 99999); @@ -225,6 +232,12 @@ function vanilla_datacubes_rules() i++; // datacube with the security password, don't allow it to go in the basement, you might need it to open the weird door things + datacubes_rules[i].item_name = '04_Datacube02'; + datacubes_rules[i].min_pos = vect(100, 329, 1010); + datacubes_rules[i].max_pos = vect(116, 345, 1050); + datacubes_rules[i].allow = false; + i++; + datacubes_rules[i].item_name = '04_Datacube02'; datacubes_rules[i].min_pos = vect(-99999, -99999, -99999); datacubes_rules[i].max_pos = vect(99999, 99999, 0); diff --git a/DXRModules/DeusEx/Classes/DXREnemies.uc b/DXRModules/DeusEx/Classes/DXREnemies.uc index c550707be..604e8c7a2 100644 --- a/DXRModules/DeusEx/Classes/DXREnemies.uc +++ b/DXRModules/DeusEx/Classes/DXREnemies.uc @@ -72,7 +72,7 @@ function CheckConfig() AddRandomEnemyType(class'#var(prefix)Karkian', 1, FactionAny); AddRandomEnemyType(class'#var(prefix)SecurityBot2', 2, FactionAny);//walker AddRandomEnemyType(class'#var(prefix)SecurityBot3', 2, FactionAny);//little guy from liberty island - AddRandomEnemyType(class'#var(prefix)SecurityBot4', 2, FactionAny);//unused little guy + AddRandomEnemyType(class'DXRSecurityBot4', 2, FactionAny);//unused little guy AddRandomEnemyType(class'#var(prefix)UNATCOTroop', 10, UNATCO); AddRandomEnemyType(class'UNATCOClone1', 10, UNATCO); @@ -112,9 +112,9 @@ function CheckConfig() AddRandomEnemyType(class'NSFClone2', 10, NSF); AddRandomEnemyType(class'NSFClone3', 10, NSF); AddRandomEnemyType(class'NSFClone4', 10, NSF); - AddRandomEnemyType(class'#var(prefix)ThugMale', 5, NSF); - AddRandomEnemyType(class'#var(prefix)ThugMale2', 5, NSF); - AddRandomEnemyType(class'#var(prefix)ThugMale3', 5, NSF); + AddRandomEnemyType(class'NSFThugMale', 5, NSF); + AddRandomEnemyType(class'NSFThugMale2', 5, NSF); + AddRandomEnemyType(class'NSFThugMale3', 5, NSF); AddRandomEnemyType(class'NSFCloneAugShield1', 1.5, NSF); AddRandomEnemyType(class'NSFCloneAugTough1', 1.5, NSF); AddRandomEnemyType(class'NSFCloneAugStealth1', 1.5, NSF); @@ -160,15 +160,35 @@ function FirstEntry() RandoEnemies(dxr.flags.settings.enemiesrandomized, dxr.flags.settings.hiddenenemiesrandomized); RandoCarcasses(dxr.flags.settings.swapitems); GivePatrols(); + + //DebugAlliances(); +} + +function DebugAlliances() +{ + local #var(prefix)ScriptedPawn p; + + foreach AllActors(class'#var(prefix)ScriptedPawn', p) { + l("FixAlliances() " $ p @ p.Alliance); + if(p.Alliance == 'Bot' || p.Alliance == 'Robot') err(p @ p.Alliance); + l(p $ " reactions: "$ p.bLikesNeutral @ p.bHateWeapon @ p.bHateDistress @ p.bHateShot @ p.bHateInjury @ p.bHateIndirectInjury @ p.bHateCarcass); +#ifdef injections + if(#var(prefix)Animal(p) != None) #var(prefix)Animal(p).PrintAlliances(); + else if(#var(prefix)HumanMilitary(p) != None) #var(prefix)HumanMilitary(p).PrintAlliances(); + else if(#var(prefix)HumanCivilian(p) != None) #var(prefix)HumanCivilian(p).PrintAlliances(); + else if(#var(prefix)HumanThug(p) != None) #var(prefix)HumanThug(p).PrintAlliances(); + else if(#var(prefix)Robot(p) != None) #var(prefix)Robot(p).PrintAlliances(); + else err("unknown pawn type "$p); +#endif + } } function RandoEnemies(int percent, int hidden_percent) { // TODO: later when hidden_percent is well tested, we can get rid of it and _perc - local int i, _perc; + local int i, _perc, num_enemies, e, new_enemies, r; local ScriptedPawn p; - local ScriptedPawn n; - local ScriptedPawn newsp; + local ScriptedPawn enemies[128]; l("RandoEnemies "$percent@hidden_percent@dxr.flags.settings.enemystats); if(percent <= 0 && hidden_percent <= 0 && dxr.flags.settings.enemystats <= 0) @@ -178,43 +198,42 @@ function RandoEnemies(int percent, int hidden_percent) foreach AllActors(class'ScriptedPawn', p) { - if( p != None && p.bImportant ) continue; -#ifdef gmdx - if( SpiderBot2(p) != None && SpiderBot2(p).bUpsideDown ) continue; -#endif - RandomizeSize(p); - } - - foreach AllActors(class'ScriptedPawn', p) - { - if( p == newsp ) break; - if( IsCritter(p) ) continue; - //if( SkipActor(p, 'ScriptedPawn') ) continue; - //if( IsInitialEnemy(p) == False ) continue; #ifdef gmdx if( SpiderBot2(p) != None && SpiderBot2(p).bUpsideDown ) continue; #endif + if(!p.bImportant) { + RandomizeSize(p); + } + if( !IsRelevantPawn(p.class) ) continue; if( HasItemSubclass(p, class'Weapon') == false ) continue;//don't randomize neutral npcs that don't already have weapons + enemies[num_enemies++] = p; + } + + for(e=0; e=100 || chance_single(_perc) ) RandomizeSP(p, _perc); CheckHelmet(p); if(p.bImportant && p.Tag != 'RaidingCommando') continue; if(p.bInvincible) continue; if( p.Region.Zone.bWaterZone || p.Region.Zone.bPainZone ) continue; - if( chance_single(_perc) == false ) continue; + if( _perc < 100 && chance_single(_perc) == false ) continue; - for(i = rng(enemy_multiplier*100+_perc)/100; i >= 0; i--) { - n = RandomEnemy(p, _perc); - if( newsp == None ) newsp = n; + r = rng(enemy_multiplier*100+_perc); + for(i = r/100; i >= 0; i--) { + if(RandomEnemy(p, _perc) != None) new_enemies++; } } + + l("RandoEnemies num_enemies == " $ num_enemies $ ", new_enemies == " $ new_enemies $ ", percent == " $ percent); } function int GetFactionId(ScriptedPawn p) @@ -260,13 +279,13 @@ function RandomizeSP(ScriptedPawn p, int percent) p.BaseAccuracy = FClamp(p.BaseAccuracy, 0, 2);//ensure BaseAccuracy doesn't go below 0 } - if(p.RaiseAlarm==RAISEALARM_BeforeAttacking && chance_single(dxr.flags.settings.enemystats)) { + if(p.RaiseAlarm==RAISEALARM_BeforeAttacking && !p.bIsSecretGoal && chance_single(dxr.flags.settings.enemystats)) { p.RaiseAlarm = RAISEALARM_BeforeFleeing; } - if( IsCritter(p) ) return; // only give random weapons to humans and robots + if( !IsHuman(p.class) && !IsCombatRobot(p.class) ) return; // only give random weapons to humans and robots // TODO: if p.bIsFemale then give only 1 handed weapons? - if( p.IsA('MJ12Commando') || p.IsA('WIB') ) return; + if( p.IsA('MJ12Commando') || (!#defined(injections) && p.IsA('WIB')) ) return; if( IsHuman(p.class)) { if(!p.bImportant) { diff --git a/DXRModules/DeusEx/Classes/DXREnemiesBase.uc b/DXRModules/DeusEx/Classes/DXREnemiesBase.uc index 5a8dd8bc1..7b96c85aa 100644 --- a/DXRModules/DeusEx/Classes/DXREnemiesBase.uc +++ b/DXRModules/DeusEx/Classes/DXREnemiesBase.uc @@ -184,7 +184,7 @@ function RandoCarcasses(int chance) item = c.Inventory; while( item != None ) { nextItem = item.Inventory; - if( chance_single(50) && !item.IsA('NanoKey') ) { + if( chance_single(50) && #var(prefix)NanoKey(item)==None && #var(prefix)AugmentationCannister(item)==None && #var(prefix)AugmentationUpgradeCannister(item)==None ) { c.DeleteInventory(item); item.Destroy(); } @@ -244,6 +244,7 @@ function ScriptedPawn CloneScriptedPawn(ScriptedPawn p, optional class 160) { @@ -315,9 +326,11 @@ function ScriptedPawn CloneScriptedPawn(ScriptedPawn p, optional class 0) { + b.ChangeAlly(a.InitialAlliances[i].AllianceName, a.InitialAlliances[i].AllianceLevel, a.InitialAlliances[i].bPermanent); + } + if(b.InitialAlliances[i].AllianceName != '' && b.InitialAlliances[i].AllianceLevel > 0) { + a.ChangeAlly(b.InitialAlliances[i].AllianceName, b.InitialAlliances[i].AllianceLevel, b.InitialAlliances[i].bPermanent); + } + } +} function SwapOrders(ScriptedPawn a, ScriptedPawn b) { @@ -41,9 +59,20 @@ function SwapOrders(ScriptedPawn a, ScriptedPawn b) function bool ShouldSwap(ScriptedPawn a, ScriptedPawn b) { // always ok to swap with a placeholder enemy - if(PlaceholderEnemy(a) != None || PlaceholderEnemy(b) != None) return true; + if((PlaceholderEnemy(a) != None && a.Alliance=='') || (PlaceholderEnemy(b) != None && b.Alliance=='')) return true; // otherwise check alliance - return a.GetAllianceType( b.Alliance ) != ALLIANCE_Hostile && b.GetAllianceType( a.Alliance ) != ALLIANCE_Hostile; + return a.GetAllianceType( b.Alliance ) == ALLIANCE_Friendly && b.GetAllianceType( a.Alliance ) == ALLIANCE_Friendly; +} + +function bool CanSit(ScriptedPawn sp) +{ + if (#var(prefix)MJ12Commando(sp) != None) return False; + if (#var(prefix)SpiderBot2(sp) != None) return True; //Small spiderbots are very funny in chairs + if (#var(prefix)Robot(sp) != None) return False; //Normal robots are lame in chairs + if (#var(prefix)ChildMale(sp) != None) return False; //Kids don't have sitting animations + if (#var(prefix)ChildMale2(sp) != None) return False; //(They probably aren't getting shuffled, but might as well note it) + //Animals don't have any special sitting animations, but are very funny also + return True; } function SwapScriptedPawns(int percent, bool enemies) @@ -56,6 +85,11 @@ function SwapScriptedPawns(int percent, bool enemies) num=0; switch(dxr.localURL) { + case "04_NYC_NSFHQ": + if(enemies) + SwapScriptedPawns(percent, false); + break; + case "06_HONGKONG_MJ12LAB": if(enemies) SwapScriptedPawns(percent, false); @@ -81,7 +115,7 @@ function SwapScriptedPawns(int percent, bool enemies) { if( a.bHidden || a.bStatic ) continue; if( a.bImportant || a.bIsSecretGoal ) continue; - if( IsCritter(a) ) continue; + if( !IsRelevantPawn(a.class) ) continue; if( IsInitialEnemy(a) != enemies ) continue; if( !chance_single(percent) ) continue; if( a.Region.Zone.bWaterZone || a.Region.Zone.bPainZone ) continue; @@ -128,13 +162,14 @@ function SwapScriptedPawns(int percent, bool enemies) SwapProperty(temp[i], temp[slot], "HomeExtent"); SwapProperty(temp[i], temp[slot], "bUseHome"); SwapProperty(temp[i], temp[slot], "RaiseAlarm"); + MergeAlliances(temp[i], temp[slot]); SwapOrders(temp[i], temp[slot]); } for(i=0; i 0) { BingoWinScreen(); bingo_win_countdown--; @@ -661,12 +668,13 @@ function _AddPawnDeath(ScriptedPawn victim, optional Actor Killer, optional coer class'DXRStats'.static.AddKill(player()); //Were they an ally? Skip on NSF HQ, because that's kind of a bait - if (!isInitialPlayerEnemy(victim) && !IsCritter(victim) && //Must have not been an enemy initially - (dxr.localURL!="04_NYC_NSFHQ" || (dxr.localURL=="04_NYC_NSFHQ" && dxr.flagbase.GetBool('DL_SimonsPissed_Played')==False)) //Not on the NSF HQ map, or if it is, before you send the signal (kludgy) - ){ + if ( + !isInitialPlayerEnemy(victim) && //Must have not been an enemy initially + IsHuman(victim.class) && //There's no such thing as an innocent Cat + ( dxr.localURL!="04_NYC_NSFHQ" || dxr.flagbase.GetBool('NSFSignalSent')==False ) //Not on the NSF HQ map, or if it is, before you send the signal (kludgy) + ) { _MarkBingo("AlliesKilled"); } - } if (damageType=="stomped" && IsHuman(victim.class)){ //If you stomp a human to death... _MarkBingo("HumanStompDeath"); @@ -749,6 +757,11 @@ static function BeatGame(DXRando dxr, int ending) local class js; js = class'Json'; + // Mark the rando as having been beaten, affects dialogs on the new game menu. + dxr.rando_beaten = Max(1, dxr.rando_beaten + 1); + dxr.rando_beaten = Min(2000000000, dxr.rando_beaten);// Make sure you can beat the game over 2 billion times without overflow issues. + dxr.SaveConfig(); + stats = DXRStats(dxr.FindModule(class'DXRStats')); j = js.static.Start("BeatGame"); diff --git a/DXRModules/DeusEx/Classes/DXRFixup.uc b/DXRModules/DeusEx/Classes/DXRFixup.uc index 8ee5137fc..bce582d80 100644 --- a/DXRModules/DeusEx/Classes/DXRFixup.uc +++ b/DXRModules/DeusEx/Classes/DXRFixup.uc @@ -199,6 +199,7 @@ function PreFirstEntry() OverwriteDecorations(); FixFlagTriggers(); + FixBeamLaserTriggers(); SpawnDatacubes(); AntiEpilepsy(); @@ -260,7 +261,7 @@ function ShowTeleporters() local #var(prefix)Teleporter t; local int show_teleporters; - show_teleporters = int(ConsoleCommand("get #var(package).MenuChoice_ShowTeleporters show_teleporters")); + show_teleporters = class'MenuChoice_ShowTeleporters'.default.show_teleporters; foreach AllActors(class'#var(prefix)Teleporter', t) { t.bHidden = !(t.bCollideActors && t.bEnabled && show_teleporters>0); @@ -579,6 +580,7 @@ function OverwriteDecorations() for(i=0; i < ArrayCount(DecorationsOverwrites); i++) { if(DecorationsOverwritesClasses[i] == None) continue; if( d.IsA(DecorationsOverwritesClasses[i].name) == false ) continue; + if( d.bIsSecretGoal == True) continue; d.bInvincible = DecorationsOverwrites[i].bInvincible; d.HitPoints = DecorationsOverwrites[i].HitPoints; d.minDamageThreshold = DecorationsOverwrites[i].minDamageThreshold; @@ -611,6 +613,21 @@ function FixFlagTriggers() } } +function FixBeamLaserTriggers() +{ +#ifdef fixes + local #var(prefix)BeamTrigger bt; + local #var(prefix)LaserTrigger lt; + + foreach AllActors(class'#var(prefix)BeamTrigger',bt){ + bt.TriggerType=TT_AnyProximity; + } + foreach AllActors(class'#var(prefix)LaserTrigger',lt){ + lt.TriggerType=TT_AnyProximity; + } +#endif +} + function SpawnDatacubes() { #ifdef injections @@ -659,7 +676,7 @@ function AntiEpilepsy() { local Light l; - if (!bool(ConsoleCommand("get #var(package).MenuChoice_Epilepsy enabled"))){ + if (!class'MenuChoice_Epilepsy'.default.enabled){ return; } diff --git a/DXRModules/DeusEx/Classes/DXRFlags.uc b/DXRModules/DeusEx/Classes/DXRFlags.uc index b6726f2eb..f88129706 100644 --- a/DXRModules/DeusEx/Classes/DXRFlags.uc +++ b/DXRModules/DeusEx/Classes/DXRFlags.uc @@ -35,12 +35,10 @@ simulated function PlayerAnyEntry(#var(PlayerPawn) p) p.bCheatsEnabled = true; if(difficulty_names[difficulty] == "Super Easy QA" && dxr.dxInfo.missionNumber > 0 && dxr.dxInfo.missionNumber < 99) { + p.bCheatsEnabled = true; p.ReducedDamageType = 'All';// god mode p.AllWeapons(); p.AllAmmo(); - if(dxr.localURL == "01_NYC_UNATCOISLAND") { - p.ConsoleCommand("legend"); - } #ifdef injections autosave = DXRAutosave(dxr.FindModule(class'DXRAutosave')); @@ -191,7 +189,7 @@ function CheckConfig() difficulty_names[i] = "Easy"; #else difficulty_names[i] = "Normal"; - difficulty_settings[i].CombatDifficulty = 1.2; + difficulty_settings[i].CombatDifficulty = 1.3; #endif difficulty_settings[i].doorsmode = undefeatabledoors + doormutuallyinclusive; difficulty_settings[i].doorsdestructible = 100; @@ -227,7 +225,7 @@ function CheckConfig() difficulty_settings[i].goals = 100; difficulty_settings[i].equipment = 4; difficulty_settings[i].medbots = 35; - more_difficulty_settings[i].empty_medbots = 15; + more_difficulty_settings[i].empty_medbots = 20; difficulty_settings[i].repairbots = 35; difficulty_settings[i].medbotuses = 10; difficulty_settings[i].repairbotuses = 10; @@ -262,7 +260,7 @@ function CheckConfig() difficulty_names[i] = "Medium"; #else difficulty_names[i] = "Hard"; - difficulty_settings[i].CombatDifficulty = 1.7; + difficulty_settings[i].CombatDifficulty = 2; #endif difficulty_settings[i].doorsmode = undefeatabledoors + doorindependent; difficulty_settings[i].doorsdestructible = 40; @@ -298,7 +296,7 @@ function CheckConfig() difficulty_settings[i].goals = 100; difficulty_settings[i].equipment = 2; difficulty_settings[i].medbots = 27; - more_difficulty_settings[i].empty_medbots = 15; + more_difficulty_settings[i].empty_medbots = 20; difficulty_settings[i].repairbots = 27; difficulty_settings[i].medbotuses = 5; difficulty_settings[i].repairbotuses = 5; @@ -333,7 +331,7 @@ function CheckConfig() difficulty_names[i] = "Hard"; #else difficulty_names[i] = "Extreme"; - difficulty_settings[i].CombatDifficulty = 2.3; + difficulty_settings[i].CombatDifficulty = 3; #endif difficulty_settings[i].doorsmode = undefeatabledoors + doorindependent; difficulty_settings[i].doorsdestructible = 25; @@ -359,7 +357,7 @@ function CheckConfig() difficulty_settings[i].banned_skill_levels = 7; difficulty_settings[i].minskill = 50; difficulty_settings[i].maxskill = 250; - difficulty_settings[i].ammo = 60; + difficulty_settings[i].ammo = 65; difficulty_settings[i].medkits = 60; difficulty_settings[i].biocells = 50; difficulty_settings[i].lockpicks = 60; @@ -369,7 +367,7 @@ function CheckConfig() difficulty_settings[i].goals = 100; difficulty_settings[i].equipment = 1; difficulty_settings[i].medbots = 25; - more_difficulty_settings[i].empty_medbots = 15; + more_difficulty_settings[i].empty_medbots = 20; difficulty_settings[i].repairbots = 25; difficulty_settings[i].medbotuses = 2; difficulty_settings[i].repairbotuses = 2; @@ -404,7 +402,7 @@ function CheckConfig() difficulty_names[i] = "DeusEx"; #else difficulty_names[i] = "Impossible"; - difficulty_settings[i].CombatDifficulty = 3; + difficulty_settings[i].CombatDifficulty = 4; #endif difficulty_settings[i].doorsmode = undefeatabledoors + doorindependent; difficulty_settings[i].doorsdestructible = 25; @@ -426,13 +424,13 @@ function CheckConfig() difficulty_settings[i].skills_disable_downgrades = 5; difficulty_settings[i].skills_reroll_missions = 5; difficulty_settings[i].skills_independent_levels = 100; - difficulty_settings[i].banned_skills = 13; - difficulty_settings[i].banned_skill_levels = 7; + difficulty_settings[i].banned_skills = 9; + difficulty_settings[i].banned_skill_levels = 9; difficulty_settings[i].minskill = 50; - difficulty_settings[i].maxskill = 350; - difficulty_settings[i].ammo = 40; + difficulty_settings[i].maxskill = 300; + difficulty_settings[i].ammo = 50; difficulty_settings[i].medkits = 50; - difficulty_settings[i].biocells = 30; + difficulty_settings[i].biocells = 40; difficulty_settings[i].lockpicks = 50; difficulty_settings[i].multitools = 50; difficulty_settings[i].speedlevel = 1; @@ -440,7 +438,7 @@ function CheckConfig() difficulty_settings[i].goals = 100; difficulty_settings[i].equipment = 1; difficulty_settings[i].medbots = 20; - more_difficulty_settings[i].empty_medbots = 15; + more_difficulty_settings[i].empty_medbots = 20; difficulty_settings[i].repairbots = 20; difficulty_settings[i].medbotuses = 1; difficulty_settings[i].repairbotuses = 1; @@ -493,14 +491,11 @@ function MoreFlagsSettings GetMoreDifficulty(int diff) function FlagsSettings SetDifficulty(int new_difficulty) { - local bool memes_enabled; - difficulty = new_difficulty; settings = difficulty_settings[difficulty]; moresettings = more_difficulty_settings[difficulty]; - memes_enabled = bool(ConsoleCommand("get #var(package).MenuChoice_ToggleMemes enabled")); - if(!memes_enabled) settings.dancingpercent = 0; + if(!class'MenuChoice_ToggleMemes'.default.enabled) settings.dancingpercent = 0; if(IsReducedRando()) { settings.doorsmode = 0; @@ -586,7 +581,7 @@ function FlagsSettings SetDifficulty(int new_difficulty) } else if(gamemode == SeriousSam) { #ifndef hx - settings.CombatDifficulty *= 0.1; + settings.CombatDifficulty *= 0.2; #endif settings.enemiesrandomized = 1000; settings.hiddenenemiesrandomized = 1000; @@ -633,6 +628,11 @@ function FlagsSettings SetDifficulty(int new_difficulty) l("applying WaltonWare, DXRando: " $ dxr @ dxr.seed); settings.starting_map = class'DXRStartMap'.static.ChooseRandomStartMap(self, 10); } + else if(IsHordeMode()) { +#ifndef hx + settings.CombatDifficulty *= 0.75; +#endif + } return settings; } @@ -895,4 +895,18 @@ function RunTests() function ExtendedTests() { Super.ExtendedTests(); + + gamemode = 0; + testint(moresettings.remove_paris_mj12, 0, "check remove_paris_mj12"); + moresettings.remove_paris_mj12 = 50; + SetDifficulty(0); + testint(settings.bingo_freespaces, 1, "SetDifficulty check bingo_freespaces"); + testint(Settings.spoilers, 1, "SetDifficulty check spoilers"); + testint(Settings.menus_pause, 1, "SetDifficulty check menus_pause"); + testint(settings.health, 200, "SetDifficulty check health"); + testint(settings.energy, 200, "SetDifficulty check energy"); + testint(moresettings.remove_paris_mj12, 0, "SetDifficulty check remove_paris_mj12"); + SetDifficulty(1); + testint(settings.health, 100, "SetDifficulty check health"); + testint(settings.energy, 100, "SetDifficulty check energy"); } diff --git a/DXRModules/DeusEx/Classes/DXRFlagsBase.uc b/DXRModules/DeusEx/Classes/DXRFlagsBase.uc index e30c1ecdb..de16c348d 100644 --- a/DXRModules/DeusEx/Classes/DXRFlagsBase.uc +++ b/DXRModules/DeusEx/Classes/DXRFlagsBase.uc @@ -179,9 +179,12 @@ function AnyEntry() function RollSeed() { seed = dxr.Crc( Rand(MaxInt) @ (FRand()*1000000) @ (Level.TimeSeconds*1000) ); - seed = abs(seed) % 1000000; dxr.seed = seed; + dxr.tseed = seed; bSetSeed = 0; + seed = rng(1000000); + dxr.seed = seed; + dxr.tseed = seed; } #ifdef hx @@ -859,7 +862,7 @@ simulated function string flagValToHumanVal(name flagname, int val){ break; case 'Rando_starting_map': - return class'DXRStartMap'.static.GetStartingMapName(val); + return class'DXRStartMap'.static.GetStartingMapNameCredits(val); break; default: return val $ " (Unhandled!)"; @@ -1036,18 +1039,21 @@ function RunTests() t=rng(100); test( t >=0 && t < 100, "rng(100) got " $t$" >= 0 and < 100"); } + dxr.SetSeed(-111); i = rng(100); test( rng(100) != i, "rng(100) != rng(100)"); - dxr.SetSeed(111); + dxr.SetSeed(72665856); testbool( chance_single(0), false, "chance_single(0)"); testbool( chance_single(1), false, "chance_single(1)"); + testbool( chance_single(99), true, "chance_single(99)"); testbool( chance_single(100), true, "chance_single(100)"); - testbool( chance_single(50), true, "chance_single(50) 1"); - testbool( chance_single(50), false, "chance_single(50) 2"); + testbool( chance_single(50), false, "chance_single(50) 1"); + testbool( chance_single(50), true, "chance_single(50) 2"); testbool( chance_single(50), true, "chance_single(50) 3"); - testbool( chance_single(50), false, "chance_single(50) 4"); + testbool( chance_single(50), true, "chance_single(50) 4"); + testbool( chance_single(50), false, "chance_single(50) 5"); teststring( FloatToString(0.5555, 1), "0.6", "FloatToString 1"); teststring( FloatToString(0.5454999, 4), "0.5455", "FloatToString 2"); @@ -1064,9 +1070,9 @@ function RunTests() function ExtendedTests() { - local int i, total; + local int i, t, total, a[16]; local float f; - local string credits_text; + local string text; Super.ExtendedTests(); testint(FindLast("this is a test", "nope"), -1, "FindLast"); @@ -1078,6 +1084,34 @@ function ExtendedTests() TestRngExp(0, 1, 0.5, 1.5); + dxr.SetSeed(1112); + t=0; + for(i=0; i<100; i++) { + if(chance_single(1)) t++; + } + testint(t, 2, "chance_single(1) about 1%"); + t=0; + for(i=0; i<100; i++) { + if(chance_single(50)) t++; + } + testint(t, 46, "chance_single(50) about 50%"); + t=0; + for(i=0; i<100; i++) { + if(chance_single(99)) t++; + } + testint(t, 98, "chance_single(99) about 99%"); + + dxr.SetSeed(1112); + for(i=0;i<1000;i++) { + t = rng(3); + a[t]++; + test(t >= 0, "rng(3) >= 0"); + } + testint(a[0], 329, "rng(3) == 0"); + testint(a[1], 325, "rng(3) == 1"); + testint(a[2], 346, "rng(3) == 2"); + testint(a[3], 0, "rng(3) != 3"); + for(i=1;i<=4;i++) TestRngExp(25, 300, 100, i); for(i=1;i<=4;i++) @@ -1109,11 +1143,12 @@ function ExtendedTests() TestTime(); TestStorage(); + TestRollSeed(); - credits_text = StringifyFlags(Credits); - test( InStr(credits_text, "(ADD HUMAN READABLE NAME!)") == -1, "Credits does not contain (ADD HUMAN READABLE NAME!)"); - test( InStr(credits_text, "(Unhandled!)") == -1, "Credits does not contain (Unhandled!)"); - test( InStr(credits_text, "(Mishandled!)") == -1, "Credits does not contain (Mishandled!)"); + text = StringifyFlags(Credits); + test( InStr(text, "(ADD HUMAN READABLE NAME!)") == -1, "Credits does not contain (ADD HUMAN READABLE NAME!)"); + test( InStr(text, "(Unhandled!)") == -1, "Credits does not contain (Unhandled!)"); + test( InStr(text, "(Mishandled!)") == -1, "Credits does not contain (Mishandled!)"); teststring(ToHex(0), "0", "ToHex(0)"); teststring(ToHex(0xF), "F", "ToHex(0xF)"); @@ -1121,19 +1156,8 @@ function ExtendedTests() teststring(ToHex(0x100F), "100F", "ToHex(0x100F)"); teststring(ToHex(0x9001F), "9001F", "ToHex(0x9001F)"); - gamemode = 0; - testint(moresettings.remove_paris_mj12, 0, "check remove_paris_mj12"); - moresettings.remove_paris_mj12 = 50; - SetDifficulty(0); - testint(settings.bingo_freespaces, 1, "SetDifficulty check bingo_freespaces"); - testint(Settings.spoilers, 1, "SetDifficulty check spoilers"); - testint(Settings.menus_pause, 1, "SetDifficulty check menus_pause"); - testint(settings.health, 200, "SetDifficulty check health"); - testint(settings.energy, 200, "SetDifficulty check energy"); - testint(moresettings.remove_paris_mj12, 0, "SetDifficulty check remove_paris_mj12"); - SetDifficulty(1); - testint(settings.health, 100, "SetDifficulty check health"); - testint(settings.energy, 100, "SetDifficulty check energy"); + text = VersionString(); + testbool(VersionIsStable(), InStr(text, "Alpha")==-1 && InStr(text, "Beta")==-1, "VersionIsStable() matches version text, " $ text); } function TestTime() @@ -1270,3 +1294,23 @@ function TestRngExp(float minrange, float maxrange, float mid, float curve) test( lows > times/10, "exponential ^"$curve$" - lows "$lows$" > times/8 "$(times/10)); test( highs > times/10, "exponential ^"$curve$" - highs "$highs$" > times/8 "$(times/10)); } + +function TestRollSeed() +{ + local int i, b, t, a[32]; + + for(i=0; i<1000; i++) { + RollSeed(); + for(b=0; b<32; b++) { + t = seed & (1< 400 && a[b] < 600, "RollSeed bit "$b$" hit "$a[b]$" times"); + } + for(b=20; b<32; b++) { + test(a[b] == 0, "RollSeed bit "$b$" hit "$a[b]$" times"); + } +} diff --git a/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc b/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc index c8d63d085..e9f86f9a1 100644 --- a/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc +++ b/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc @@ -160,7 +160,7 @@ function NewGamePlus() local DataStorage ds; local DXRSkills skills; local DXRAugmentations augs; - local int i, bingo_win, bingo_freespaces; + local int i, bingo_win, bingo_freespaces, newgameplus_curve_scalar; local float exp; local int randomStart; local int oldseed; @@ -190,16 +190,19 @@ function NewGamePlus() // we only want to do this on maxrando because we want to retain the user's custom choices bingo_win = settings.bingo_win; bingo_freespaces = settings.bingo_freespaces; + newgameplus_curve_scalar = moresettings.newgameplus_curve_scalar; SetDifficulty(difficulty); ExecMaxRando(); settings.bingo_win = bingo_win; settings.bingo_freespaces = bingo_freespaces; + moresettings.newgameplus_curve_scalar = newgameplus_curve_scalar; // increase difficulty on each flag like exp = newgameplus_loops; x *= 1.2 ^ exp; exp = newgameplus_loops; } dxr.SetSeed(dxr.Crc("NG+ curve tweak " $ (seed - newgameplus_loops))); + rng(9);// advance the rng #ifdef hx p.CombatDifficulty = 3;// I don't think NG+ works in HX anyways? #else diff --git a/DXRModules/DeusEx/Classes/DXRHints.uc b/DXRModules/DeusEx/Classes/DXRHints.uc index c052cd48a..dae680730 100644 --- a/DXRModules/DeusEx/Classes/DXRHints.uc +++ b/DXRModules/DeusEx/Classes/DXRHints.uc @@ -50,6 +50,28 @@ simulated function InitHints() AddHint("Weapon animation speeds now improve with skills,", "especially grenades with Demolition skill."); AddHint("Grenades can now be attached to the floor", "or even on a door!"); AddHint("Attaching a grenade to a wall increases its", "blast radius and damage, especially with high skill."); + AddHint("You can safely save during infolinks!", "Give it a shot, Tong won't mind!"); + AddHint("Red lasers will always set off an alarm", "Blue lasers won't, but will trigger something else!"); + AddHint("Everything except an NPC will set off a laser!", "Better be careful around them!"); + AddHint("Enemies with gold visors are resistant to gas", "so you might need to deal with them differently!"); + AddHint("Enemies with helmets take less damage from headshots", "so you might need to be more careful!"); + if (class'MenuChoice_AutoWeaponMods'.default.enabled){ + AddHint("Picking up a weapon mod while holding a weapon", "will automatically apply it to that weapon!"); + } + } + + if(mission <= 3) { + if(dxr.flags.settings.enemiesrandomized > 0) { + AddHint("Some NSF terrorists are visibly augmented.", "Watch out for their special capabilities!"); + } + } else if(mission <= 4) { + if(dxr.flags.settings.enemiesrandomized > 0) { + AddHint("Some UNATCO troops are visibly augmented.", "They explode when they die, so watch out!"); + } + } else { + if(dxr.flags.settings.enemiesrandomized > 0) { + AddHint("Some UNATCO and MJ12 troops are visibly augmented.", "They explode when they die, so watch out!"); + } } if(mission <= 5) { @@ -60,7 +82,9 @@ simulated function InitHints() AddHint("Use everything at your disposal, like TNT crates.", "Randomizer makes this even more of a strategy/puzzle game."); AddHint("A vending machine can provide you with 20 health worth of food.", "Eat up!"); AddHint("Pepper spray and fire extinguishers can incapacitate an enemy", "letting you sneak past them."); - AddHint("The large metal crates are now destructible.", "They have 500 hp."); + AddHint("The medium and large metal crates are now destructible.", "They have 500 hp."); + AddHint("Datacubes and nanokeys give off a glow.", "Keep your eyes open for it!"); + if(!dxr.flags.IsZeroRando()) AddHint("Make sure to read the descriptions for skills, augs, and items.", "Randomizer adds some extra info."); if(dxr.flags.settings.min_weapon_dmg != dxr.flags.settings.max_weapon_dmg || dxr.flags.settings.min_weapon_shottime != dxr.flags.settings.max_weapon_shottime) @@ -172,8 +196,12 @@ simulated function InitHints() if(map ~= "01_NYC_UNATCOIsland") { if(dxr.flags.settings.passwordsrandomized > 0) AddHint("Passwords have been randomized.", "Don't even try smashthestate!"); - if(dxr.flags.settings.goals > 0) + if(dxr.flags.settings.goals > 0){ AddHint("The locations of the terrorist commander and boat are randomized.", "Check the Goal Randomization page on our Wiki."); + if(#defined(injections)) { + AddHint("The map of the island can show possible goal locations.", "Give it a try!"); + } + } } break; @@ -202,8 +230,12 @@ simulated function InitHints() AddHint("The locations of some NPCs on this map are randomized.", "Check the Goal Randomization page on our Wiki."); break; case "03_NYC_Airfield": - if(dxr.flags.settings.goals > 0) - AddHint("The location of the NSF soldier with the Easy Gate key is randomized.", "Check the Goal Randomization page on our Wiki."); + if(dxr.flags.settings.goals > 0){ + AddHint("The location of the NSF soldier with the East Gate key is randomized.", "Check the Goal Randomization page on our Wiki."); + if(#defined(injections)) { + AddHint("The map of the airfield can show possible goal locations.", "Give it a try!"); + } + } break; case "03_NYC_747": AddHint("Anna will no longer trigger a LAM", "while she's allied to you!"); @@ -213,8 +245,10 @@ simulated function InitHints() case 4: if (map ~= "04_NYC_NSFHQ") { - if(dxr.flags.settings.goals > 0) - AddHint("The location of the computer to open the door is randomized.", "Check the Goal Randomization page on our Wiki."); + if(dxr.flags.settings.goals > 0){ + AddHint("The location of the computer to align the satellites is randomized.", "Check the Goal Randomization page on our Wiki."); + AddHint("The location of the computer to send the signal is randomized.", "Check the Goal Randomization page on our Wiki."); + } } else if(dxr.flags.settings.goals > 0) { AddHint("Anna Navarre's location is randomized.", "Check the Goal Randomization page on our Wiki."); } @@ -225,6 +259,9 @@ simulated function InitHints() if(dxr.flags.settings.goals > 0) { AddHint("Paul's location in the lab is randomized.", "Check the Goal Randomization page on our Wiki."); AddHint("Your equipment could be in either", "the armory, or the surgery ward."); + if(#defined(injections)) { + AddHint("The map of the lab can show possible goal locations.", "Give it a try!"); + } } } else if (map ~= "05_NYC_UnatcoHQ") { if(dxr.flags.settings.goals > 0) { @@ -256,8 +293,11 @@ simulated function InitHints() break; case 8: - if(dxr.flags.settings.goals > 0) + if(dxr.flags.settings.goals > 0){ AddHint("The locations of Filben, Greene, and Vinny are randomized.", "Check the Goal Randomization page on our Wiki."); + AddHint("The start location of the raid has been randomized.", "Look for the black vans!"); + AddHint("The location of Jock when leaving is randomized.", "Check the Goal Randomization page on our Wiki."); + } break; case 9: @@ -265,8 +305,13 @@ simulated function InitHints() if(dxr.flags.settings.goals > 0) AddHint("The location of the signal jammer is randomized.", "Check the Goal Randomization page on our Wiki."); } else if (map ~= "09_nyc_shipbelow") { - if(dxr.flags.settings.goals > 0) + if(dxr.flags.settings.goals > 0){ AddHint("The locations of the tri-hull weld points are randomized.", "Check the Goal Randomization page on our Wiki."); + AddHint("The location of the bilge pump computer is randomized.", "Check the Goal Randomization page on our Wiki."); + if(#defined(injections)) { + AddHint("The map of the ship can show possible goal locations.", " Give it a try!"); + } + } } else if (map ~= "09_nyc_dockyard") { if(dxr.flags.settings.goals > 0) { if(dxr.flagbase.GetBool('MS_ShipBreeched')) @@ -292,6 +337,16 @@ simulated function InitHints() } if(dxr.flags.settings.goals > 0 && (map ~= "10_paris_metro" || map ~= "10_paris_club")) { AddHint("The location of Nicolette DuClare is randomized.", "Check the Goal Randomization page on our Wiki."); + if(#defined(injections)) { + AddHint("The street map can show possible goal locations.", "Give it a try!"); + } + } + if(dxr.flags.settings.goals > 0 && (map ~= "10_Paris_Catacombs_Tunnels")) { + if(#defined(injections)) { + AddHint("The map of the catacombs can show possible goal locations.", "Give it a try!"); + } + AddHint("Agent Hela will always have two copies of the sewer key.", "She will be carrying one and keep another nearby."); + AddHint("The location of Agent Hela is randomized.", "Check the Goal Randomization page on our Wiki."); } break; @@ -327,6 +382,7 @@ simulated function InitHints() if (map ~= "14_oceanlab_silo") { if(dxr.flags.settings.goals > 0) { AddHint("Howard Strong is now on a random floor of the missile silo.", "Check the Goal Randomization page on our Wiki."); + AddHint("Howard Strong will only show up if you've done your objectives!", "Been to the Ocean Lab UC, merged Helios, and redirected the missile?"); AddHint("Jock will pick you up at a random location.", "Check the Goal Randomization page on our Wiki."); } } diff --git a/DXRModules/DeusEx/Classes/DXRHordeMode.uc b/DXRModules/DeusEx/Classes/DXRHordeMode.uc index 69d08f3ca..e9ff30e16 100644 --- a/DXRModules/DeusEx/Classes/DXRHordeMode.uc +++ b/DXRModules/DeusEx/Classes/DXRHordeMode.uc @@ -19,9 +19,9 @@ var config int wine_bottles_per_enemy; var config name default_orders; var config name default_order_tag; var config string map_name; -var config name remove_objects[12]; +var config name remove_objects[16]; var config name unlock_doors[8]; -var config name lock_doors[8]; +var config name lock_doors[16]; var config vector starting_location; struct EnemyChances { @@ -43,7 +43,7 @@ var config ItemChances items[32]; function CheckConfig() { local int i; - if( ConfigOlderThan(2,4,0,1) ) { + if( ConfigOlderThan(2,6,0,2) ) { time_between_waves = 65; time_before_damage = 180; damage_timer = 10; @@ -143,11 +143,11 @@ function CheckConfig() enemies[i].chance = 3; enemies[i].minWave = 4; enemies[i].difficulty = 2; - /*i++; - enemies[i].type = "WIB";//bugged animations? + i++; + enemies[i].type = "WIB"; enemies[i].chance = 2; enemies[i].minWave = 4; - enemies[i].difficulty = 2;*/ + enemies[i].difficulty = 2; i++; enemies[i].type = "SpiderBot2"; enemies[i].chance = 2; @@ -235,7 +235,7 @@ function CheckConfig() items[i].chance = 3; map_name = "11_paris_cathedral"; - starting_location = vectm(-3811.785156, 2170.053223, -774.903442); + starting_location = vect(-3811.785156, 2170.053223, -774.903442); default_orders = 'Attacking'; default_order_tag = ''; @@ -252,6 +252,10 @@ function CheckConfig() lock_doors[i++] = 'BreakableGlass1'; lock_doors[i++] = 'BreakableGlass2'; lock_doors[i++] = 'BreakableGlass3'; + lock_doors[i++] = 'BreakableGlass4'; + lock_doors[i++] = 'BreakableGlass5'; + lock_doors[i++] = 'BreakableGlass6'; + lock_doors[i++] = 'BreakableGlass7'; lock_doors[i++] = 'DeusExMover8'; lock_doors[i++] = 'DeusExMover9'; lock_doors[i++] = 'DeusExMover17'; @@ -275,11 +279,17 @@ function AnyEntry() local DeusExMover d; local DXREnemies dxre; local Inventory item; + local DXRMapVariants mapvariants; local int i; if( !dxr.flags.IsHordeMode() ) return; Super.AnyEntry(); + if( dxr.dxInfo.missionNumber>0 && dxr.localURL != map_name ) { + mapvariants = DXRMapVariants(dxr.FindModule(class'DXRMapVariants')); + if(mapvariants != None) { + map_name = mapvariants.VaryMap(map_name); + } Level.Game.SendPlayer(player(), map_name); return; } @@ -287,6 +297,7 @@ function AnyEntry() return; } + starting_location = vectm(starting_location.X, starting_location.Y, starting_location.Z); player().SetLocation(starting_location); dxre = DXREnemies(dxr.FindModule(class'DXREnemies')); diff --git a/DXRModules/DeusEx/Classes/DXRKeys.uc b/DXRModules/DeusEx/Classes/DXRKeys.uc index fb9ceb2da..997e48da5 100644 --- a/DXRModules/DeusEx/Classes/DXRKeys.uc +++ b/DXRModules/DeusEx/Classes/DXRKeys.uc @@ -119,6 +119,13 @@ function vanilla_keys_rules() break; case "04_NYC_NSFHQ": + // don't allow the basement door key to be in the vanilla transmit signal room or the basement + keys_rules[i].item_name = 'BasementDoor'; + keys_rules[i].min_pos = vect(100, 329, 1010); + keys_rules[i].max_pos = vect(116, 345, 1050); + keys_rules[i].allow = false; + i++; + keys_rules[i].item_name = 'BasementDoor'; keys_rules[i].min_pos = vect(-99999, -99999, 0); keys_rules[i].max_pos = vect(99999, 99999, 99999); @@ -291,6 +298,20 @@ function vanilla_keys_rules() keys_rules[i].allow = false; i++; + //Disallow on the upper shelves in the pit + keys_rules[i].item_name = 'control_room'; + keys_rules[i].min_pos = vect(-132, 1761, -2830); + keys_rules[i].max_pos = vect(-724, 2233, -2640); + keys_rules[i].allow = false; + i++; + + //Disallow on the upper shelves in the pit + keys_rules[i].item_name = 'maintenancekey'; + keys_rules[i].min_pos = vect(-132, 1761, -2830); + keys_rules[i].max_pos = vect(-724, 2233, -2640); + keys_rules[i].allow = false; + i++; + keys_rules[i].item_name = 'maintenancekey'; keys_rules[i].min_pos = vect(-3521.955078, 3413.110352, -3246.771729); keys_rules[i].max_pos = vect(-2844.053467, 3756.776855, -3097.210205); @@ -303,6 +324,12 @@ function vanilla_keys_rules() keys_rules[i].allow = true; i++; + keys_rules[i].item_name = 'maintenancekey'; + keys_rules[i].min_pos = vect(-1631, -99999, -99999); + keys_rules[i].max_pos = vect(99999, 2971, 99999); + keys_rules[i].allow = false; + i++; + keys_rules[i].item_name = 'maintenancekey'; keys_rules[i].min_pos = vect(-99999, -99999, -99999); keys_rules[i].max_pos = vect(99999, 99999, 99999); @@ -883,7 +910,7 @@ function RandoKey(#var(prefix)NanoKey k) if( dxr.flags.settings.keysrando == 4 || dxr.flags.settings.keysrando == 2 ) { oldseed = SetSeed( "RandoKey " $ k.Name ); _RandoKey(k, dxr.flags.settings.keys_containers > 0); - dxr.SetSeed(oldseed); + ReapplySeed(oldseed); } } diff --git a/DXRModules/DeusEx/Classes/DXRLoadouts.uc b/DXRModules/DeusEx/Classes/DXRLoadouts.uc index 06862d9e1..756481278 100644 --- a/DXRModules/DeusEx/Classes/DXRLoadouts.uc +++ b/DXRModules/DeusEx/Classes/DXRLoadouts.uc @@ -389,8 +389,7 @@ function bool ban(DeusExPlayer player, Inventory item) } return true; } else if(item.bDeleteMe) { - bFixGlitches = bool(ConsoleCommand("get #var(package).MenuChoice_FixGlitches enabled")); - if(bFixGlitches) { + if(class'MenuChoice_FixGlitches'.default.enabled) { return true; } else { @@ -425,8 +424,8 @@ function NinjaAdjustWeapon(DeusExWeapon w) ws.default.blood_mult = 3; ws.anim_speed = 1.2; ws.default.anim_speed = 1.2; - w.ShotTime=0; - w.default.ShotTime=0; + w.ShotTime=0.01; + w.default.ShotTime=0.01; w.maxRange = 110; w.default.maxRange = 110; w.AccurateRange = 110; @@ -435,8 +434,8 @@ function NinjaAdjustWeapon(DeusExWeapon w) case class'WeaponNanoSword': ws.blood_mult = 4; ws.default.blood_mult = 4; - w.ShotTime=0; - w.default.ShotTime=0; + w.ShotTime=0.01; + w.default.ShotTime=0.01; w.maxRange = 110; w.default.maxRange = 110; w.AccurateRange = 110; diff --git a/DXRModules/DeusEx/Classes/DXRMachines.uc b/DXRModules/DeusEx/Classes/DXRMachines.uc index 584a9758a..621911975 100644 --- a/DXRModules/DeusEx/Classes/DXRMachines.uc +++ b/DXRModules/DeusEx/Classes/DXRMachines.uc @@ -243,6 +243,39 @@ function bool GetCameraLocation(out vector loc, out rotator rotation) return true; } +function bool GetLazyCameraLocation(out vector loc, int max_range) +{ + local LocationNormal locnorm, ceiling; + local FMinMax distrange; + local float mult; + local Vector loc2; + locnorm.loc = loc; + distrange.min = 0.1; + distrange.max = 16*max_range; + + if( NearestCeiling(locnorm, distrange, 16) ) { + ceiling = locnorm; + } else { + if( ! NearestFloor(locnorm, distrange, 16) ) return false; + locnorm.loc.Z += 16*3; + ceiling = locnorm; + ceiling.loc.Z += 16*6; + } + distrange.max = 16*75; + if( ! NearestWallSearchZ(locnorm, distrange, 16*3, ceiling.loc, 10) ) return false; + + if (VSize(locnorm.loc-loc)>(max_range)){ + mult = (float(max_range)) / VSize(locnorm.loc-loc); + loc2 = (locnorm.loc-loc) * mult; + locnorm.loc = loc + loc2; + } + + loc = locnorm.loc; + + return true; +} + + function bool MoveCamera(#var(prefix)SecurityCamera c, vector loc) { local rotator rotation; @@ -298,6 +331,8 @@ function #var(injectsprefix)ComputerSecurity SpawnSecurityComputer(vector loc, o local LocationNormal locnorm; local int i; local FMinMax distrange; + local DXRPasswords pass; + info("SpawnSecurityComputer near "$loc); locnorm.loc = loc; distrange.min = 0.1; @@ -321,7 +356,13 @@ function #var(injectsprefix)ComputerSecurity SpawnSecurityComputer(vector loc, o } c.UserList[0].userName = ReplaceText(String(c.Name), "#var(injectsprefix)ComputerSecurity", "Comp"); c.itemName = c.UserList[0].userName; - c.UserList[0].Password = class'DXRPasswords'.static.GeneratePassword(dxr, dxr.localURL @ String(c.Name) ); + + pass = DXRPasswords(dxr.FindModule(class'DXRPasswords')); + if(pass != None) { + c.UserList[0].Password = pass.GeneratePassword(dxr.localURL @ String(c.Name) ); + } else { + c.UserList[0].Password = "security"; + } info("SpawnSecurityComputer "$c.UserList[0].userName$" done at ("$loc$"), ("$rotation$") with password: "$c.UserList[0].Password ); return c; } diff --git a/DXRModules/DeusEx/Classes/DXRMapInfo.uc b/DXRModules/DeusEx/Classes/DXRMapInfo.uc index 8003ba691..f1a02be4f 100644 --- a/DXRModules/DeusEx/Classes/DXRMapInfo.uc +++ b/DXRModules/DeusEx/Classes/DXRMapInfo.uc @@ -199,6 +199,8 @@ switch(mapname) case "tunnel_drop_nyc": case "unatcoisland": return "Liberty Island UNATCO Entrance"; + case "": + return "UNATCO Helipad"; } break; case "02_NYC_BAR": @@ -221,6 +223,8 @@ switch(mapname) return "Battery Park Subway"; case "BBSExit": return "Battery Park underneath Phone Booth"; + case "": + return "Battery Park"; } break; case "02_NYC_FREECLINIC": @@ -285,6 +289,8 @@ switch(mapname) case "PathNode194": case "ToStreet": return "Hells Kitchen Subway"; + case "": + return "Hells Kitchen Streets"; } break; case "02_NYC_UNDERGROUND": @@ -375,6 +381,8 @@ switch(mapname) { case "mj12": return "UNATCO MJ12 Base Entrance"; + case "": + return "UNATCO MJ12 Jail Cell"; } break; case "06_HONGKONG_HELIBASE": @@ -382,6 +390,8 @@ switch(mapname) { case "Helibase": return "MJ12 Helibase Elevator"; + case "": + return "MJ12 Helibase"; } break; case "06_HONGKONG_MJ12LAB": @@ -486,15 +496,18 @@ switch(mapname) return "Dockyard Exterior Air Conditioning Entrance"; case "ExitShip": return "Dockyard Exterior Front Door"; + case "": + return "Brooklyn Naval Shipyards"; + } + break; + case "09_NYC_GRAVEYARD": + switch(teleportername) + { + case "Entrance": + case "": + return "Graveyard"; } break; - //case "09_NYC_GRAVEYARD": - // switch(teleportername) - // { - // case "Entrance": - // return "Graveyard"; - // } - // break; case "09_NYC_SHIP": switch(teleportername) { @@ -533,6 +546,8 @@ switch(mapname) { case "spiralstair": return "Paris Exterior Spiral Staircase"; + case "": + return "Paris Denfert-Rochereau"; } break; case "10_PARIS_CATACOMBS_TUNNELS": @@ -551,6 +566,8 @@ switch(mapname) return "DuClare Estate Front Doors"; case "Light135": return "DuClare Estate Sewer Entrance"; + case "": + return "DuClare Estate"; } break; case "10_PARIS_CLUB": @@ -584,13 +601,13 @@ switch(mapname) return "Cathedral Metro Entrance"; } break; - //case "11_PARIS_EVERETT": - // switch(teleportername) - // { - // case "Entrance": - // return "Everett Main Entrance"; - // } - // break; + case "11_PARIS_EVERETT": + switch(teleportername) + { + case "Entrance": + return "Everett Main Entrance"; + } + break; case "11_PARIS_UNDERGROUND": switch(teleportername) { @@ -609,6 +626,8 @@ switch(mapname) return "Vandenberg Control Center Exterior Entrance"; case "PathNode8": return "Vandenberg Helipad"; + case "": + return "Vandenberg"; } break; case "12_VANDENBERG_COMPUTER": @@ -622,6 +641,7 @@ switch(mapname) switch(teleportername) { case "gas_start": + case "": return "Gas Station Main Entrance"; case "PathNode98": return "Gas Station Junkyard Entrance"; @@ -649,6 +669,7 @@ switch(mapname) switch(teleportername) { case "frontgate": + case "": return "Silo Front Gates"; } break; @@ -665,6 +686,7 @@ switch(mapname) case "subbay": return "Ocean Lab Shoreside Sub Bay"; case "PlayerStart": + case "": return "Ocean Lab Shoreside Helicopter"; case "InterpolationPoint39": return "Ocean Lab Shoreside Rooftop Helicopter"; @@ -676,6 +698,9 @@ switch(mapname) case "commstat": case "Light188": return "Area 51 Bunker Exterior Door"; + case "": + case "bunker_start": + return "Area 51 Bunker"; } break; case "15_AREA51_ENTRANCE": @@ -716,10 +741,11 @@ static function string GetTeleporterName(string mapname, string teleportername) teleportername = Right(teleportername,Len(teleporterName)-8); } - //Sometimes they left a .dx at the end of the map name - strip that - if (InStr(mapname,".dx")!=-1){ - mapname = Left(mapname,Len(mapname)-4); - } + //Strip a .dx from the map name if it's there + mapName = class'DXRInfo'.static.ReplaceText(mapName,".dx",""); + + //Strip any spaces that might be in the name... + mapName = class'DXRInfo'.static.ReplaceText(mapName," ",""); mapname = Caps(mapname); //Just to be sure diff --git a/DXRModules/DeusEx/Classes/DXRMapVariants.uc b/DXRModules/DeusEx/Classes/DXRMapVariants.uc index 2bce25b79..f5a7b9643 100644 --- a/DXRModules/DeusEx/Classes/DXRMapVariants.uc +++ b/DXRModules/DeusEx/Classes/DXRMapVariants.uc @@ -86,7 +86,7 @@ static function string CleanupMapName(string mapName) v = GetCoordsMult(mapName); s = GetMapPostfix(v); ret = ReplaceText(mapName, s, ""); - log("CleanupMapName ReplaceText("$mapName$", "$s$", \"\") == "$ret, 'DXRMapVariants'); + //log("CleanupMapName ReplaceText("$mapName$", "$s$", \"\") == "$ret, 'DXRMapVariants'); return ret; } diff --git a/DXRModules/DeusEx/Classes/DXRMemes.uc b/DXRModules/DeusEx/Classes/DXRMemes.uc index e471ffb51..f6ab6f1f1 100644 --- a/DXRModules/DeusEx/Classes/DXRMemes.uc +++ b/DXRModules/DeusEx/Classes/DXRMemes.uc @@ -132,60 +132,60 @@ function RandomMJ12Globe() SetGlobalSeed("RandomGlobe"); earth.bIsSecretGoal=True; - + startRot = earth.Rotation; scaleMult=1.0; if ( rng(3)!=0 && !IsAprilFools() ) return; //33% chance of getting a random globe switch(rng(16)){ - case 0: + case 0: PlayDressUp(earth,class'Basketball',0); startRot = rotm(8000,0,7000); //Give it a bit of tilt for more drama scaleMult = 2; break; - case 1: + case 1: PlayDressUp(earth,class'BoneSkull',0); startRot = rotm(0,32765,-5000); //Slightly tilted down scaleMult = 1.0; break; - case 2: + case 2: PlayDressUp(earth,class'Liquor40oz',0); startRot = rotm(0,16000,12000); scaleMult = 2; break; - case 3: + case 3: PlayDressUp(earth,class'#var(prefix)DXLogo',0); startRot = earth.Rotation; scaleMult = 3; break; - case 4: + case 4: PlayDressUp(earth,class'SodaCan',0); startRot = rotm(6000,16000,12000); scaleMult = 1.0; break; case 5: //Does this one even look good? - PlayDressUp(earth,class'BoneFemur',0); + PlayDressUp(earth,class'BoneFemur',0); startRot = rotm(0,16000,12000); scaleMult = 0.25; break; - case 6: - PlayDressUp(earth,class'ChildMale2',24000); + case 6: + PlayDressUp(earth,class'ChildMale2',24000); startRot = earth.Rotation; scaleMult = 1.5; break; - case 7: + case 7: PlayDressUp(earth,class'Trophy',0); startRot = earth.Rotation; scaleMult = 1.0; break; - case 8: - PlayDressUp(earth,class'GrayCarcass',0); + case 8: + PlayDressUp(earth,class'GrayCarcass',0); startRot = rotm(-16385,20000,0); scaleMult = 0.25; break; - case 9: - PlayDressUp(earth,class'Mutt',24000); + case 9: + PlayDressUp(earth,class'Mutt',24000); startRot = earth.Rotation; scaleMult = 1.5; break; @@ -231,12 +231,9 @@ function RandomMJ12Globe() function PreFirstEntry() { - local bool memes_enabled; - Super.PreFirstEntry(); if(dxr.flags.IsReducedRando()) return; - memes_enabled = bool(ConsoleCommand("get #var(package).MenuChoice_ToggleMemes enabled")); - if(!memes_enabled) return; + if(!class'MenuChoice_ToggleMemes'.default.enabled) return; switch(dxr.localURL) { @@ -269,12 +266,10 @@ function AnyEntry() local Actor a; local Rotator r; local Vector v; - local bool memes_enabled; Super.AnyEntry(); if(dxr.flags.IsReducedRando()) return; - memes_enabled = bool(ConsoleCommand("get #var(package).MenuChoice_ToggleMemes enabled")); - if(!memes_enabled) return; + if(!class'MenuChoice_ToggleMemes'.default.enabled) return; switch(dxr.localURL) { @@ -344,7 +339,7 @@ function AnyEntry() } -//Add me back in once we have "Randomizer" name textures! Just change the textures below + //Add me back in once we have "Randomizer" name textures! Just change the textures below foreach AllActors(class'#var(prefix)DXText',text) { text.bHidden=True; //Hide all the original text @@ -436,7 +431,6 @@ function PostFirstEntry() local LuciusDeBeers lucius; local vector v; local rotator r; - local bool memes_enabled; Super.PostFirstEntry(); @@ -450,8 +444,7 @@ function PostFirstEntry() } if(dxr.flags.IsReducedRando()) return; - memes_enabled = bool(ConsoleCommand("get #var(package).MenuChoice_ToggleMemes enabled")); - if(!memes_enabled) return; + if(!class'MenuChoice_ToggleMemes'.default.enabled) return; SetSeed("Memes InterpolationPoints"); @@ -571,13 +564,8 @@ function PaulToilet() chair.Event = ''; chair.Destroy(); - toilet.DrawScale = 0.7; - // _AddActor does good stuff to ignore collision - chair = #var(prefix)Chair1(_AddActor(chair, class'#var(prefix)Chair1', toilet.Location, toilet.Rotation)); - chair.bHidden = true; - chair.sitPoint[0].Y += 4.0; - paul.SetLocation(chair.Location); + paul.SetLocation(toilet.Location); ft.SetLocation(paul.Location); } @@ -736,6 +724,27 @@ function RandomizeDialogConversation(Conversation conv) } } +static function float GetVoicePitch(DXRando dxr){ + if (!dxr.flags.IsReducedRando() && dxr.IsAprilFools()){ + if ((dxr.seed)%10>=5){ + return 1.5; + } else { + return 0.75; + } + } + return 1.0; +} + +function AddDXRCredits(CreditsWindow cw) +{ + if(IsAprilFools()) { + cw.PrintLn(); + cw.PrintHeader("APRIL FOOLS!"); + cw.PrintLn(); + cw.PrintLn(); + } +} + function bool is_valid(string s, class o) {// determines if a class is worthy of replacing the logo in the menu local class a; diff --git a/DXRModules/DeusEx/Classes/DXRMissions.uc b/DXRModules/DeusEx/Classes/DXRMissions.uc index 74f36fa34..822953108 100644 --- a/DXRModules/DeusEx/Classes/DXRMissions.uc +++ b/DXRModules/DeusEx/Classes/DXRMissions.uc @@ -383,8 +383,8 @@ function MoveActorsIn(int goalsToLocations[32]) function bool _ChooseGoalLocations(out int goalsToLocations[32]) { - local int i, g1, g2, r, _num_locs, _num_starts; - local int availLocs[64], goalsOrder[32]; + local int i, a, g, g1, g2, r, loc, _num_locs, _num_starts, _num_goal_locs; + local int availLocs[64], goalsOrder[32], goalLocs[64]; // build list of availLocs based on flags, also count _num_starts _num_locs = 0; @@ -396,29 +396,28 @@ function bool _ChooseGoalLocations(out int goalsToLocations[32]) // exclude the vanilla goal locations if randomized goal locations are disabled if( dxr.flags.settings.goals <= 0 && (VANILLA_GOAL & locations[i].bitMask) != 0 ) continue; - availLocs[_num_locs++] = i; - if( (START_LOCATION & locations[i].bitMask) != 0) - _num_starts++; + if( (START_LOCATION & locations[i].bitMask) != 0) { + goalLocs[_num_starts++] = _num_locs; + } + availLocs[_num_locs++] = i; } // choose a starting location goalsToLocations[num_goals] = -1; if(_num_starts > 0) { - for(i=0; i<20; i++) { - r = rng(_num_locs); - if( (START_LOCATION & locations[availLocs[r]].bitMask) == 0) - continue; - - goalsToLocations[num_goals] = availLocs[r]; - _num_locs--; - availLocs[r] = availLocs[_num_locs]; - break; - } - if(goalsToLocations[num_goals] == -1) - return false; + _num_goal_locs = _num_starts; + r = rng(_num_goal_locs); + a = goalLocs[r]; + loc = availLocs[a]; + + goalsToLocations[num_goals] = loc; + _num_locs--; + availLocs[a] = availLocs[_num_locs]; } + if(num_goals == 0) return true; + // do the goals in a random order for(i=0; i 100) { + warning("ChooseGoalLocations took " $ (attempts+1) $ " attempts!"); + } + return; + } } err("ChooseGoalLocations took too many attempts!"); } @@ -523,13 +537,14 @@ function Timer() } } -function UpdateGoalWithRandoInfo(name goalName, string text) +function UpdateGoalWithRandoInfo(name goalName, string text, optional bool always) { local string goalText; local DeusExGoal goal; local int randoPos; if(player(true)==None) return;// don't spam HX logs + if(!always && dxr.flags.settings.goals == 0) return; //Don't add rando notes if goal randomization is turned off goal = player().FindGoal(goalName); if(goal == None) return; @@ -738,14 +753,22 @@ static function bool IsCloseToStart(DXRando dxr, vector loc) return IsCloseToRandomStart(dxr, loc); } else { - too_close = 120 * 16;// worst cases are 05 jail and 06 helibase? + switch(dxr.localURL) { + case "05_NYC_UNATCOMJ12lab": + case "06_HongKong_Helibase": + case "14_Vandenberg_Sub": + too_close = 120 * 16;// worst cases are 05 jail and 06 helibase? for larger maps this doesn't matter much anyways + break; + default: + too_close = 50 * 16; + } foreach dxr.RadiusActors(class'PlayerStart', ps, too_close, loc) { dist = VSize(loc-ps.location); if( dist < too_close ) return true; } } - too_close = 75 * 16; + too_close = 50 * 16; foreach dxr.RadiusActors(class'Teleporter', t, too_close, loc) { if( t.Tag == '' ) continue; dist = VSize(loc-t.location); diff --git a/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc b/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc index 790f3b054..5fc800ebb 100644 --- a/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc +++ b/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc @@ -96,9 +96,9 @@ function ClientSetMusic( playerpawn NewPlayer, music NewSong, byte NewSection, b local int continuous_setting; p = #var(PlayerPawn)(NewPlayer); - continuous_setting = int(NewPlayer.ConsoleCommand("get #var(package).MenuChoice_ContinuousMusic continuous_music")); - rando_music_setting = bool(p.ConsoleCommand("get #var(package).MenuChoice_RandomMusic enabled")); c = class'MenuChoice_ContinuousMusic'; + continuous_setting = c.default.continuous_music; + rando_music_setting = class'MenuChoice_RandomMusic'.default.enabled; l("ClientSetMusic("$NewSong@NewSection@NewCdTrack@NewTransition$") "$continuous_setting@rando_music_setting@PrevSong@PrevMusicMode@dxr.dxInfo.missionNumber); // copy to LevelSong in order to support changing songs, since Level.Song is const @@ -215,8 +215,8 @@ function PlayRandomSong(bool setseed) if(p == None) return; - continuous_setting = int(p.ConsoleCommand("get #var(package).MenuChoice_ContinuousMusic continuous_music")); - rando_music_setting = bool(p.ConsoleCommand("get #var(package).MenuChoice_RandomMusic enabled")); + continuous_setting = class'MenuChoice_ContinuousMusic'.default.continuous_music; + rando_music_setting = class'MenuChoice_RandomMusic'.default.enabled; l("AnyEntry 1: "$p@dxr@dxr.dxInfo.missionNumber@continuous_setting@rando_music_setting); if( p == None || dxr == None || (continuous_setting == c.default.disabled && rando_music_setting==false) ) return; diff --git a/DXRModules/DeusEx/Classes/DXRPasswords.uc b/DXRModules/DeusEx/Classes/DXRPasswords.uc index dee7e8fd1..a1e3ea8f2 100644 --- a/DXRModules/DeusEx/Classes/DXRPasswords.uc +++ b/DXRModules/DeusEx/Classes/DXRPasswords.uc @@ -141,7 +141,7 @@ function FixCodes() for(i=0; i 57 ) c += 39; out = out $ Chr(c); } - dxr.SetSeed(oldseed); + ReapplySeed(oldseed); return out; } @@ -563,7 +563,7 @@ function string GeneratePasscode(string oldpasscode) oldseed = SetGlobalSeed(oldpasscode);//manually set the seed to avoid using the level name in the seed newpasscode = rng(maximum) $ ""; - dxr.SetSeed(oldseed); + ReapplySeed(oldseed); //If the new passcode is shorter than the old one, we need to add some leading zeroes until it matches while (Len(newpasscode) < oldpasslength) { @@ -681,7 +681,7 @@ function RunTests() testint( PassInStr("password is captain.", "captain"), 12, "yes password period"); testint( PassInStr("password is \"captain\"", "captain"), 13, "yes password quotes"); - teststring( GeneratePassword(dxr, "CAPTain"), GeneratePassword(dxr, "captain"), "GeneratePassword is case insensitive"); + teststring( GeneratePassword("CAPTain"), GeneratePassword("captain"), "GeneratePassword is case insensitive"); not_passwords[0] = oldnot; num_not_passwords = old_num_not_passwords; diff --git a/DXRModules/DeusEx/Classes/DXRPlayerStats.uc b/DXRModules/DeusEx/Classes/DXRPlayerStats.uc index 3c9c4925b..7745b80bc 100644 --- a/DXRModules/DeusEx/Classes/DXRPlayerStats.uc +++ b/DXRModules/DeusEx/Classes/DXRPlayerStats.uc @@ -40,7 +40,7 @@ function PlayerAnyEntry(#var(PlayerPawn) p) SetMaxStats(p); if(p.HealthTorso <= 0 || p.HealthHead <= 0) { - //bFixGlitches = bool(ConsoleCommand("get #var(package).MenuChoice_FixGlitches enabled")); + //bFixGlitches = class'MenuChoice_FixGlitches'.default.enabled; // TODO: this one is a bit weird to fix because our code doesn't get run with the glitched load if(bFixGlitches) { p.TakeDamage(10000, p, p.Location, vect(0,0,0), 'Radiation'); diff --git a/DXRModules/DeusEx/Classes/DXRReduceItems.uc b/DXRModules/DeusEx/Classes/DXRReduceItems.uc index 4bec3636c..105e7933f 100644 --- a/DXRModules/DeusEx/Classes/DXRReduceItems.uc +++ b/DXRModules/DeusEx/Classes/DXRReduceItems.uc @@ -394,7 +394,8 @@ simulated function SetMaxAmmo(class type, int percent) maxAmmo = a.MaxAmmo; #endif - if( a.AmmoAmount > maxAmmo ) a.AmmoAmount = maxAmmo; + // don't reduce ammo of pawns + if( ScriptedPawn(a.Owner)==None && a.AmmoAmount > maxAmmo ) a.AmmoAmount = maxAmmo; } } diff --git a/DXRModules/DeusEx/Classes/DXRSkills.uc b/DXRModules/DeusEx/Classes/DXRSkills.uc index aa3040550..200068888 100644 --- a/DXRModules/DeusEx/Classes/DXRSkills.uc +++ b/DXRModules/DeusEx/Classes/DXRSkills.uc @@ -164,6 +164,9 @@ simulated function RandoSkillLevelValues(Skill a) else if( #var(prefix)SkillComputer(a) != None ) { add_desc = "Hacking uses 5 bioelectric energy per second."; } + else if( #var(prefix)SkillEnviro(a)!=None ) { + add_desc = "Each level increases the number of fire extinguishers you can carry by 1."; + } #endif skill_value_wet_dry = float(dxr.flags.settings.skill_value_rando) / 100.0; diff --git a/DXRModules/DeusEx/Classes/DXRStartMap.uc b/DXRModules/DeusEx/Classes/DXRStartMap.uc index 0c5f55afb..555366b2f 100644 --- a/DXRModules/DeusEx/Classes/DXRStartMap.uc +++ b/DXRModules/DeusEx/Classes/DXRStartMap.uc @@ -15,7 +15,7 @@ function PlayerLogin(#var(PlayerPawn) p) //Add extra skill points to make available once you enter the game AddStartingSkillPoints(dxr,p); - StartMapSpecificFlags(p.flagbase, dxr.localURL); + StartMapSpecificFlags(p, p.flagbase, dxr.flags.settings.starting_map, dxr.localURL); } function PlayerAnyEntry(#var(PlayerPawn) p) @@ -32,6 +32,7 @@ function PreFirstEntry() { local #var(PlayerPawn) p; local string startMapName; + local ScriptedPawn sp; foreach AllActors(class'#var(PlayerPawn)',p){break;} @@ -40,74 +41,59 @@ function PreFirstEntry() startMapName = Caps(startMapName); if (InStr(startMapName,dxr.localURL)!=-1){ - StartMapSpecificFlags(p.flagbase, dxr.localURL); + StartMapSpecificFlags(p, p.flagbase, dxr.flags.settings.starting_map, dxr.localURL); } + switch(dxr.localURL) { + case "02_NYC_BATTERYPARK": + if(dxr.flags.settings.starting_map > 20) { + foreach AllActors(class'ScriptedPawn', sp, 'SubTerrorist') { + sp.Destroy(); + } + foreach AllActors(class'ScriptedPawn', sp, 'hostageMan') { + sp.Destroy(); + } + foreach AllActors(class'ScriptedPawn', sp, 'hostageWoman') { + sp.Destroy(); + } + } + break; + } } static simulated function int GetStartingMissionMask(int start_map) { + local int mask, i; + switch(start_map) {// these numbers are basically mission number * 10, with some extra for progress within the mission - case 0: - case 10: - //startMap="01_NYC_UNATCOIsland"; - return 65535; - break; - case 20: - return 65532; - break; - case 30: - return 65528; - break; - case 40: - //startMap="04_NYC_UNATCOHQ" - return 65520; - case 50: - //startMap="05_NYC_UNATCOMJ12lab"; - return 65504; - break; - case 61: - //startMap="06_HongKong_WanChai_Market"; - return 65472; - break; - case 81: - //startMap="08_NYC_Smug"; - return 65280; - break; - case 90: - return 65024; + case 70:// 2nd half of hong kong, but maybe we should actually give bingo goals the mission 7 mask? + case 75: + start_map = 60; break; case 99: //startMap="09_NYC_Graveyard"; - return 64512; //Mission 10 onwards (you're at the end of mission 9) + start_map = 100; //Mission 10 onwards (you're at the end of mission 9) break; case 109: //startMap="10_Paris_Chateau"; - return 64512; //Mission 10 onwards (but mark most mission 10 goals as impossilbe) + start_map = 100; //Mission 10 onwards (but mark most mission 10 goals as impossible, TODO: would this be easier using GetMaybeMissionMask for a whitelist instead of blacklist?) break; case 119: //startMap="11_Paris_Everett"; - return 61440; //Mission 12 onwards - break; - case 140: - //startMap="14_Vandenberg_Sub"; - return 49152; - break; - case 150: - //startMap="15_Area51_Bunker"; - return 32768; - break; - default: - //There's always a place for you on Liberty Island - //startMap="01_NYC_UNATCOIsland"; - return 65535; + start_map = 120;//Mission 12 onwards break; } + + mask = 0xFFFF; + for(i=0; i < (start_map/10); i++) { + mask -= (1<20; + } + break; + + case 3: // Airfield + switch(bingo_event) + { + case "CleanerBot_ClassDead": + case "AlexCloset": + case "CommsPit": + case "BathroomFlags": + case "ReadJCEmail": + case "Shannon_Dead": + case "TrophyHunter": + case "SlippingHazard": + case "un_PrezMeadPic_peepedtex": + case "WaltonConvos": + case "un_bboard_peepedtex": + case "UNATCOHandbook": + case "ManderleyMail": + case "LetMeIn": + return start_map > 30 && start_map < 36 && end_mission <= 3;// you can do these m03 unatco goals in m04 unatco, but if you start in helibase it's far + + case "SickMan_Dead": + case "NYEagleStatue_peeped": + return start_map>35 && end_mission <= 3;// no battery park goals once you get to airfield? + + case "KnowYourEnemy": + case "SimonsAssassination": + return start_map>31; + } + break; + + case 4: // Paul and NSFHQ + switch(bingo_event) + { + } + break; + + case 5: // escape from MJ12 Jail + switch(bingo_event) + { + } + break; + + case 6: // Hong Kong + case 7:// fallthrough to 2nd half of Hong Kong + switch(bingo_event) + { + } + break; + + case 8: // return to NYC + switch(bingo_event) + { + } + break; + + case 9: // Dockyard and Ship + switch(bingo_event) + { + } + break; + + case 10: // Paris + case 11: // fallthrough to the rest of Paris + switch(bingo_event) + { + case "GuntherHermann_Dead": + return start_map>=115; + } + break; + + case 12: // Vandenberg + case 14: // fallthrough to the rest of Vandenberg + switch(bingo_event) + { + } + break; + + case 15: // Area 51 + switch(bingo_event) + { + } + break; + } + + // goals that are spread across many missions, like LeoToTheBar + // TODO: need to reconsider all of these switch(bingo_event) { case "LeoToTheBar": //Only possible if you started in the first level - return start_map!=0; + return start_map>10 || end_mission < 2; break; case "MetSmuggler": return start_map>=80; //Mission 8 and later starts you should already know Smuggler (see StartMapSpecificFlags) @@ -377,9 +632,7 @@ static function bool BingoGoalImpossible(string bingo_event, int start_map, int if (end_mission < 8){ return True; } - return start_map>=60; //Have to have told Jaime to meet you in Hong Kong in mission 5 - case "VialAmbrosia_Activated": - return start_map>=96; //Have to have started before the superfreighter upper decks (Arbitrarily chose 96 as that point) + return start_map>=60; //TODO: Have to have told Jaime to meet you in Hong Kong in mission 5 case "Terrorist_ClassDead": case "Terrorist_ClassUnconscious": case "Terrorist_peeptime": @@ -400,8 +653,8 @@ static function bool BingoGoalImpossible(string bingo_event, int start_map, int case "IcarusCalls_Played": case "roof_elevator": case "MeetRenault_Played": - return start_map>100; //All these early Paris things - if we were to add a "Streets" starting location, this would need to be split more accurately - case "ManWhoWasThursday":// in 10_Paris_Catacombs, and then 12_Vandenberg_Cmd, but nothing in M11 + return start_map>100; //TODO: All these early Paris things - if we were to add a "Streets" starting location, this would need to be split more accurately + case "ManWhoWasThursday":// TODO: in 10_Paris_Catacombs, and then 12_Vandenberg_Cmd, but nothing in M11 return start_map > 100 && end_mission <= 11; case "PresentForManderley": //Have to be able to get Juan from mission 3 and bring him to the start of mission 4 @@ -415,7 +668,7 @@ static function bool BingoGoalImpossible(string bingo_event, int start_map, int } return start_map>=90; case "PhoneCall": - return start_map>100; //Last phone is in the building before the catacombs (Where Icarus calls) + return start_map>100; //TODO: Last phone is in the building before the catacombs (Where Icarus calls) default: return False; } @@ -426,6 +679,7 @@ static function bool BingoGoalImpossible(string bingo_event, int start_map, int static function bool BingoGoalPossible(string bingo_event, int start_map, int end_mission) { + // TODO: any of the exceptions in GetStartingMissionMask, and will also need to add them to GetMaybeMissionMask switch(start_map) { case 119: switch(bingo_event) { @@ -446,68 +700,138 @@ static function int ChooseRandomStartMap(DXRBase m, int avoidStart) local int startMap; local int attempts; - startMap=-1; + startMap=avoidStart; attempts=0; m.SetGlobalSeed("randomstartmap"); - m.rng(1);// HACK: dummy roll to shuffle the CRC to improve rng, we should do this automatically next compatibility break - //Don't try forever. If we manage to grab the avoided map 5 times, it was meant to be. - while ((startMap==-1 || startMap==avoidStart) && attempts<5){ - i = m.rng(13); + //Don't try forever. If we manage to grab the avoided map 50 times, it was meant to be. + //the widest span is Hong Kong: Helipad is 60, Storage is 75, a span of 15 + while (Abs(startMap-avoidStart) <= 15 && attempts < 50){ + startMap = _ChooseRandomStartMap(m); + m.l("Start map selection attempt "$ ++attempts $" was "$startMap); + } - //Should be able to legitimately return Liberty Island (even if that's as a value of 10), but needs additional special handling - switch(i) - { - case 0: - startMap = 10; - break; - case 1: - startMap = 20; - break; - case 2: - startMap = 30; - break; - case 3: - startMap = 40; - break; - case 4: - startMap = 50; - break; - case 5: - startMap = 61; - break; - case 6: - startMap = 81; - break; - case 7: - startMap = 90; - break; - case 8: - startMap = 99; - break; - case 9: - startMap = 109; - break; - case 10: - startMap = 119; - break; - case 11: - startMap = 140; - break; - case 12: - startMap = 150; - break; - default: - m.err("Random Starting Map picked value "$i$" which is unhandled!"); - startMap = 0; //Fall back on Liberty Island - break; + return startMap; +} + +static function int _ChooseRandomStartMap(DXRBase m) +{ + local int i; + i = m.rng(13); + + if(VersionIsStable()) { + switch(i) { + case 0: return 10; + case 1: return 20; + case 2: return 30; + case 4: return 40; + case 5: return 61; + case 6: return 81; + case 7: return 90; + case 8: return 99; + case 9: return 109; + case 10: return 119; + case 11: return 140; + case 12: return 150; } - m.l("Start map selection attempt "$attempts$" was "$startMap); + m.err("Random Starting Map picked value "$i$" which is unhandled!"); + return 0; } - return startMap; + //Should be able to legitimately return Liberty Island (even if that's as a value of 10), but needs additional special handling + switch(i) + { + case 0:// mission 1 + return 10; + case 1:// mission 2 + if(m.rngb()) return 21; + return 20; + case 2:// mission 3 + i = m.rng(3); + switch(i) { + case 0: return 30; + case 1: return 35; + case 2: return 37; + } + return 30; // just in case the switch misses + case 3:// mission 4 + if(m.rngb()) return 45; + return 40; + case 4:// mission 5 + if(m.rngb()) return 55; + return 50; + case 5:// mission 6 + i = m.rng(6); + switch(i) { + case 0: return 60; + case 1: return 61; + case 2: return 65; + case 3: return 67; + case 4: return 70; + case 5: return 75; + } + return 61; + case 6:// mission 8 + i = m.rng(5); + switch(i) { + case 0: return 81; + case 1: return 82; + case 2: return 83; + case 3: return 84; + case 4: return 85; + } + return 81; + case 7:// mission 9 + i = m.rng(3); + switch(i) { + case 0: return 90; + case 1: return 92; + case 2: return 95; + } + return 90; + case 8:// mission 10 + i = m.rng(3); + switch(i) { + case 0: return 99; + case 1: return 101; + case 2: return 106; + } + return 99; + case 9:// mission 11 + if(m.rngb()) return 115; + return 109; + case 10:// mission 12 + i = m.rng(3); + switch(i) { + case 0: return 119; + case 1: return 121; + case 2: return 129; + } + return 119; + case 11:// mission 14 + i = m.rng(4); + switch(i) { + case 0: return 140; + case 1: return 141; + case 2: return 142; + case 3: return 145; + } + return 140; + case 12:// mission 15 + i = m.rng(4); + switch(i) { + case 0: return 150; + case 1: return 151; + case 2: return 152; + case 3: return 153; + } + return 150; + } + m.err("Random Starting Map picked value "$i$" which is unhandled!"); + return 0; //Fall back on Liberty Island } + static function AddStartingCredits(DXRando dxr, #var(PlayerPawn) p) { local int i; diff --git a/DXRModules/DeusEx/Classes/DXRStats.uc b/DXRModules/DeusEx/Classes/DXRStats.uc index db4704477..2b5c1a500 100644 --- a/DXRModules/DeusEx/Classes/DXRStats.uc +++ b/DXRModules/DeusEx/Classes/DXRStats.uc @@ -16,6 +16,16 @@ var RunInfo runs[20]; var int missions_times[16]; var int missions_menu_times[16]; +function FirstEntry() +{ + Super.FirstEntry(); + + //Track how many maps the player has visited + if (dxr.dxInfo != None && dxr.dxInfo.MissionNumber > 0 && dxr.dxInfo.MissionNumber < 98){ + IncStatFlag(player(),'DXRStats_mapcoverage'); + } +} + function AnyEntry() { local int i; @@ -540,7 +550,8 @@ static function CheckLeaderboard(DXRando dxr, Json j) function AddDXRCredits(CreditsWindow cw) { - local int fired,swings,jumps,deaths,burnkills,gibbedkills,saves,autosaves,loads,kills,kos,killsByOther,kosByOther; + local int fired,swings,jumps,deaths,burnkills,gibbedkills,saves,autosaves,loads,kills,kos,killsByOther,kosByOther,mapcoverage,nummaps; + local float mappercent; local CreditsLeaderboardWindow leaderboard; cw.PrintLn(); @@ -565,11 +576,20 @@ function AddDXRCredits(CreditsWindow cw) kos = dxr.flagbase.GetInt('DXRStats_knockouts'); killsByOther = dxr.flagbase.GetInt('DXRStats_kills_by_other'); kosByOther = dxr.flagbase.GetInt('DXRStats_knockouts_by_other'); + mapcoverage = dxr.flagbase.GetInt('DXRStats_mapcoverage'); deaths = GetDataStorageStat(dxr, "DXRStats_deaths"); saves = player().saveCount; autosaves = GetDataStorageStat(dxr, "DXRStats_autosaves"); loads = GetDataStorageStat(dxr, "DXRStats_loads"); + //Calculate percentage of maps visited + if(class'DXRMapVariants'.static.IsRevisionMaps(player())){ + nummaps=76; + } else { + nummaps=72; + } + mappercent = (float(mapcoverage)/float(nummaps))*100.0; + cw.PrintHeader("Statistics"); if(dxr.dxInfo.missionNumber == 99) @@ -587,6 +607,7 @@ function AddDXRCredits(CreditsWindow cw) cw.PrintText("Total NPCs Knocked Out: "$(kos + kosByOther)); cw.PrintText("Total NPCs Burned to Death: "$burnkills); cw.PrintText("Total NPCs Gibbed: "$gibbedkills); + cw.PrintText("Maps Visited: "$mapcoverage$" (" $ class'DXRInfo'.static.TruncateFloat(mappercent,1) $ "%)"); cw.PrintText("Deaths: "$deaths); cw.PrintText("Saves: "$saves$" ("$autosaves$" Autosaves)"); cw.PrintText("Loads: "$loads); @@ -650,7 +671,7 @@ static function int _ScoreRun(int time, int time_without_menus, float CombatDiff i += SkillPointsTotal; i += Nanokeys * 20;// unique nanokeys i -= Clamp(cheats, 0, 100) * 300; - return i; + return Max(1, i); } function TestScoring() @@ -664,16 +685,16 @@ function TestScoring() bingo_win, bingos, bingo_spots, skill_points, nanokeys, cheats; dxr.flags.SetDifficulty(1); - testint(dxr.flags.ScoreFlags(), 4835, "score bonus for Normal"); + testint(dxr.flags.ScoreFlags(), 4820, "score bonus for Normal"); dxr.flags.SetDifficulty(2); - testint(dxr.flags.ScoreFlags(), 10545, "score bonus for Hard"); + testint(dxr.flags.ScoreFlags(), 10530, "score bonus for Hard"); dxr.flags.SetDifficulty(3); - testint(dxr.flags.ScoreFlags(), 12645, "score bonus for Extreme"); + testint(dxr.flags.ScoreFlags(), 12605, "score bonus for Extreme"); dxr.flags.SetDifficulty(4); - testint(dxr.flags.ScoreFlags(), 14610, "score bonus for Impossible"); + testint(dxr.flags.ScoreFlags(), 13915, "score bonus for Impossible"); names[num] = "1 Million Points!"; scores[num++] = 1000000; @@ -689,8 +710,8 @@ function TestScoring() scores[num++] = _ScoreRun(time, time_without_menus, combat_difficulty, flags_score, saves, loads, bingo_win, bingos, bingo_spots, skill_points, nanokeys, cheats); - names[num] = "130k Points"; - scores[num++] = 130000; + names[num] = "129k Points"; + scores[num++] = 129000; names[num] = "literal god: 1 hour, full bingo, 5 saves, 5 loads"; time=72000; time_without_menus=36000; combat_difficulty=2; rando_difficulty=2; saves=5; loads=5; diff --git a/DXRModules/DeusEx/Classes/DXRWeapons.uc b/DXRModules/DeusEx/Classes/DXRWeapons.uc index 913aaa0fe..cb9b94c78 100644 --- a/DXRModules/DeusEx/Classes/DXRWeapons.uc +++ b/DXRModules/DeusEx/Classes/DXRWeapons.uc @@ -63,7 +63,7 @@ simulated function RandoWeapon(DeusExWeapon w) min_weapon_shottime = float(dxr.flags.settings.min_weapon_shottime) / 100; max_weapon_shottime = float(dxr.flags.settings.max_weapon_shottime) / 100; w.ShotTime = rngrange(w.default.ShotTime, min_weapon_shottime, max_weapon_shottime); - l(w $ " w.HitDamage: "$ w.HitDamage $ ", ShotTime: " $ w.ShotTime); + l(w $ " w.HitDamage="$ w.HitDamage $ ", ShotTime=" $ w.ShotTime); /*f = w.default.ReloadTime * (rngf()+0.5); w.ReloadTime = f; f = float(w.default.MaxRange) * (rngf()+0.5); @@ -72,7 +72,7 @@ simulated function RandoWeapon(DeusExWeapon w) w.AccurateRange = int(f); f = w.default.BaseAccuracy * (rngf()+0.5); w.BaseAccuracy = f;*/ - dxr.SetSeed(oldseed); + ReapplySeed(oldseed); } simulated function bool RandoProjectile(DeusExWeapon w, out class p, out class d, float new_damage) diff --git a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalATM.uc b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalATM.uc index 59df778d1..1e07f1968 100644 --- a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalATM.uc +++ b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalATM.uc @@ -38,14 +38,12 @@ function ConfigurationChanged() function CreateKnownAccountsWindow() { - local int codes_mode; - codes_mode = int(player.ConsoleCommand("get #var(package).MenuChoice_PasswordAutofill codes_mode")); - if( codes_mode < 1 ) return; + if( class'MenuChoice_PasswordAutofill'.default.codes_mode < 1 ) return; winKnownShadow = ShadowWindow(NewChild(Class'ShadowWindow')); winKnownAccounts = ComputerScreenKnownAccounts(NewChild(Class'ComputerScreenKnownAccounts')); - if( codes_mode == 2 ) + if( class'MenuChoice_PasswordAutofill'.default.codes_mode == 2 ) winKnownAccounts.bShowPasswords = true; winKnownAccounts.SetNetworkTerminal(Self); winKnownAccounts.SetCompOwner(compOwner); diff --git a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalPersonal.uc b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalPersonal.uc index ddd2251f3..37f9f0e1c 100644 --- a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalPersonal.uc +++ b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalPersonal.uc @@ -34,14 +34,12 @@ function ConfigurationChanged() function CreateKnownAccountsWindow() { - local int codes_mode; - codes_mode = int(player.ConsoleCommand("get #var(package).MenuChoice_PasswordAutofill codes_mode")); - if( codes_mode < 1 ) return; + if( class'MenuChoice_PasswordAutofill'.default.codes_mode < 1 ) return; winKnownShadow = ShadowWindow(NewChild(Class'ShadowWindow')); winKnownAccounts = ComputerScreenKnownAccounts(NewChild(Class'ComputerScreenKnownAccounts')); - if( codes_mode == 2 ) + if( class'MenuChoice_PasswordAutofill'.default.codes_mode == 2 ) winKnownAccounts.bShowPasswords = true; winKnownAccounts.SetNetworkTerminal(Self); winKnownAccounts.SetCompOwner(compOwner); diff --git a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalSecurity.uc b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalSecurity.uc index f3f596677..da0a8ee33 100644 --- a/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalSecurity.uc +++ b/DXRNonVanilla/DeusEx/Classes/DXRNetworkTerminalSecurity.uc @@ -34,14 +34,12 @@ function ConfigurationChanged() function CreateKnownAccountsWindow() { - local int codes_mode; - codes_mode = int(player.ConsoleCommand("get #var(package).MenuChoice_PasswordAutofill codes_mode")); - if( codes_mode < 1 ) return; + if( class'MenuChoice_PasswordAutofill'.default.codes_mode < 1 ) return; winKnownShadow = ShadowWindow(NewChild(Class'ShadowWindow')); winKnownAccounts = ComputerScreenKnownAccounts(NewChild(Class'ComputerScreenKnownAccounts')); - if( codes_mode == 2 ) + if( class'MenuChoice_PasswordAutofill'.default.codes_mode == 2 ) winKnownAccounts.bShowPasswords = true; winKnownAccounts.SetNetworkTerminal(Self); winKnownAccounts.SetCompOwner(compOwner); diff --git a/DXRNonVanilla/DeusEx/Classes/DXRandoRootWindow.uc b/DXRNonVanilla/DeusEx/Classes/DXRandoRootWindow.uc index 3761d4fd4..3c43319b8 100644 --- a/DXRNonVanilla/DeusEx/Classes/DXRandoRootWindow.uc +++ b/DXRNonVanilla/DeusEx/Classes/DXRandoRootWindow.uc @@ -49,7 +49,7 @@ function DeusExBaseWindow PopWindow(optional Bool bNoUnpause) local SkilledTool tool; local bool bFixGlitches; - bFixGlitches = bool(parentPawn.ConsoleCommand("get #var(package).MenuChoice_FixGlitches enabled")); + bFixGlitches = class'MenuChoice_FixGlitches'.default.enabled; // check for super jumps f = DeusExPlayer(parentPawn).AugmentationSystem.GetAugLevelValue(class'AugSpeed'); diff --git a/DXRNonVanilla/DeusEx/Classes/VMD156MenuSelectDifficulty.uc b/DXRNonVanilla/DeusEx/Classes/VMD156MenuSelectDifficulty.uc index d5e351987..8fabbad12 100644 --- a/DXRNonVanilla/DeusEx/Classes/VMD156MenuSelectDifficulty.uc +++ b/DXRNonVanilla/DeusEx/Classes/VMD156MenuSelectDifficulty.uc @@ -1,18 +1,19 @@ class VMDR156MenuSelectDifficulty extends DXRMenuSelectDifficulty; -function _InvokeNewGameScreen(float difficulty, DXRando dxr) +#ifdef vmd +function _InvokeNewGameScreen(float difficulty) { local DXRMenuScreenNewGame newGame; -#ifdef vmd local MenuSelectDifficulty VMDNewGame; local VMDBufferPlayer VMP; + local DXRando dxr; + dxr = GetDxr(); dxr.flags.SaveFlags(); // I think we really just need to run DXRSkills here dxr.RandoEnter(); Player.CombatDifficulty = Difficulty; VMDNewGame = MenuSelectDifficulty(root.InvokeMenuScreen(Class'MenuSelectDifficulty')); -#endif } function NewGameSetup(float difficulty) @@ -26,3 +27,4 @@ function NewGameSetup(float difficulty) newGame.Init(dxr); } } +#endif diff --git a/DXRNonVanilla/DeusEx/Classes/VMD175MenuSelectDifficulty.uc b/DXRNonVanilla/DeusEx/Classes/VMD175MenuSelectDifficulty.uc index 36c313d88..f12fa1960 100644 --- a/DXRNonVanilla/DeusEx/Classes/VMD175MenuSelectDifficulty.uc +++ b/DXRNonVanilla/DeusEx/Classes/VMD175MenuSelectDifficulty.uc @@ -1,12 +1,14 @@ class VMDR175MenuSelectDifficulty extends DXRMenuSelectDifficulty; #ifdef vmd175 -function _InvokeNewGameScreen(float difficulty, DXRando dxr) +function _InvokeNewGameScreen(float difficulty) { local DXRMenuScreenNewGame newGame; local VMDMenuSelectCustomDifficulty VMDNewGame; local VMDBufferPlayer VMP; + local DXRando dxr; + dxr = GetDxr(); dxr.flags.SaveFlags(); // I think we really just need to run DXRSkills here dxr.RandoEnter(); @@ -19,7 +21,7 @@ function _InvokeNewGameScreen(float difficulty, DXRando dxr) VMP.VMDResetNewGameVars(1); } - Player.CombatDifficulty = Difficulty; + Player.CombatDifficulty = difficulty; } function NewGameSetup(float difficulty) diff --git a/DXRNonVanilla/DeusEx/Classes/VMDR156MenuSetupRando.uc b/DXRNonVanilla/DeusEx/Classes/VMDR156MenuSetupRando.uc index 3e89244bc..4285175bf 100644 --- a/DXRNonVanilla/DeusEx/Classes/VMDR156MenuSetupRando.uc +++ b/DXRNonVanilla/DeusEx/Classes/VMDR156MenuSetupRando.uc @@ -1,12 +1,14 @@ class VMDR156MenuSetupRando extends DXRMenuSetupRando; -function _InvokeNewGameScreen(float difficulty, DXRando dxr) +#ifdef vmd +function _InvokeNewGameScreen(float difficulty) { local DXRMenuScreenNewGame newGame; -#ifdef vmd local VMDMenuSelectCampaign VMDNewGame; local VMDBufferPlayer VMP; + local DXRando dxr; + dxr = GetDxr(); dxr.flags.SaveFlags(); // I think we really just need to run DXRSkills here dxr.RandoEnter(); @@ -21,10 +23,10 @@ function _InvokeNewGameScreen(float difficulty, DXRando dxr) //MADDERS: We only call this from the main menu, NOT in game. //By this logic, setting it all on the fly is fine. - Player.CombatDifficulty = Difficulty; + Player.CombatDifficulty = difficulty; if (VMDNewGame != None) VMDNewGame.SetDifficulty(difficulty); return; -#endif } +#endif diff --git a/DXRNonVanilla/DeusEx/Classes/VMDR175MenuSetupRando.uc b/DXRNonVanilla/DeusEx/Classes/VMDR175MenuSetupRando.uc index e7b4ef0d8..2613c26f7 100644 --- a/DXRNonVanilla/DeusEx/Classes/VMDR175MenuSetupRando.uc +++ b/DXRNonVanilla/DeusEx/Classes/VMDR175MenuSetupRando.uc @@ -1,12 +1,14 @@ class VMDR175MenuSetupRando extends DXRMenuSetupRando; #ifdef vmd175 -function _InvokeNewGameScreen(float difficulty, DXRando dxr) +function _InvokeNewGameScreen(float difficulty) { local DXRMenuScreenNewGame newGame; local VMDMenuSelectCustomDifficulty VMDNewGame; local VMDBufferPlayer VMP; + local DXRando dxr; + dxr = GetDxr(); dxr.flags.SaveFlags(); // I think we really just need to run DXRSkills here dxr.RandoEnter(); @@ -19,6 +21,6 @@ function _InvokeNewGameScreen(float difficulty, DXRando dxr) VMP.VMDResetNewGameVars(1); } - Player.CombatDifficulty = Difficulty; + Player.CombatDifficulty = difficulty; } #endif diff --git a/DXRVanilla/DeusEx/Classes/Augmentation.uc b/DXRVanilla/DeusEx/Classes/Augmentation.uc index 1a7a7a182..ded12dfd1 100644 --- a/DXRVanilla/DeusEx/Classes/Augmentation.uc +++ b/DXRVanilla/DeusEx/Classes/Augmentation.uc @@ -1,12 +1,107 @@ class DXRAugmentation merges Augmentation; +var float LastUsed; +var float AutoLength; + function PostBeginPlay() { local DXRAugmentations a; Super.PostBeginPlay(); + SetAutomatic(); + foreach AllActors(class'DXRAugmentations', a) { a.RandoAug(self); break; } } + +simulated function SetAutomatic() +{ + if(default.bAutomatic) { + // AugVision and AugMuscle have randomized energyRate, but they aren't bAutomatic anyways + energyRate = default.energyRate; + } + + if(class'MenuChoice_AutoAugs'.default.enabled) { + bAutomatic = default.bAutomatic; + if(bAutomatic) { + energyRate = default.energyRate * 2; + } + } + else { + bAutomatic = false; + } +} + +simulated function bool IsTicked() +{ + return (bAutomatic==false && bIsActive) + || (bAutomatic && LastUsed+AutoLength > Level.TimeSeconds && Player.Energy > 0); +} + +simulated function TickUse() +{ + if(bAutomatic && !IsTicked()) { + Player.Energy -= energyRate/60.0; + if(Player.Energy <= 0) { + Player.Energy = 0; + return;// don't update the LastUsed + } else { + Player.PlaySound(ActivateSound, SLOT_None, 0.75); + Player.AmbientSound = LoopSound; + } + } + LastUsed = Level.TimeSeconds; +} + +simulated function float GetEnergyRate() +{ + if(bAutomatic && !IsTicked()) { + if (Player.AmbientSound == LoopSound && Player.AugmentationSystem.NumAugsActive() == 0) { + Player.PlaySound(DeactivateSound, SLOT_None, 0.75); + Player.AmbientSound = None; + } + return 0; + } + return energyRate; +} + +// fix hum sounds for auto augs +function Activate() +{ + local Sound oldAmbient; + + oldAmbient = Player.AmbientSound; + + _Activate();// call the super, but this is merges + + if(bAutomatic && oldAmbient != LoopSound && Player.AmbientSound == LoopSound) + Player.AmbientSound = oldAmbient; +} + + +// DXRando: don't disable auto augs when upgrading +function bool IncLevel() +{ + if ( !CanBeUpgraded() ) + { + Player.ClientMessage(Sprintf(AugAlreadyHave, AugmentationName)); + return False; + } + + if (bIsActive && !bAutomatic) { + Deactivate(); + } + + CurrentLevel++; + + Player.ClientMessage(Sprintf(AugNowHave, AugmentationName, CurrentLevel + 1)); +} + + +defaultproperties +{ + LastUsed=-100 + AutoLength=5 +} diff --git a/DXRVanilla/DeusEx/Classes/BarkManager.uc b/DXRVanilla/DeusEx/Classes/BarkManager.uc new file mode 100644 index 000000000..8698a6781 --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/BarkManager.uc @@ -0,0 +1,106 @@ +class DXRBarkManager injects BarkManager; + +//Copied from regular BarkManager, added pitchAdjust +function bool StartBark(DeusExRootWindow newRoot, ScriptedPawn newBarkPawn, EBarkModes newBarkMode) +{ + local Name conName; + local Conversation con; + local int barkIndex; + local Float barkDuration; + local bool bBarkStarted; + local ConPlayBark conPlayBark; + local String conSpeechString; + local ConSpeech conSpeech; + local Sound speechAudio; + local bool bHaveSpeechAudio; + local int playingSoundID; + local float pitchAdjust; + + pitchAdjust=class'DXRMemes'.static.GetVoicePitch(Human(owner).dxr); + minimumTextPause = Default.minimumTextPause / pitchAdjust; + + bBarkStarted = False; + + // Store away the root window + rootWindow = newRoot; + + // Don't even go any further if the actor is too far away + // from the player + if (!CheckRadius(newBarkPawn)) + return False; + + // Now check the height difference + if (!CheckHeightDifference(newBarkPawn)) + return False; + + // First attempt to find this conversation + conName = BuildBarkName(newBarkPawn, newBarkMode); + + // Okay, we have the name of the bark, now attempt to find a + // conversation based on this name. + con = ConListItem(newBarkPawn.conListItems).FindConversationByName(conName); + + if (con != None) + { + barkIndex = GetAvailableCurrentBarkSlot(newBarkPawn, newBarkMode); + + // Abort if we don't get a valid barkIndex back + if (barkIndex == -1) + return False; + + // Make sure that another NPC isn't already playing this + // particular bark. + if (IsBarkPlaying(conName)) + return False; + + // Now check to see if the same kind of bark has already been + // played by this NPC within a certain range of time. + if (HasBarkTypePlayedRecently(newBarkPawn, newBarkMode)) + return False; + + // Summon a 'ConPlayBark' object, which will process + // the conversation and play the bark. + // Found an active conversation, so start it + conPlayBark = Spawn(class'ConPlayBark'); + conPlayBark.SetConversation(con); + + conSpeech = conPlayBark.GetBarkSpeech(); + + bHaveSpeechAudio = False; + + // Nuke conPlayBark + conPlayBark.Destroy(); + + // Play the audio (if we have audio) + if ((conSpeech != None) && (conSpeech.soundID != -1)) + { + speechAudio = con.GetSpeechAudio(conSpeech.soundID); + + if (speechAudio != None) + { + bHaveSpeechAudio = True; + playingSoundID = newBarkPawn.PlaySound(speechAudio, SLOT_Talk,,,1024.0,pitchAdjust); + barkDuration = con.GetSpeechLength(conSpeech.soundID) / pitchAdjust; + } + } + + // If we don't have any audio, then calculate the timer based on the + // length of the speech text. + + if ((conSpeech != None) && (!bHaveSpeechAudio)) + barkDuration = FMax(Len(conSpeech.speech) * perCharDelay / pitchAdjust, minimumTextPause); + + // Show the speech if Subtitles are on + if ((DeusExPlayer(owner) != None) && (DeusExPlayer(owner).bSubtitles) && (conSpeech != None) && (conSpeech.speech != "")) + { + rootWindow.hud.barkDisplay.AddBark(conSpeech.speech, barkDuration, newBarkPawn); + } + + // Keep track fo the bark + SetBarkInfo(barkIndex, conName, newBarkPawn, newBarkMode, barkDuration, playingSoundID); + + bBarkStarted = True; + } + + return bBarkStarted; +} diff --git a/DXRVanilla/DeusEx/Classes/ConPlay.uc b/DXRVanilla/DeusEx/Classes/ConPlay.uc new file mode 100644 index 000000000..f65fd5973 --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/ConPlay.uc @@ -0,0 +1,114 @@ +class DXRConPlay injects ConPlay; + +var float pitchAdjust; + +//Copied from ConPlay, but added pitchAdjust +function PlaySpeech( int soundID, Actor speaker ) +{ + local Sound speech; + + pitchAdjust=class'DXRMemes'.static.GetVoicePitch(Human(player).dxr); + perCharDelay = default.perCharDelay / pitchAdjust; + minimumTextPause = default.minimumTextPause / pitchAdjust; + + speech = con.GetSpeechAudio(soundID); + + // Keep a pointer to the current speaking pawn so we can stop + // the speech animation when we're finished. + + if (speech != None) + { + // If this is an intro/endgame, force speech to play through + // the player so we can *hear* it. + if (bForcePlay) + { + // Check how close the player is to this actor. If the player is + // close enough to the speaker, play through the speaker. + if ((speaker == None) || (VSize(player.Location - speaker.Location) > 400)) + { + playingSoundID = player.PlaySound(speech, SLOT_Talk,,,65536.0,pitchAdjust); + } + else + { + playingSoundID = speaker.PlaySound(speech, SLOT_Talk,,,65536.0,pitchAdjust); + } + } + else + { + // If this is a forced conversation (bCannotBeInterrupted = True) + // then set the radius higher. This is a hack. Yes, a hack, + // in some situations where the PC is far from one or more speaking + // NPCs but needs to be able to overhear them. Also, want to make + // this reasonably loud for letterbox convos + + if ((con.bCannotBeInterrupted) || (!con.bFirstPerson)) + playingSoundID = speaker.PlaySound(speech, SLOT_Talk,,,65536.0,pitchAdjust); + else + playingSoundID = speaker.PlaySound(speech, SLOT_Talk,,,512.0 + initialRadius,pitchAdjust); + } + } + + StartSpeakingAnimation(); +} + + +state WaitForSpeech +{ + // We get here when the timer we set when playing the sound + // has finished. We want to play the next event. + function Timer() + { + GotoState( 'WaitForSpeech', 'SpeechFinished' ); + } + +SpeechFinished: + // Restrict input + if (conWinThird != None) + conWinThird.RestrictInput(True); + + StopSpeakingAnimation(); + + // Sleep for a second before continuing + Sleep(0.5); + + // Fire the next event + PlayNextEvent(); + Stop; + +Idle: + // Allow input + if (conWinThird != None) + conWinThird.RestrictInput(False); + + Sleep(0.5); + Goto('Idle'); + +Begin: + + pitchAdjust=class'DXRMemes'.static.GetVoicePitch(Human(player).dxr); + perCharDelay = default.perCharDelay / pitchAdjust; + minimumTextPause = default.minimumTextPause / pitchAdjust; + + // If this is a first person conversation and A) we don't have speech + // or B) we're in "Subtitles Only" mode, then set a timer based on + // the length of speech. + + if ( ConEventSpeech(currentEvent).conSpeech.soundID == -1 ) + { + SetTimer( FMax(lastSpeechTextLength * perCharDelay / pitchAdjust, minimumTextPause), False ); + } + else + { + // Play the sound, set the timer and go to sleep until the sound + // has finished playing. + + // First Stop any sound that was playing + PlaySpeech( ConEventSpeech(currentEvent).conSpeech.soundID, ConEventSpeech(currentEvent).Speaker ); + + // Add two seconds to the sound since there seems to be a slight lag + SetTimer( con.GetSpeechLength(ConEventSpeech(currentEvent).conSpeech.soundID)/pitchAdjust, False ); + log ("Original timer length: "$con.GetSpeechLength(ConEventSpeech(currentEvent).conSpeech.soundID)$" pitch adjust: "$pitchAdjust$" after adjust length: "$con.GetSpeechLength(ConEventSpeech(currentEvent).conSpeech.soundID)/pitchAdjust); + } + + Goto('Idle'); +} diff --git a/DXRVanilla/DeusEx/Classes/ConWindowActive.uc b/DXRVanilla/DeusEx/Classes/ConWindowActive.uc new file mode 100644 index 000000000..26da1a783 --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/ConWindowActive.uc @@ -0,0 +1,92 @@ +class DXRConWindowActive merges ConWindowActive; +// merges because Kentie's Launcher does this https://github.com/Die4Ever/deus-ex-randomizer/issues/453 + +var TextWindow creditsText; + +event InitWindow() +{ + _InitWindow(); + CreateCreditsWindow(); +} + +function CreateCreditsWindow() +{ + creditsText = TextWindow(upperConWindow.NewChild(class'TextWindow')); + creditsText.SetTextColor(class'ConWindowSpeech'.Default.colConTextNormal); + creditsText.SetTextAlignments(HALIGN_Left, VALIGN_Top); + creditsText.SetFont(class'ConPlay'.Default.ConversationSpeechFonts[0]); + creditsText.Show(False); +} + +function UpdateCreditsWindow() +{ + if (player!=None){ + creditsText.SetText("Credits: "$player.credits); + } + + //bForcePlay is true during the intro and endgames + creditsText.Show(!bForcePlay); +} + +//Gets called on every new screen in a conversation. +//Parameter indicates whether it will accept input or not +function RestrictInput(bool bNewRestrictInput) +{ + _RestrictInput(bNewRestrictInput); + UpdateCreditsWindow(); +} + +event bool VirtualKeyPressed(EInputKey key, bool bRepeat) +{ + local int selectedOption; + + selectedOption=0; + switch(key){ + case IK_1: + case IK_NumPad1: + selectedOption=1; + break; + case IK_2: + case IK_NumPad2: + selectedOption=2; + break; + case IK_3: + case IK_NumPad3: + selectedOption=3; + break; + case IK_4: + case IK_NumPad4: + selectedOption=4; + break; + case IK_5: + case IK_NumPad5: + selectedOption=5; + break; + default: + selectedOption=0; + break; + } + + if ( numChoices != 0 ){ + if (selectedOption!=0){ + if (selectedOption<=numChoices){ + ButtonActivated(conChoices[selectedOption-1]); + return True; + } + } + } else { + if (selectedOption!=0){ + conPlay.PlayNextEvent(); + return True; + } + } + + return _VirtualKeyPressed(key,bRepeat); +} + +function AddButton( ConChoiceWindow newButton ) +{ + _AddButton(newButton); + + newButton.SetText("("$numChoices$") "$ Mid(newButton.GetText(),2)); // (#) Dialog option +} diff --git a/DXRVanilla/DeusEx/Classes/DXRAmmo.uc b/DXRVanilla/DeusEx/Classes/DXRAmmo.uc new file mode 100644 index 000000000..ffdb738a3 --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/DXRAmmo.uc @@ -0,0 +1,33 @@ +Class DXRAmmo injects #var(DeusExPrefix)Ammo; + +function bool HandlePickupQuery( inventory Item ) +{ + local Ammo ownedAmmo,thisAmmo; + local int ammoToAdd,ammoRemaining; + local DeusExPlayer player; + + thisAmmo = Ammo(Item); + player = DeusExPlayer(Owner); + + if (thisAmmo!=None && player!=None && Item.Class == Class && thisAmmo.AmmoAmount > 0){ + ownedAmmo = Ammo(player.FindInventoryType(thisAmmo.Class)); + if (ownedAmmo!=None){ + ammoToAdd = thisAmmo.AmmoAmount; + ammoRemaining=0; + if ((ammoToAdd + ownedAmmo.AmmoAmount) > ownedAmmo.MaxAmmo){ + ammoRemaining = (ammoToAdd + ownedAmmo.AmmoAmount) - ownedAmmo.MaxAmmo; + ammoToAdd = ammoToAdd - ammoRemaining; + } + + if (ammoRemaining>0){ + thisAmmo.ammoAmount = ammoRemaining; + AddAmmo(ammoToAdd); + return True; + } + } + + } + + return Super.HandlePickupQuery(Item); + +} diff --git a/DXRVanilla/DeusEx/Classes/DXRNetworkTerminal.uc b/DXRVanilla/DeusEx/Classes/DXRNetworkTerminal.uc index d8eab0206..7fd1951e4 100644 --- a/DXRVanilla/DeusEx/Classes/DXRNetworkTerminal.uc +++ b/DXRVanilla/DeusEx/Classes/DXRNetworkTerminal.uc @@ -104,14 +104,12 @@ function CloseScreen(String action) function CreateKnownAccountsWindow() { - local int codes_mode; - codes_mode = int(player.ConsoleCommand("get #var(package).MenuChoice_PasswordAutofill codes_mode")); - if( codes_mode < 1 ) return; + if( class'MenuChoice_PasswordAutofill'.default.codes_mode < 1 ) return; winKnownShadow = ShadowWindow(NewChild(Class'ShadowWindow')); winKnownAccounts = ComputerScreenKnownAccounts(NewChild(Class'ComputerScreenKnownAccounts')); - if( codes_mode == 2 ) + if( class'MenuChoice_PasswordAutofill'.default.codes_mode == 2 ) winKnownAccounts.bShowPasswords = true; winKnownAccounts.SetNetworkTerminal(Self); winKnownAccounts.SetCompOwner(compOwner); diff --git a/DXRVanilla/DeusEx/Classes/DXRShowClassWindow.uc b/DXRVanilla/DeusEx/Classes/DXRShowClassWindow.uc new file mode 100644 index 000000000..dc5db71fb --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/DXRShowClassWindow.uc @@ -0,0 +1,74 @@ +class DXRShowClassWindow injects ShowClassWindow; + +var ToolEditWindow custAttribName; +var ToolEditWindow nameFilter; +var ToolEditWindow radiusFilter; +var ToolCheckboxWindow chkCustom; +var ToolCheckboxWindow chkInventory; +var ToolCheckboxWindow chkLimitRadius; +var ToolCheckboxWindow chkTagEvent; +var ToolCheckboxWindow chkTagConns; +var ToolCheckboxWindow chkEventConns; + +event InitWindow() +{ + Super.InitWindow(); + + SetSize(420,420); //215,420 normally + + CreateDXRandoControls(); +} + +function CreateDXRandoControls() +{ + // If you wanted the custom attribute up at the top of the window + CreateToolLabel(218, 30, "Name Filter:"); + nameFilter = CreateToolEditWindow(215, 50, 185, 64); + nameFilter.SetText(actorDisplay.GetNameFilter()); + nameFilter.SetInsertionPoint(Len(actorDisplay.GetNameFilter()) - 1); + nameFilter.SetSelectedArea(0, Len(actorDisplay.GetNameFilter())); + + chkCustom = CreateToolCheckbox(215, 90, "Show Custom Attribute", actorDisplay.IsCustomVisible()); + + // Spot to enter the custom attribute to show + custAttribName = CreateToolEditWindow(235, 105, 160, 64); + custAttribName.SetText(actorDisplay.GetCustomAttrib()); + custAttribName.SetInsertionPoint(Len(actorDisplay.GetCustomAttrib()) - 1); + custAttribName.SetSelectedArea(0, Len(actorDisplay.GetCustomAttrib())); + + // Show inventory + chkInventory = CreateToolCheckbox(215, 130, "Show Inventory", actorDisplay.IsInventoryVisible()); + + //Limit the actors shown to a radius? + chkLimitRadius = CreateToolCheckbox(215, 155, "Limit to Radius", actorDisplay.IsRadiusLimited()); + + // Spot to enter the radius limit + radiusFilter = CreateToolEditWindow(235, 170, 160, 64); + radiusFilter.SetText(string(actorDisplay.GetActorRadius())); + radiusFilter.SetInsertionPoint(Len(string(actorDisplay.GetActorRadius())) - 1); + radiusFilter.SetSelectedArea(0, Len(string(actorDisplay.GetActorRadius()))); + + //Show the tag and event of the actors? + chkTagEvent = CreateToolCheckbox(215, 195, "Show Tag and Event", actorDisplay.IsTagEventVisible()); + + chkTagConns = CreateToolCheckbox(215, 220, "Show Connections to Tag (Green)", actorDisplay.IsTagConnsVisible()); + chkEventConns = CreateToolCheckbox(215, 245, "Show Connections to Event (Red)", actorDisplay.IsEventConnsVisible()); + +} + +function SaveSettings() +{ + Super.SaveSettings(); + + actorDisplay.SetNameFilter(nameFilter.GetText()); + actorDisplay.SetCustomAttrib(custAttribName.GetText()); + actorDisplay.ShowCustom(chkCustom.GetToggle()); + + actorDisplay.ShowInventory(chkInventory.GetToggle()); + actorDisplay.ShowTagEvent(chkTagEvent.GetToggle()); + actorDisplay.ShowTagConns(chkTagConns.GetToggle()); + actorDisplay.ShowEventConns(chkEventConns.GetToggle()); + + actorDisplay.LimitRadius(chkLimitRadius.GetToggle()); + actorDisplay.SetActorRadius(radiusFilter.GetText()); +} diff --git a/DXRVanilla/DeusEx/Classes/DataLinkPlay.uc b/DXRVanilla/DeusEx/Classes/DataLinkPlay.uc index 47ff024d0..fbfe213cb 100644 --- a/DXRVanilla/DeusEx/Classes/DataLinkPlay.uc +++ b/DXRVanilla/DeusEx/Classes/DataLinkPlay.uc @@ -3,6 +3,7 @@ class DataLinkPlay injects DataLinkPlay; var transient float speechFastEndTime; var transient bool restarting; var DataLinkTrigger dataLinkTriggerQueue[16]; +var transient float pitchAdjust; function bool PushDataLink( Conversation queueCon ) { @@ -21,8 +22,17 @@ function bool PushDataLink( Conversation queueCon ) function PlaySpeech( int soundID ) { + local Sound speech; + + pitchAdjust=class'DXRMemes'.static.GetVoicePitch(Human(player).dxr); + perCharDelay = default.perCharDelay / pitchAdjust; + speechFastEndTime = Level.Timeseconds + lastSpeechTextLength * perCharDelay; - Super.PlaySpeech(soundID); + + speech = con.GetSpeechAudio(soundID); + + if (speech != None) + playingSoundID = player.PlaySound(speech, SLOT_Talk,,,,pitchAdjust); } function bool HaveQueued() @@ -30,6 +40,40 @@ function bool HaveQueued() return dataLinkQueue[0] != None; } +function FastForward() +{ + bSilent = True; + + // Make sure no sound playing + player.StopSound(playingSoundId); + + if ((!bEndTransmission) && (bStartTransmission)) + { + bStartTransmission = False; + SetTimer(0.0, False); + } + else if(GetStateName() == 'WaitForSpeech') { + PlayNextEvent(); + } + + while(currentEvent != None) { + SetupEventFunc(); + } + + rootWindow.hud.DestroyInfoLinkWindow(); + dataLink = None; + + if ( FireNextDataLink() == False ) + { + player.dataLinkPlay = None; + Destroy(); + } + else + { + FastForward(); + } +} + ///// function Bool StartConversation(DeusExPlayer newPlayer, optional Actor newInvokeActor, optional bool bForcePlay) @@ -76,7 +120,7 @@ function Bool StartConversation(DeusExPlayer newPlayer, optional Actor newInvoke // Play a sound and wait a few seconds before starting datalink.ShowTextCursor(False); - if(restarting) { + if(restarting || bSilent) { bStartTransmission = True; restarting = false; SetTimer(0.05, True); @@ -118,6 +162,8 @@ Idle: Goto('Idle'); Begin: + pitchAdjust=class'DXRMemes'.static.GetVoicePitch(Human(player).dxr); + perCharDelay = default.perCharDelay / pitchAdjust; // Play the sound, set the timer and go to sleep until the sound // has finished playing. @@ -135,15 +181,15 @@ Begin: if(HaveQueued() == false || Human(player).bZeroRando) { // Add two seconds to the sound since there seems to be a slight lag - SetTimer( con.GetSpeechLength(ConEventSpeech(currentEvent).conSpeech.soundID), False ); + SetTimer( con.GetSpeechLength(ConEventSpeech(currentEvent).conSpeech.soundID) / pitchAdjust, False ); } else { // if we have queued items, use the fast timer just for showing text - SetTimer( lastSpeechTextLength * perCharDelay, False ); + SetTimer( lastSpeechTextLength * perCharDelay / pitchAdjust, False ); } } else { - SetTimer( lastSpeechTextLength * perCharDelay, False ); + SetTimer( lastSpeechTextLength * perCharDelay / pitchAdjust, False ); } Goto('Idle'); @@ -183,6 +229,90 @@ function NotifyDatalinkTrigger() } +// copied from state PlayEvent, because FastForward needs this to happen immediately +function SetupEventFunc() +{ + local EEventAction nextAction; + local String nextLabel; + + if ( currentEvent == None ) { + TerminateConversation(); + return; + } + + switch( currentEvent.EventType ) + { + // Unsupported events + case ET_MoveCamera: + case ET_Choice: + case ET_Animation: + case ET_Trade: + break; + + case ET_Speech: + nextAction = SetupEventSpeech( ConEventSpeech(currentEvent), nextLabel ); + break; + + case ET_SetFlag: + nextAction = SetupEventSetFlag( ConEventSetFlag(currentEvent), nextLabel ); + break; + + case ET_CheckFlag: + nextAction = SetupEventCheckFlag( ConEventCheckFlag(currentEvent), nextLabel ); + break; + + case ET_CheckObject: + nextAction = SetupEventCheckObject( ConEventCheckObject(currentEvent), nextLabel ); + break; + + case ET_Jump: + nextAction = SetupEventJump( ConEventJump(currentEvent), nextLabel ); + break; + + case ET_Random: + nextAction = SetupEventRandomLabel( ConEventRandomLabel(currentEvent), nextLabel ); + break; + + case ET_Trigger: + nextAction = SetupEventTrigger( ConEventTrigger(currentEvent), nextLabel ); + break; + + case ET_AddGoal: + nextAction = SetupEventAddGoal( ConEventAddGoal(currentEvent), nextLabel ); + break; + + case ET_AddNote: + nextAction = SetupEventAddNote( ConEventAddNote(currentEvent), nextLabel ); + break; + + case ET_AddSkillPoints: + nextAction = SetupEventAddSkillPoints( ConEventAddSkillPoints(currentEvent), nextLabel ); + break; + + case ET_AddCredits: + nextAction = SetupEventAddCredits( ConEventAddCredits(currentEvent), nextLabel ); + break; + + case ET_CheckPersona: + nextAction = SetupEventCheckPersona( ConEventCheckPersona(currentEvent), nextLabel ); + break; + + case ET_TransferObject: + nextAction = SetupEventTransferObject( ConEventTransferObject(currentEvent), nextLabel ); + break; + + case ET_End: + nextAction = SetupEventEnd( ConEventEnd(currentEvent), nextLabel ); + break; + } + + // Based on the result of the setup, we either need to jump to another event + // or wait for some input from the user. + + ProcessAction( nextAction, nextLabel ); +} + + defaultproperties { blinkRate=0.3 diff --git a/DXRVanilla/DeusEx/Classes/HUDObjectBelt.uc b/DXRVanilla/DeusEx/Classes/HUDObjectBelt.uc index c483363d1..7252435be 100644 --- a/DXRVanilla/DeusEx/Classes/HUDObjectBelt.uc +++ b/DXRVanilla/DeusEx/Classes/HUDObjectBelt.uc @@ -9,3 +9,9 @@ function UpdateObjectText(int pos) if(objects[i] != None) objects[i].UpdateItemText(); } } + +event DrawWindow(GC gc) +{ + Super.DrawWindow(gc); + UpdateObjectText(0); //Make sure ammo counts are updated +} diff --git a/DXRVanilla/DeusEx/Classes/MenuSelectDifficulty.uc b/DXRVanilla/DeusEx/Classes/MenuSelectDifficulty.uc index 6ec0031be..e9bae98e8 100644 --- a/DXRVanilla/DeusEx/Classes/MenuSelectDifficulty.uc +++ b/DXRVanilla/DeusEx/Classes/MenuSelectDifficulty.uc @@ -2,7 +2,7 @@ class MenuSelectDifficulty extends DXRMenuSelectDifficulty; // a stub to overwrite the original game's MenuSelectDifficulty // stub for Lay D Denton compatibility -function InvokeNewGameScreen(float difficulty) +function InvokeNewGameScreen(float d) { - Super.InvokeNewGameScreen(difficulty); + DoNewGameScreen(); } diff --git a/DXRVanilla/DeusEx/Classes/Mission01.uc b/DXRVanilla/DeusEx/Classes/Mission01.uc new file mode 100644 index 000000000..6a09ab26b --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/Mission01.uc @@ -0,0 +1,21 @@ +class DXRMission01 injects Mission01; + +function Timer() +{ + local ScriptedPawn P; + + if (!flags.GetBool('MS_MissionComplete')) + { + if (flags.GetBool('StatueMissionComplete')) + { + foreach AllActors(class'ScriptedPawn', P) + { + if (P.GetAllianceType('player')!=ALLIANCE_Hostile) continue; //Only destroy enemies + if (#var(prefix)Terrorist(P)!=None) continue; //Skip these and let the original script handle them + if (InStr(P.Tag,"_clone")!=-1) P.Destroy(); + } + //The original mission script will mark MS_MissionComplete + } + } + Super.Timer(); +} diff --git a/DXRVanilla/DeusEx/Classes/Mission03.uc b/DXRVanilla/DeusEx/Classes/Mission03.uc new file mode 100644 index 000000000..a1fec7dbe --- /dev/null +++ b/DXRVanilla/DeusEx/Classes/Mission03.uc @@ -0,0 +1,28 @@ +class DXRMission03 injects Mission03; + +function FirstFrame() +{ + local ScriptedPawn P; + local bool trashEm; + + trashEm=False; + + if (localURL == "03_NYC_AIRFIELDHELIBASE" || localURL == "03_NYC_AIRFIELD") + { + if (flags.GetBool('MeetLebedev_Played') || + flags.GetBool('JuanLebedev_Dead')) + { + trashEm = True; + } + } + + if (trashEm) + { + foreach AllActors(class'ScriptedPawn', P) + { + if (P.GetAllianceType('player')!=ALLIANCE_Hostile) continue; //Only destroy enemies + if (InStr(P.Tag,"_clone")!=-1) P.Destroy(); + } + } + Super.FirstFrame(); +} diff --git a/DXRVanilla/DeusEx/Classes/PersonaScreenInventory.uc b/DXRVanilla/DeusEx/Classes/PersonaScreenInventory.uc index 282832162..3e79dc22e 100644 --- a/DXRVanilla/DeusEx/Classes/PersonaScreenInventory.uc +++ b/DXRVanilla/DeusEx/Classes/PersonaScreenInventory.uc @@ -85,3 +85,43 @@ function string CalcChargedPickupDurations(ChargedPickup cp) return chargeVals; } + +//Dragging an item out of the inventory grid will now drop it +function FinishButtonDrag() +{ + local Inventory draggedItem; + local Bool shouldDrop; + + shouldDrop=False; + draggedItem=None; + + if (lastDragOverWindow==None){ + draggedItem=Inventory(dragButton.GetClientObject()); + shouldDrop = (draggedItem!=None); + } + + Super.FinishButtonDrag(); + + if (shouldDrop && draggedItem!=None){ + SelectInventoryItem(draggedItem); + DropSelectedItem(); + } +} + +//Try to prevent item stacking +//If an item is being "dragged" while the inventory is closing, put it back where it started +event DescendantRemoved(Window descendant) +{ + local Inventory draggedItem; + + if (descendant==winStatus){ //Only act as the inventory is being dismantled + if (class'MenuChoice_FixGlitches'.default.enabled && bDragging && dragButton!=None){ + draggedItem=Inventory(dragButton.GetClientObject()); + if (draggedItem!=None){ + //Return the item to the slot it started in + player.PlaceItemInSlot(draggedItem,draggedItem.invPosX,draggedItem.invPosY); + } + } + } + Super.DescendantRemoved(descendant); +} diff --git a/DXRVanilla/DeusEx/Classes/Player.uc b/DXRVanilla/DeusEx/Classes/Player.uc index e1c9be2ce..1417a8fa7 100644 --- a/DXRVanilla/DeusEx/Classes/Player.uc +++ b/DXRVanilla/DeusEx/Classes/Player.uc @@ -5,6 +5,8 @@ var DXRando dxr; var DXRLoadouts loadout; var bool bOnLadder; var transient string nextMap; +var laserEmitter aimLaser; +var bool bDoomMode; var Rotator ShakeRotator; @@ -31,6 +33,42 @@ function PlayerMove( float DeltaTime ) GotoState('PlayerWalking'); } +event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) +{ + local CCResidentEvilCam reCam; + + reCam = CCResidentEvilCam(ViewTarget); + + if (reCam!=None){ + CameraRotation = reCam.Rotation; + CameraLocation = reCam.Location; + return; + } else { + Super.PlayerCalcView(ViewActor,CameraLocation,CameraRotation); + if (bDoomMode){ + CameraRotation.Pitch=0; + ViewRotation.Pitch=0; + } + } +} + +function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist) +{ + local vector View,HitLocation,HitNormal; + local float ViewDist; + + Dist = Dist/1.25; //Bring the camera in a bit closer than normal + + CameraRotation = ViewRotation; + CameraLocation.Z+=BaseEyeHeight; //Adjust camera center to eye height + View = vect(1,-0.2,0) >> CameraRotation; //Slightly offset the view to the right (so it's over the shoulder) + if( Trace( HitLocation, HitNormal, CameraLocation - (Dist + 30) * vector(CameraRotation), CameraLocation ) != None ) + ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist ); + else + ViewDist = Dist; + CameraLocation -= (ViewDist - 30) * View; +} + event ClientTravel( string URL, ETravelType TravelType, bool bItems ) { nextMap = URL; @@ -138,8 +176,8 @@ exec function QuickSave() info = GetLevelInfo(); //Same logic from DeusExPlayer, so we can add a log message if the quick save succeeded or not - if (((info != None) && (info.MissionNumber < 0)) || - ((IsInState('Dying')) || (IsInState('Paralyzed')) || (IsInState('Interpolating'))) || + if (((info != None) && (info.MissionNumber < 0)) || + ((IsInState('Dying')) || (IsInState('Paralyzed')) || (IsInState('Interpolating'))) || (dataLinkPlay != None) || (Level.Netmode != NM_Standalone)) { ClientMessage("Cannot quick save during infolink!",, true); @@ -171,14 +209,14 @@ function bool HandleItemPickup(Actor FrobTarget, optional bool bSearchOnly) //Try to apply the mod being picked up to the currently held weapon //Does not happen in Zero Rando - if (!dxr.flags.IsZeroRando() && bool(ConsoleCommand("get #var(package).MenuChoice_AutoWeaponMods enabled"))){ + if (!dxr.flags.IsZeroRando() && class'MenuChoice_AutoWeaponMods'.default.enabled){ mod = #var(prefix)WeaponMod(FrobTarget); weap = #var(DeusExPrefix)Weapon(inHand); if (mod!=None && weap!=None){ if (mod.CanUpgradeWeapon(weap)){ mod.ApplyMod(weap); ClientMessage(mod.ItemName$" applied to "$weap.ItemName); - if (mod.IsA('WeaponModLaser') && bool(ConsoleCommand("get #var(package).MenuChoice_AutoLaser enabled"))){ + if (mod.IsA('WeaponModLaser') && class'MenuChoice_AutoLaser'.default.enabled){ weap.LaserOn(); } mod.DestroyMod(); @@ -484,6 +522,33 @@ exec function ParseLeftClick() } } +exec function ParseRightClick() +{ + local bool handled; + local #var(DeusExPrefix)Mover dxm; + handled=False; + + if (RestrictInput()) + return; + + if (#var(DeusExPrefix)Mover(FrobTarget) != None){ //If it's a door... + dxm=#var(DeusExPrefix)Mover(FrobTarget); + //That is locked and you have the key + if (dxm.bLocked && dxm.KeyIDNeeded != '' && KeyRing.HasKey(dxm.KeyIDNeeded)){ + //And you aren't carrying anything + if (CarriedDecoration==None){ + handled=True; + PutInHand(KeyRing); + UpdateInHand(); + } + } + } + + if (!handled){ + Super.ParseRightClick(); + } +} + //A whole lot of copy paste just to add one "if (bDrop)" check to change the dropVect exec function bool DropItem(optional Inventory inv, optional bool bDrop) { @@ -747,10 +812,61 @@ function bool IsHighlighted(actor A) wasBehind = bBehindView; bBehindView = False; highlight = Super.IsHighlighted(A); + if (LaserTrigger(A)!=None || BeamTrigger(A)!=None){ + highlight=True; + } bBehindView = wasBehind; return highlight; } +function bool IsFrobbable(actor A) +{ + if (!A.bHidden) + if (A.IsA('BeamTrigger') || A.IsA('LaserTrigger')) + return True; + + return Super.IsFrobbable(A); +} + +function HighlightCenterObject() +{ + local CCResidentEvilCam reCam; + local Vector loc; + + Super.HighlightCenterObject(); + + + reCam = CCResidentEvilCam(ViewTarget); + + //Activate the aim laser any time you aren't seeing through your eyes + if (reCam!=None || bBehindView){ + if (aimLaser==None){ + aimLaser = Spawn(class'LaserEmitter', Self, , Location, Pawn(Owner).ViewRotation); + if (aimLaser != None) { + aimLaser.SetHiddenBeam(False); + aimLaser.AmbientSound = None; + aimLaser.SetBlueBeam(); + } else { + ClientMessage("Failed to spawn aim laser?"); + } + } + + loc = Location; + loc.Z+=BaseEyeHeight; + loc = loc + vector(ViewRotation) * (CollisionRadius/2); + aimLaser.SetLocation(loc); + aimLaser.SetRotation(ViewRotation); + aimLaser.proxy.DistanceFromPlayer=0; //Make sure the laser doesn't get frozen + + aimLaser.TurnOn(); + + } else { + if (aimLaser!=None){ + aimLaser.TurnOff(); + } + } +} + exec function CrowdControlAnon() { local DXRCrowdControl cc; @@ -951,6 +1067,9 @@ function UpdateRotation(float DeltaTime, float maxPitch) } //Track and handle shake rotation as though we are always right-ways up + //Carry the Yaw over, since the shake doesn't adjust that, so it resets you + //to Yaw 0 when a roll starts otherwise (Issue #608) + ShakeRotator.Yaw = ViewRotation.Yaw; ViewRotation = ShakeRotator; Super.UpdateRotation(DeltaTime,maxPitch); ShakeRotator = ViewRotation; @@ -1032,6 +1151,7 @@ function UpdateAnimRate( float augValue ) } function PlayDying(name damageType, vector hitLoc) { + SetCollision(false,false,false); Super.PlayDying(damageType, hitLoc); } function TweenToSwimming(float tweentime) diff --git a/DXRVanilla/DeusEx/Classes/RootWindow.uc b/DXRVanilla/DeusEx/Classes/RootWindow.uc index 1dd285565..3bacc1c3f 100644 --- a/DXRVanilla/DeusEx/Classes/RootWindow.uc +++ b/DXRVanilla/DeusEx/Classes/RootWindow.uc @@ -37,7 +37,7 @@ function DeusExBaseWindow PopWindow(optional Bool bNoUnpause) local SkilledTool tool; local bool bFixGlitches; - bFixGlitches = bool(parentPawn.ConsoleCommand("get #var(package).MenuChoice_FixGlitches enabled")); + bFixGlitches = class'MenuChoice_FixGlitches'.default.enabled; // check for super jumps f = DeusExPlayer(parentPawn).AugmentationSystem.GetAugLevelValue(class'AugSpeed'); diff --git a/DXRVanilla/DeusEx/Classes/Weapon.uc b/DXRVanilla/DeusEx/Classes/Weapon.uc index ea1884fc8..c6e372516 100644 --- a/DXRVanilla/DeusEx/Classes/Weapon.uc +++ b/DXRVanilla/DeusEx/Classes/Weapon.uc @@ -8,6 +8,8 @@ var name prev_anim; var float prev_anim_rate; var float prev_weapon_skill; +var int WeaponTexLoc[8]; + function PostBeginPlay() { local DXRWeapons m; @@ -20,6 +22,8 @@ function PostBeginPlay() function BringUp() { + local int texLoc; + Super.BringUp(); // don't let NPC geps lock on to targets @@ -28,10 +32,19 @@ function BringUp() else bCanTrack = default.bCanTrack; - if (bool(ConsoleCommand("get #var(package).MenuChoice_AutoLaser enabled"))){ + if (class'MenuChoice_AutoLaser'.default.enabled){ //LaserOn already checks to see if it has a laser, so just call it LaserOn(); } + + for (texLoc=0;texLoc<8;texLoc++){ + if (IsWeaponTexture(texLoc)){ + WeaponTexLoc[texLoc]=1; + } else { + WeaponTexLoc[texLoc]=0; + } + } + } simulated function Tick(float deltaTime) @@ -46,23 +59,31 @@ simulated function Tick(float deltaTime) if(AnimSequence != prev_anim || GetWeaponSkill() != prev_weapon_skill) { prev_anim = AnimSequence; + r = 1.0; e = 1.7; if(AnimSequence == 'PlaceBegin' || AnimSequence == 'PlaceEnd') + { if(AnimFrame<0.2)// skip the beginning of the animation AnimFrame=0.2; - else if(AnimSequence == 'Shoot' - || AnimSequence == 'Attack' || AnimSequence == 'Attack2' || AnimSequence == 'Attack3' - || AnimSequence == 'Idle1' || AnimSequence == 'Idle2' || AnimSequence == 'Idle3' - ) { + } + else if(AnimSequence == 'Shoot' || AnimSequence == 'Attack' || AnimSequence == 'Attack2' || AnimSequence == 'Attack3') + { + r = (default.ShotTime / ShotTime); + r = FClamp(r, 0.4, 1.7); + e = 1.0;// these animations don't scale as much with skill + } + else if(AnimSequence == 'Idle1' || AnimSequence == 'Idle2' || AnimSequence == 'Idle3') + { e = 1.0;// these animations don't scale as much with skill } if(GoverningSkill == Class'SkillDemolition') { - anim_speed = 1.1;// why are grenades so slow? + r *= 1.1;// why are grenades so slow? e = 1.9; } prev_weapon_skill = GetWeaponSkill(); - r = (anim_speed + -0.2 * prev_weapon_skill) ** e; + r *= (anim_speed + -0.2 * prev_weapon_skill) ** e; + r = FClamp(r, 0.001, 1000); prev_anim_rate = AnimRate * r; } @@ -95,7 +116,10 @@ simulated function bool NearWallCheck() placeNormal = HitNormal; placeMover = Mover(HitActor); - if (!bNearWall && IsAnimating() && (GetStateName() == 'NormalFire')) + if (!bNearWall && + IsAnimating() && + (AnimSequence=='Attack' || AnimSequence=='Attack2' || AnimSequence=='Attack3' ) && + (GetStateName() == 'NormalFire')) { //The throw animation is about to be canceled by a place animation. //Ammo gets consumed at the start of the animation, but the projectile is only spawned @@ -637,7 +661,7 @@ simulated function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNo //Hack borrowed from WCCC if (Other == Level){ dxPlayer = DeusExPlayer(Owner); - if (dxPlayer != None && dxPlayer.FrobTarget.IsA('Mover')){ + if (dxPlayer != None && Mover(dxPlayer.FrobTarget) != None){ Other = dxPlayer.FrobTarget; } } @@ -653,6 +677,109 @@ function TravelPostAccept() } } +simulated function bool IsWeaponTexture(int i) +{ + local Texture thisTex; + + thisTex = GetMeshTexture(i); + if (thisTex==None){ + return false; + } else if (InStr(string(thisTex),"MaskTex")!=-1){ + return false; + } else if (InStr(string(thisTex),"WeaponHandsTex")!=-1){ + return false; + } else if (InStr(string(thisTex),"SFX")!=-1){ + return false; + } else if (InStr(string(thisTex),"MapTex")!=-1){ + return false; + } else { + return true; + } +} + +simulated event RenderOverlays( canvas Canvas ) +{ + local Texture origTex[8]; + local int texLoc; + Super.RenderOverlays(Canvas); + + //Draw an indication that the weapon still has a shot in progress + //if (bFiring && !IsAnimating() && PlayerPawn(Owner)!=None){ + //bPointing seems to be updated basically the same as bFiring, except it works for melee as well + if (GetStateName()=='NormalFire' && !IsAnimating() && !bAutomatic && PlayerPawn(Owner)!=None){ + ScaleGlow=0.1; + Style = STY_Translucent; + + for (texLoc=0;texLoc<8;texLoc++){ + origTex[texLoc] = MultiSkins[texLoc]; + if (WeaponTexLoc[texLoc]==1){ + MultiSkins[texLoc]=Texture'Effects.Laser.LaserBeam1'; + } + } + + Canvas.DrawActor(self, false); + + for (texLoc=0;texLoc<8;texLoc++){ + MultiSkins[texLoc]=origTex[texLoc]; + } + + Style = STY_Normal; + ScaleGlow=1.0; + } +} + +function bool HandlePickupQuery(Inventory Item) +{ + local DeusExWeapon W; + local DeusExPlayer player; + local class defAmmoClass; + local Ammo defAmmo,newAmmo; + local int ammoToAdd,ammoRemaining; + + W = DeusExWeapon(Item); + player = DeusExPlayer(Owner); + + if (w!=None && player!=None && Item.Class == Class) + { + if (!( (w.bWeaponStay && (Level.NetMode == NM_Standalone)) && (!w.bHeldItem || w.bTossedOut))) + { + if ( AmmoType != None ) + { + if ( AmmoNames[0] == None ){ + defAmmoClass = AmmoName; + }else{ + defAmmoClass = AmmoNames[0]; + } + defAmmo = Ammo(player.FindInventoryType(defAmmoClass)); + if(defAmmo!=None){ + ammoToAdd = w.PickUpAmmoCount; + ammoRemaining=0; + if ((ammoToAdd + defAmmo.AmmoAmount) > defAmmo.MaxAmmo){ + ammoRemaining = (ammoToAdd + defAmmo.AmmoAmount) - defAmmo.MaxAmmo; + ammoToAdd = ammoToAdd - ammoRemaining; + } + + w.PickUpAmmoCount = ammoToAdd; + if (ammoRemaining>0){ + if(defAmmoClass.Default.Mesh!=LodMesh'DeusExItems.TestBox'){ + //Weapons with normal ammo that exists + newAmmo = Spawn(defAmmoClass,,,w.Location,w.Rotation); + newAmmo.ammoAmount = ammoRemaining; + newAmmo.Velocity = Velocity + VRand() * 280; + } else { + w.PickUpAmmoCount = ammoRemaining; + defAmmo.AddAmmo(ammoToAdd); + return True; + } + } + } + } + } + } + + return Super.HandlePickupQuery(Item); +} + // vanilla MinSpreadAcc is 0.25, but only used in multiplayer, so really it normally acts like 0 // we're mainly turning on MinSpreadAcc for singleplayer because of the shotguns, so we want a minimal change here of 0.05 defaultproperties diff --git a/DXRando.cs b/DXRando.cs index f77f78135..5140abe25 100644 --- a/DXRando.cs +++ b/DXRando.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using ConnectorType = CrowdControl.Common.ConnectorType; -namespace CrowdControl.Games.Packs; +namespace CrowdControl.Games.Packs.DeusEx; [UsedImplicitly] public class DeusEx : SimpleTCPPack @@ -29,7 +29,6 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect("Full Heal", "full_heal"){Price = 30,Description = "Fully heal the player"}, new Effect("Drunk Mode", "drunk_mode"){Price = 10,Description = "Let the player overindulge with some nice alcohol"}, new Effect("Drop Selected Item", "drop_selected_item"){Price = 2,Description = "Toss the currently held weapon out in front of the player"}, - new Effect("Enable Matrix Mode", "matrix"){Price = 5,Description = "Make the player see the code behind the game...",Duration=60}, new Effect("Give Player EMP Field", "emp_field"){Price = 25,Description = "Make all electronics around the player go haywire for 15 seconds!",Duration=15}, new Effect("Give Bioelectric Energy (x10)", "give_energy") { Quantity = 100,Price = 1,Description = "Top up the players battery by a bit" }, new Effect("Give Skill Points (x100)", "give_skillpoints") { Quantity = 1000,Price = 5,Description = "Give the player some skill points" }, //Updated text for second Crowd Control batch @@ -38,7 +37,6 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect("Gotta Go Fast", "gotta_go_fast"){Price = 5,Description = "Make the player go extremely fast!",Duration=60}, new Effect("Slow Like Snail", "gotta_go_slow"){Price = 5,Description = "Make the player go very slow...",Duration=60}, new Effect("Ice Physics!","ice_physics"){Price = 10,Description = "Make the ground freeze up and become as slippery as a skating rink!",Duration=60}, - new Effect("Go Third-Person","third_person"){Price = 5,Description = "Change the game into a third person shooter for a minute!",Duration=60}, new Effect("Take Double Damage","dmg_double"){Price = 10,Description = "Make the player weaker so they take double damage!",Duration=60}, new Effect("Take Half Damage","dmg_half"){Price = 5,Description = "Make the player tougher so they take half damage!",Duration=60}, new Effect("Give Credits (x100)", "add_credits") { Quantity = 1000,Price = 2,Description = "Make it rain on the player and give them some spare cash!" }, //Updated for text second Crowd Control batch @@ -48,6 +46,8 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect ("Ask a Question","ask_a_question"){Price = 5,Description = "Make a dialog box appear on screen with a question while the game continues in behind!"}, //New for second Crowd Control batch new Effect ("Nudge","nudge"){Price = 1,Description = "Just ever so slightly... nudge... the player in a random direction"}, //New for second Crowd Control batch new Effect ("Swap Player with another human","swap_player_position"){Price = 40,Description = "Finds another human somewhere in the current level and swaps their position with the player!"}, //New for second Crowd Control batch + new Effect ("Swap all enemies positions","swap_enemies"){Price = 20,Description = "Shuffles all the enemies in the level into each others locations!"}, //New for fifth Crowd Control batch + new Effect ("Swap all item positions","swap_items"){Price = 5,Description = "Shuffles all the inventory items in the level into each others locations!"}, //New for fifth Crowd Control batch new Effect ("Float Away","floaty_physics"){Price = 100,Description = "Suddenly gravity feels very light and everything starts floating up into the sky...",Duration=30}, //New for second Crowd Control batch new Effect ("Floor is Lava","floor_is_lava"){Price = 75,Description = "Floor is lava! If the player doesn't keep jumping or get up on top of something, they're gonna burn!",Duration=60}, //New for second Crowd Control batch new Effect ("Invert Mouse Controls","invert_mouse"){Price = 20,Description = "Up is down and down is up!",Duration=60}, //New for second Crowd Control batch @@ -55,16 +55,17 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect ("Earthquake","earthquake"){Price = 25,Description = "Set off a massive earthquake in the game!",Duration=30}, //New for fourth Crowd Control batch new Effect ("Full Bioelectric Energy","give_full_energy"){Price = 5,Description = "Completely fill the players bioelectric energy"}, //New for fourth Crowd Control batch new Effect ("Trigger all alarms","trigger_alarms"){Price = 5,Description = "Set off every alarm panel and security camera in the current level to make sure all the enemies are on high alert!"}, //New for fourth Crowd Control batch - new Effect ("Flip camera upside down","flipped"){Price = 20,Description = "Australia mode",Duration=60}, //New for fourth Crowd Control batch - new Effect ("Flip camera sideways","limp_neck"){Price = 20,Description = "Just turn the screen to the side!",Duration=60}, //New for fourth Crowd Control batch - new Effect ("Do a barrel roll!","barrel_roll"){Price = 25,Description = "The camera does an ever so slow barrel roll over the course of a minute...",Duration=60}, //New for fourth Crowd Control batch - new Effect ("Set off a Flashbang", "flashbang"){Price = 5,Description = "Set off a flashbang in the players face"}, //New for fourth Crowd Control batch new Effect ("Eat Beans", "eat_beans"){Price = 5,Description = "Force feed the player a bunch of beans and witness the consequences!",Duration=60}, //New for fourth Crowd Control batch new Effect ("Fire the current weapon", "fire_weapon"){Price = 5,Description = "Fire whatever weapon the player is holding!"}, //New for fourth Crowd Control batch new Effect ("Switch to next item", "next_item"){Price = 2,Description = "Switch to the next item in the players item belt"}, //New for fourth Crowd Control batch new Effect ("Switch to next HUD color scheme", "next_hud_color"){Price = 1,Description = "Maybe the current color scheme doesn't look so good?"}, //New for fourth Crowd Control batch new Effect ("Quick Save", "quick_save"){Price = 10,Description = "Stir up some real trouble..."}, //New for fourth Crowd Control batch new Effect ("Quick Load", "quick_load"){Price = 20,Description = "Hope that last quick save wasn't too far back, or in too much danger!"}, //New for fourth Crowd Control batch + new Effect ("Drop a piano on the player", "drop_piano"){Price = 10,Description = "Spawn a piano above the player to drop it on them, just like in the cartoons!"}, //New for fifth Crowd Control batch, v2.6 + new Effect ("Toggle the Flashlight", "toggle_flashlight"){Price = 1,Description = "Toggle the flashlight!"}, //New for fifth Crowd Control batch, v2.6 + new Effect ("Heal all Enemies", "heal_all_enemies"){Price = 10,Description = "Fully heal all enemies in the current level!"}, //New for fifth Crowd Control batch, v2.6 + new Effect ("Make Player Radioactive", "radioactive"){Price = 10,Description = "The player becomes radioactive and starts hurting nearby people!",Duration=60}, //New for fifth Crowd Control batch, v2.6 + new Effect ("Corpse Explosion", "corpse_explosion"){Price = 10,Description = "Fill up to 5 nearby corpses with energy, causing them to explode violently!"}, //New for fifth Crowd Control batch, v2.6 //Spawn Enemies/Allies //new Effect("Spawn Enemies/Allies","spawnpawns",ItemKind.Folder), //New for fourth Crowd Control batch @@ -78,6 +79,8 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect ("Spawn friendly Military Bot", "spawnfriendly_militarybot") { Category = "Spawn Enemies/Allies",Price = 30,Description = "Spawn a military bot to give the player a hand" }, //New for fourth Crowd Control batch new Effect ("Spawn hostile Doberman", "spawnenemy_doberman") { Category = "Spawn Enemies/Allies",Price = 5,Description = "Spawn a doberman to tear you to shreds" }, //New for fourth Crowd Control batch new Effect ("Spawn hostile Greasel", "spawnenemy_greasel") { Category = "Spawn Enemies/Allies",Price = 10,Description = "Spawn a hostile greasel to poison you to death" }, //New for fourth Crowd Control batch + new Effect ("Spawn a nasty rat", "nasty_rat") { Category = "Spawn Enemies/Allies",Price = 15,Description = "Spawn a huge rat that throws LAMs" }, //New for fifth Crowd Control batch + new Effect ("Raise the Dead", "raise_dead") { Category = "Spawn Enemies/Allies",Price = 10,Description = "Resurrect up to 5 nearby enemies. They're out for blood now!" }, //New for fifth Crowd Control batch //Items //new Effect("Give Items","giveitems",ItemKind.Folder), //New folder for third batch @@ -172,6 +175,8 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect("Give Gas Grenade", "give_weapongasgrenade") { Category = "Give Weapon",Price = 2,Description = "Give the player a gas grenade" }, //New for second Crowd Control batch new Effect("Give Scrambler Grenade", "give_weaponnanovirusgrenade") { Category = "Give Weapon",Price = 5,Description = "Give the player a scrambler grenade" }, //New for second Crowd Control batch new Effect("Give PS40","give_weaponhideagun") { Category = "Give Weapon",Price = 10,Description = "Give the player a PS40" }, + new Effect("Give all enemies a LAW", "giveenemyweapon_weaponlaw") { Category = "Give Weapon",Price = 40,Description = "Give all enemies a LAW" }, //New for fifth Crowd Control batch, v2.6 + new Effect("Give all enemies a PS40", "giveenemyweapon_weaponhideagun") { Category = "Give Weapon",Price = 30,Description = "Give all enemies a PS40" }, //New for fifth Crowd Control batch, v2.6 //Ammo //new Effect("Give Ammo","giveammo",ItemKind.Folder), @@ -190,6 +195,16 @@ public DeusEx(UserRecord player, Func responseHandler, new Effect("Give Rockets", "give_ammorocket") { Quantity = 100, Category = "Give Ammo",Price = 10,Description = "Give the player some rockets" }, //New for second Crowd Control batch new Effect("Give WP Rockets", "give_ammorocketwp") { Quantity = 100, Category = "Give Ammo",Price = 15,Description = "Give the player some WP rockets" }, //New for second Crowd Control batch new Effect("Give Sabot Shells", "give_ammosabot") { Quantity = 100, Category = "Give Ammo",Price = 20,Description = "Give the player some Sabot shells" }, //New for second Crowd Control batch - new Effect("Give Shotgun Shells", "give_ammoshell") { Quantity = 100, Category = "Give Ammo",Price = 5,Description = "Give the player some shotgun shells" } //New for second Crowd Control batch + new Effect("Give Shotgun Shells", "give_ammoshell") { Quantity = 100, Category = "Give Ammo",Price = 5,Description = "Give the player some shotgun shells" }, //New for second Crowd Control batch + + //Camera Effects + new Effect ("Flip camera upside down","flipped"){Category = "Camera Effects",Price = 20,Description = "Australia mode",Duration=60}, //New for fourth Crowd Control batch + new Effect ("Flip camera sideways","limp_neck"){Category = "Camera Effects",Price = 20,Description = "Just turn the screen to the side!",Duration=60}, //New for fourth Crowd Control batch + new Effect ("Do a barrel roll!","barrel_roll"){Category = "Camera Effects",Price = 25,Description = "The camera does an ever so slow barrel roll over the course of a minute...",Duration=60}, //New for fourth Crowd Control batch + new Effect("Go Third-Person","third_person"){Category = "Camera Effects",Price = 5,Description = "Change the game into a third person shooter for a minute!",Duration=60}, + new Effect("Enable Matrix Mode", "matrix"){Category = "Camera Effects",Price = 5,Description = "Make the player see the code behind the game...",Duration=60}, + new Effect ("Set off a Flashbang", "flashbang"){Category = "Camera Effects",Price = 5,Description = "Set off a flashbang in the players face"}, //New for fourth Crowd Control batch + new Effect ("Resident Evil Mode", "resident_evil"){Category = "Camera Effects",Price = 20,Description = "Switch the game to fixed camera angles! Very spooky!",Duration=60}, //New for fifth Crowd Control batch + new Effect ("Doom Mode", "doom_mode"){Category = "Camera Effects",Price = 5,Description = "Drag the player to hell, a place where there is no looking up or down!",Duration=60} //New for fifth Crowd Control batch }; } diff --git a/DXRando/DeusEx/Classes/Barrel1.uc b/DXRando/DeusEx/Classes/Barrel1.uc index b4e87c896..c61b75266 100644 --- a/DXRando/DeusEx/Classes/Barrel1.uc +++ b/DXRando/DeusEx/Classes/Barrel1.uc @@ -2,6 +2,9 @@ class DXRBarrel1 injects #var(prefix)Barrel1; function BeginPlay() { + bExplosive=Default.bExplosive; + explosionDamage=Default.explosionDamage; + explosionRadius=Default.explosionRadius; Super.BeginPlay(); bInvincible = false; } @@ -52,4 +55,14 @@ function Trigger(Actor Other, Pawn Instigator) auto state Active { + function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) + { + //Don't get zapped by electricity + //Prevents the big smoke cloud in airfield that lags everything + if (damageType=='Shocked'){ + return; + } + + Super.TakeDamage(Damage,instigatedBy,hitLocation,momentum,damageType); + } } diff --git a/DXRando/DeusEx/Classes/BingoTrigger.uc b/DXRando/DeusEx/Classes/BingoTrigger.uc index 147f02ab6..42355a08a 100644 --- a/DXRando/DeusEx/Classes/BingoTrigger.uc +++ b/DXRando/DeusEx/Classes/BingoTrigger.uc @@ -26,7 +26,7 @@ function Touch(Actor Other) { Super.Touch(Other); - if (TriggerType!=TT_Shoot && IsRelevant(Other)) + if (TriggerType!=TT_Shoot && !bPeepable && IsRelevant(Other)) { DoBingoThing(); } diff --git a/DXRando/DeusEx/Classes/CCResidentEvilCam.uc b/DXRando/DeusEx/Classes/CCResidentEvilCam.uc new file mode 100644 index 000000000..ed0dfa8e5 --- /dev/null +++ b/DXRando/DeusEx/Classes/CCResidentEvilCam.uc @@ -0,0 +1,200 @@ +class CCResidentEvilCam extends SecurityCamera; + +var DeusExPlayer p; +var bool Reposition; +var float cameraMoveTimer; + +function PostBeginPlay() +{ + Super.PostBeginPlay(); + + Reposition = False; +} + +function bool FindNewCameraPosition() +{ + local DXRMachines dxrm; + local Vector loc,loc2; + local Rotator rot; + local Actor hit; + local Vector HitLocation, HitNormal; + local bool success; + + foreach AllActors(class'DXRMachines',dxrm){break;} + + if (dxrm==None){ + return false; + } + + success = False; + loc = p.Location; + + success = dxrm.GetLazyCameraLocation(loc,cameraRange*0.75); + + if (success){ + if (!p.FastTrace(loc)){ + success=False; + } + } + + if (!success){ + //Try to fall back to a position at a point somewhere behind the player + loc2 = p.Location + Vector(p.Rotation) * (-16 * 10); + hit = Trace(HitLocation, HitNormal, loc2, p.Location, True); + if (hit!=None){ + loc2 = HitLocation; + } + loc = loc2; + } + rot = Rotator(p.Location - loc); + SetLocation(loc); + SetRotation(rot); + DesiredRotation = rot; + Reposition=False; + cameraMoveTimer=0; + + return success; +} + +function BindPlayer(DeusExPlayer play) +{ + p = play; + p.ViewTarget = Self; + FindNewCameraPosition(); +} + +function Tick(float deltaTime) +{ + local float ang; + local Rotator rot; + local DeusExPlayer curplayer; + + Super(#var(prefix)HackableDevices).Tick(deltaTime); + + if (p==None){ + return; + } + + if (p.ViewTarget!=Self){ + Destroy(); //Self destruct + } + + cameraMoveTimer+=deltaTime; + + curTarget = None; + + //Prevent it from going into stasis + LastRenderTime = p.LastRendered(); + DistanceFromPlayer=0; + + playerCheckTimer += deltaTime; + + if (playerCheckTimer > 0.1) + { + playerCheckTimer = 0; + CheckPlayerVisibility(p); + } + + if (Reposition && cameraMoveTimer>1.0){ //Don't allow moves more than once a second + //If not, find new location + FindNewCameraPosition(); + } + + // DEUS_EX AMSD For multiplayer + ReplicatedRotation = DesiredRotation; + + +} + +function CheckPlayerVisibility(DeusExPlayer player) +{ + local float yaw, pitch, dist; + local Actor hit; + local Vector HitLocation, HitNormal; + local Rotator rot; + + if (player == None) + return; + + Reposition=True; + dist = Abs(VSize(player.Location - Location)); + + foreach TraceActors(class'Actor',hit,HitLocation,HitNormal,player.Location,Location) + { + //Immediately reposition if you're on the far side of a wall or door + if (LevelInfo(hit)!=None || Mover(hit)!=None){ + break; + } + + //Aim the camera at the player + if (hit == player) + { + // figure out if we can see the player + rot = Rotator(player.Location - Location); + rot.Roll = 0; + yaw = (Abs(Rotation.Yaw - rot.Yaw)) % 65536; + pitch = (Abs(Rotation.Pitch - rot.Pitch)) % 65536; + + // center the angles around zero + if (yaw > 32767) + yaw -= 65536; + if (pitch > 32767) + pitch -= 65536; + + if (!((Abs(yaw) < cameraFOV) && (Abs(pitch) < cameraFOV))) + { + // rotate to face the player + DesiredRotation = rot; + } + Reposition = False; + break; + } + } + + // if the player is out of range + if (dist > cameraRange) + { + Reposition = True; + } +} + +function TriggerEvent(bool bTrigger) +{ +} + +function Trigger(Actor Other, Pawn Instigator) +{ +} + +function UnTrigger(Actor Other, Pawn Instigator) +{ +} + +defaultproperties +{ + bHidden=true + bCollideActors=false + bCollideWorld=false + bBlockActors=false + bBlockPlayers=false + bProjTarget=false + CollisionHeight=1 + CollisionRadius=1 + bActive=True + bNoAlarm=True + bSwing=False + bTrackPlayer=True + bGameRelevant=True + bAlwaysRelevant=True + bAlwaysTick=True + bInvincible=True + bStasis=False + cameraRange=750 + RotationRate=(Pitch=40000,Yaw=40000) + AmbientSound=None + LightType=LT_None + LightBrightness=0 + LightHue=0 + LightSaturation=0 + LightRadius=0 +} diff --git a/DXRando/DeusEx/Classes/DXRBarrelFire.uc b/DXRando/DeusEx/Classes/DXRBarrelFire.uc index 5d763aad1..578095a04 100644 --- a/DXRando/DeusEx/Classes/DXRBarrelFire.uc +++ b/DXRando/DeusEx/Classes/DXRBarrelFire.uc @@ -51,76 +51,18 @@ function Tick(float delta) function Destroyed() { - local int i; - local Vector loc; - local TrashPaper trash; - local Fire fire; - local bool fireHasSpawned; - - // trace down to see if we are sitting on the ground - loc = vect(0,0,0); - loc.Z -= CollisionHeight + 8.0; - loc += Location; - - // only generate trash if we are on the ground - if (!FastTrace(loc)) - { - fireHasSpawned = False; - - // maybe spawn some paper - for (i=0; i<3; i++) - { - if (FRand() < 0.75) - { - loc = Location; - loc.X += (CollisionRadius / 2) - FRand() * CollisionRadius; - loc.Y += (CollisionRadius / 2) - FRand() * CollisionRadius; - loc.Z += (CollisionHeight / 2) - FRand() * CollisionHeight; - trash = Spawn(class'TrashPaper',,, loc); - if (trash != None) - { - trash.SetPhysics(PHYS_Rolling); - trash.rot = RotRand(True); - trash.rot.Yaw = 0; - trash.dir = VRand() * 20 + vect(20,20,0); - trash.dir.Z = 0; - - // maybe set it on fire - if (FRand() < 0.5) - { - // trash has no collision and its collisionHeight seems to have no correspondence to its actual size - // this code is based on collisionHeight only for potential scaling purposes - loc.Z += 0.8 * trash.Collisionheight; - - fire = Spawn(class'SmokelessFire', trash,, loc); - if (fire != None) - { - fire.DrawScale = 0.5*FRand() + 1.0; - fire.DrawScale *= 0.5; - - // necessary? - if (fireHasSpawned) - { - fire.AmbientSound = None; - } - else - { - fireHasSpawned = True; - } - } - } - } - } - } - } - + class'TrashContainerCommon'.static.GenerateTrashPaper(self, 0.5, true); Super.Destroyed(); } -// same as Barrel1 +// same Mass and Buoyancy as Barrel1 +// vanilla uses FireSmall2, which is almost inaudible defaultproperties { Mass=80 Buoyancy=90 bInvincible=False + SoundRadius=32 + SoundVolume=200 + AmbientSound=Sound'Ambient.Ambient.FireSmall1' } diff --git a/DXRando/DeusEx/Classes/DXRButtonHoverHint.uc b/DXRando/DeusEx/Classes/DXRButtonHoverHint.uc new file mode 100644 index 000000000..1172fe1af --- /dev/null +++ b/DXRando/DeusEx/Classes/DXRButtonHoverHint.uc @@ -0,0 +1,29 @@ +class DXRButtonHoverHint extends DXRTeleporterHoverHint; + +var bool nameSet; + +//Self destruct as soon as the name has been set +function bool ShouldSelfDestruct() +{ + return nameSet; +} + +function String GetHintText() +{ + local String destStr; + + destStr = Super.GetHintText(); + + if (baseActor!=None){ + baseActor.FamiliarName = destStr; + baseActor.UnfamiliarName = destStr; + nameSet=True; + } + + return ""; //Don't actually show any text +} + +defaultproperties +{ + nameSet=False +} diff --git a/DXRando/DeusEx/Classes/DXRDataVaultImage.uc b/DXRando/DeusEx/Classes/DXRDataVaultImage.uc index 9cbc3bf94..3143a6eea 100644 --- a/DXRando/DeusEx/Classes/DXRDataVaultImage.uc +++ b/DXRando/DeusEx/Classes/DXRDataVaultImage.uc @@ -7,8 +7,31 @@ class DXRDataVaultImage injects DataVaultImage; function AddNote(DataVaultImageNote newNote) { Super.AddNote(newNote); - + if (!class'DXRVersion'.static.VersionIsStable() && owner!=None){ DeusExPlayer(owner).ClientMessage("New note '"$newNote.noteText$"' added at X"$newNote.posX$" Y"$newNote.posY); } } + + +static function UpdateDataVaultImageTextures(DataVaultImage newImage) +{ + local DXRando dxr; + + foreach newImage.AllActors(class'DXRando',dxr) {break;} + + //Check if we're ready or not + if (dxr==None) return; + if (dxr.flags==None) return; + if (dxr.flags.flags_loaded==False) return; + if (dxr.flags.settings.goals == 0) return; + + switch(newImage.class.name){ + case 'Image09_NYC_Ship_Bottom': + newImage.imageTextures[0]=Texture'#var(package).DXRandoImages.Image09_NYC_Ship_Bttm_1'; + newImage.imageTextures[1]=Texture'#var(package).DXRandoImages.Image09_NYC_Ship_Bttm_2'; + newImage.imageTextures[2]=Texture'#var(package).DXRandoImages.Image09_NYC_Ship_Bttm_3'; + newImage.imageTextures[3]=Texture'#var(package).DXRandoImages.Image09_NYC_Ship_Bttm_4'; + break; + } +} diff --git a/DXRando/DeusEx/Classes/DXRHoverHint.uc b/DXRando/DeusEx/Classes/DXRHoverHint.uc new file mode 100644 index 000000000..764a60d95 --- /dev/null +++ b/DXRando/DeusEx/Classes/DXRHoverHint.uc @@ -0,0 +1,150 @@ +class DXRHoverHint extends Info; + +var() string HintText; +var() int VisibleDistance; +var Actor target; +var bool attached; + +var Actor baseActor; +var bool bInWorld; + +static function DXRHoverHint Create(Actor a, String hint, vector loc, float rad, float height, optional Actor target, optional Name targetName) +{ + local DXRHoverHint hoverHint; + local Actor act; + + act = a.Spawn(default.class,,,loc); + hoverHint = DXRHoverHint(act); + hoverHint.SetCollisionSize(rad,height); + hoverHint.HintText = hint; + + if (target != None){ + hoverHint.target = target; + hoverHint.attached = true; + } + else if (targetName!=''){ + hoverHint.AttachTarget(targetName); + } + + return hoverHint; +} + +function AttachTarget(name targetName) +{ + local Actor targetActor; + + foreach AllActors(class'Actor',targetActor){ + if (targetActor.Name==targetName){ + target = targetActor; + attached = True; + break; + } + } + + if (attached==False){ + log("ERROR: Unable to find target '"$targetName$"' to attach to DXRHoverHint"); + } +} + +function SetBaseActor(Actor base) +{ + baseActor = base; + SetLocation(baseActor.Location); + SetBase(baseActor); + + //The tick logic is primarily for handling EnterWorld/LeaveWorld, + //so only activate for things that can do that. + if (ScriptedPawn(baseActor)!=None || Vehicles(baseActor)!=None){ + Enable('Tick'); + } +} + +function bool ShouldDisplay(float dist) +{ + if (dist > VisibleDistance){ + return False; + } + + if (baseActor!=None){ + if (ScriptedPawn(baseActor)!=None){ + if ((ScriptedPawn(baseActor).bInWorld==False)){ + return False; + } + } + if (Vehicles(baseActor)!=None){ + if ((Vehicles(baseActor).bInWorld==False)){ + return False; + } + } + } + + return True; +} + +function bool ShouldSelfDestruct() +{ + //Check if the attached target has been destroyed + if (attached){ + if (#var(DeusExPrefix)Mover(target)!=None){ + return #var(DeusExPrefix)Mover(target).bDestroyed; + } else { + return (target==None); + } + } + + return False; +} + +function String GetHintText() +{ + return HintText; +} + +event Tick(float DeltaTime) +{ + local bool nowInWorld; + if (baseActor==None){ + return; + } + + if (ScriptedPawn(baseActor)!=None){ + nowInWorld=ScriptedPawn(baseActor).bInWorld; + } else if (Vehicles(baseActor)!=None){ + nowInWorld=Vehicles(baseActor).bInWorld; + } else { + return; + } + + if (nowInWorld!=bInWorld){ + SetLocation(baseActor.Location); + bInWorld = nowInWorld; + SetBase(baseActor); + } +} + +//You would think this would work... It calls SetLocation and SetBase, but it stays where it is. +//Presumably the base changes to None before the baseActor actually moves? +/* +event BaseChange() +{ + log ("Base before: "$base); + Super.BaseChange(); + log ("Base after: "$base); + if (baseActor!=None && base==None){ + log("Moving to base actor location"); + SetLocation(baseActor.Location); + SetBase(baseActor); + } +} +*/ + +defaultproperties +{ + bCollideActors=True + bCollideWorld=False + HintText="HOVER HINT DEFAULT TEXT - REPORT AS A BUG" + attached=False + target=None + bInWorld=False + VisibleDistance=2000 +} diff --git a/DXRando/DeusEx/Classes/DXRTeleporterHoverHint.uc b/DXRando/DeusEx/Classes/DXRTeleporterHoverHint.uc new file mode 100644 index 000000000..d39525014 --- /dev/null +++ b/DXRando/DeusEx/Classes/DXRTeleporterHoverHint.uc @@ -0,0 +1,73 @@ +class DXRTeleporterHoverHint extends DXRHoverHint; + +function AttachTarget(name targetName) +{ + Super.AttachTarget(targetName); + + if (target!=None && Teleporter(target)==None && MapExit(target)==None){ + log("ERROR: Attached to target that was not a teleporter or map exit ("$target$","$targetName$")"); + target=None; + } +} + +function string formatMapName(string mapName) +{ + local string mapNameOnly,teleName; + local int hashPos; + + hashPos = InStr(mapName,"#"); + + if (hashPos+1 == Len(mapName)) { + // # is the last character, leave it out + return class'DXRMapInfo'.static.GetTeleporterName(Left(mapName, Len(mapName)-1),""); + } + if (hashPos==-1){ + //No # in map name, so it's probably just the map name? + return class'DXRMapInfo'.static.GetTeleporterName(mapName, ""); + } + + mapNameOnly = Left(mapName, hashPos); + + teleName = Mid(mapName,hashPos+1); + + return class'DXRMapInfo'.static.GetTeleporterName(mapNameOnly,teleName); +} + +function String GetHintText() +{ + local DynamicTeleporter dynTele; + local string teleDest; + + if (target==None){ + return HintText; + } + + if (#var(prefix)Teleporter(target)!=None){ + teleDest = #var(prefix)Teleporter(target).URL; + dynTele = DynamicTeleporter(target); + if (dynTele!=None && dynTele.destName != ''){ + if (InStr(teleDest,"#")==-1){ + teleDest = teleDest $ "#"; + } + teleDest = teleDest $ dynTele.destName; + + } + } else if (#var(prefix)MapExit(target)!=None){ + teleDest = #var(prefix)MapExit(target).DestMap; +#ifdef injections + if (#var(prefix)MapExit(target).destName!=''){ + teleDest = teleDest$#var(prefix)MapExit(target).destName; + } +#endif + } + return "To: "$formatMapName(teleDest); +} + +function bool ShouldDisplay(float dist) +{ + if (Super.ShouldDisplay(dist)==False){ + return False; + } + + return (class'MenuChoice_ShowTeleporters'.default.show_teleporters > 1); +} diff --git a/DXRando/DeusEx/Classes/DXRToiletSeat.uc b/DXRando/DeusEx/Classes/DXRToiletSeat.uc new file mode 100644 index 000000000..2bff86292 --- /dev/null +++ b/DXRando/DeusEx/Classes/DXRToiletSeat.uc @@ -0,0 +1,49 @@ +class DXRToiletSeat extends Seat; + +var #var(prefix)Toilet toilet; +var bool occupied; + +static function DXRToiletSeat Create(#var(injectsprefix)Toilet t) +{ + local DXRToiletSeat seat; + + seat = t.Spawn(class'DXRToiletSeat',,,t.Location,t.Rotation); + seat.toilet=t; + + return seat; +} + + +function BeginPlay() +{ + Super.BeginPlay(); + SetTimer(1,true); +} + +simulated event Timer() +{ + local bool occupiedNow; + + occupiedNow = (sittingActor[0]!=None); + if (occupiedNow!=occupied && !occupiedNow && toilet!=None){ + toilet.Frob(None,None); + } + occupied = occupiedNow; +} + +defaultproperties +{ + sitPoint(0)=(X=0.000000,Y=-14.000000,Z=4.00000) + ItemName="Toilet Seat" + bHidden=True + bInvincible=True + bPushable=False + Physics=PHYS_None + CollisionRadius=0 + CollisionHeight=0 + bCollideActors=false + bCollideWorld=false + bBlockActors=false + bBlockPlayers=false + occupied=false +} diff --git a/DXRando/DeusEx/Classes/DXRandoCrowdControlEffects.uc b/DXRando/DeusEx/Classes/DXRandoCrowdControlEffects.uc index ece644c57..e682b51cf 100644 --- a/DXRando/DeusEx/Classes/DXRandoCrowdControlEffects.uc +++ b/DXRando/DeusEx/Classes/DXRandoCrowdControlEffects.uc @@ -11,6 +11,14 @@ const Failed = 1; const NotAvail = 2; const TempFail = 3; +const CCType_Test = 0x00; +const CCType_Start = 0x01; +const CCType_Stop = 0x02; +const CCType_PlayerInfo = 0xE0; //Not used for us +const CCType_Login = 0xF0; //Not used for us +const CCType_KeepAlive = 0xFF; //Not used for us + + var int lavaTick; const MoveSpeedMultiplier = 10; @@ -41,6 +49,9 @@ const InvertMovementTimeDefault = 60; const EarthquakeTimeDefault = 30; const CameraRollTimeDefault = 60; const EatBeansTimeDefault = 60; +const ResidentEvilTimeDefault = 60; +const RadiationTimeDefault = 60; +const DoomModeTimeDefault = 60; struct ZoneFriction { @@ -70,6 +81,8 @@ var DXRandoCrowdControlPawn CrowdControlPawns[3]; var transient AugEffectState AugEffectStates[32]; //Vanilla has a 25 array, but in case mods bump it up? var transient bool AugEffectStatesInit; +var CCResidentEvilCam reCam; + var transient bool HaveFlamethrower; var transient bool FlamethrowerInit; @@ -115,80 +128,67 @@ function PeriodicUpdates() { //Matrix Mode Timer if (decrementTimer('cc_MatrixModeTimer')) { - StopMatrixMode(); + StopCrowdControlEvent("matrix",true); } //EMP Field timer if (decrementTimer('cc_EmpTimer')) { - player().bWarrenEMPField = false; - PlayerMessage("EMP Field has disappeared..."); + StopCrowdControlEvent("emp_field",true); } if (isTimerActive('cc_JumpTimer')) { player().JumpZ = 0; } if (decrementTimer('cc_JumpTimer')) { - player().JumpZ = player().Default.JumpZ; - PlayerMessage("Your knees feel fine again."); + StopCrowdControlEvent("disable_jump",true); } if (isTimerActive('cc_SpeedTimer')) { player().Default.GroundSpeed = DefaultGroundSpeed * retrieveFloatValue('cc_moveSpeedModifier'); } if (decrementTimer('cc_SpeedTimer')) { - player().Default.GroundSpeed = DefaultGroundSpeed; - PlayerMessage("Back to normal speed!"); + StopCrowdControlEvent("gotta_go_fast",true); //also gotta_go_slow } if (decrementTimer('cc_lamthrowerTimer')) { - UndoLamThrowers(); - PlayerMessage("Your flamethrower is boring again"); - + StopCrowdControlEvent("lamthrower",true); } if (decrementTimer('cc_iceTimer')) { - SetIcePhysics(False); - PlayerMessage("The ground thaws"); + StopCrowdControlEvent("ice_physics",true); } if (isTimerActive('cc_behindTimer')){ player().bBehindView=True; player().bCrosshairVisible=False; + player().ViewTarget=None; } if (decrementTimer('cc_behindTimer')) { - player().bBehindView=False; - player().bCrosshairVisible = True; - - PlayerMessage("You re-enter your body"); + StopCrowdControlEvent("third_person",true); } if (decrementTimer('cc_DifficultyTimer')){ - storeFloatValue('cc_damageMult',1.0); - PlayerMessage("Your body returns to its normal toughness"); + StopCrowdControlEvent("dmg_double",true); //also dmg_half } if (decrementTimer('cc_floatyTimer')) { - SetFloatyPhysics(False); - PlayerMessage("You feel weighed down again"); + StopCrowdControlEvent("floaty_physics",true); } if (decrementTimer('cc_floorLavaTimer')) { - PlayerMessage("The floor returns to normal temperatures"); + StopCrowdControlEvent("floor_is_lava",true); } if (decrementTimer('cc_invertMouseTimer')) { - PlayerMessage("Your mouse controls return to normal"); - player().bInvertMouse = bool(datastorage.GetConfigKey('cc_InvertMouseDef')); + StopCrowdControlEvent("invert_mouse",true); } if (decrementTimer('cc_invertMovementTimer')) { - PlayerMessage("Your movement controls return to normal"); - invertMovementControls(); + StopCrowdControlEvent("invert_movement",true); } if (decrementTimer('cc_Earthquake')) { - PlayerMessage("The earthquake ends"); - player().shaketimer=0; + StopCrowdControlEvent("earthquake",true); } //Re-apply the quake, just in case some other shake happened and ended during the timer (ie. superfreighter) @@ -197,17 +197,26 @@ function PeriodicUpdates() } if (decrementTimer('cc_RollTimer')) { - PlayerMessage("Your world turns rightside up again"); - datastorage.SetConfig('cc_cameraRoll',0, 3600*12); - datastorage.SetConfig('cc_cameraSpin',0, 3600*12); + StopCrowdControlEvent("barrel_roll",true); //also "flipped" and "limp_neck" } if (decrementTimer('cc_EatBeans')) { - PlayerMessage("Your stomach settles down"); + StopCrowdControlEvent("eat_beans",true); } else if (isTimerActive('cc_EatBeans') && !InMenu()){ Fart(); } + if (isTimerActive('cc_ResidentEvil')){ + if (reCam==None){ + SpawnRECam(); + } + + player().bCrosshairVisible=False; + } + if (decrementTimer('cc_ResidentEvil')) { + StopCrowdControlEvent("resident_evil",true); + } + if (flashbangDuration>0){ flashbangDuration--; if (flashbangDuration==0){ @@ -220,6 +229,24 @@ function PeriodicUpdates() quickLoadTriggered = False; player().QuickLoadConfirmed(); } + + if (isTimerActive('cc_Radioactive')){ + PlayerRadiates(); + } + if (decrementTimer('cc_Radioactive')){ + StopCrowdControlEvent("radioactive",true); + } + +#ifdef vanilla + if (isTimerActive('cc_DoomMode')){ + Player().bDoomMode=True; + } else { + Player().bDoomMode=False; + } +#endif + if (decrementTimer('cc_DoomMode')){ + StopCrowdControlEvent("doom_mode",true); + } } function HandleEffectSelectability() @@ -456,6 +483,27 @@ function InitOnEnter() { } else { player().shaketimer=0; } + + if (isTimerActive('cc_ResidentEvil')) { + if (reCam==None){ + SpawnRECam(); + } + if (player().ViewTarget==None){ + player().ViewTarget=reCam; + player().bCrosshairVisible=False; + } + + player().bCrosshairVisible=False; + } else { + player().ViewTarget=None; + player().bCrosshairVisible=True; + if (reCam==None){ + foreach AllActors(class'CCResidentEvilCam',reCam){ + reCam.Destroy(); + } + } + } + } //Effects should revert to default before exiting a level @@ -477,6 +525,10 @@ function CleanupOnExit() { if (isTimerActive('cc_invertMovementTimer')) { invertMovementControls(); } + if (reCam!=None && player().ViewTarget==reCam){ + player().ViewTarget=None; + reCam.Destroy(); + } } @@ -568,6 +620,12 @@ function int getDefaultTimerTimeByName(name timerName) { return CameraRollTimeDefault; case 'cc_EatBeans': return EatBeansTimeDefault; + case 'cc_ResidentEvil': + return ResidentEvilTimeDefault; + case 'cc_Radioactive': + return RadiationTimeDefault; + case 'cc_DoomMode': + return DoomModeTimeDefault; default: PlayerMessage("Unknown timer name "$timerName); @@ -621,6 +679,13 @@ function string getTimerLabelByName(name timerName) { return "Camera"; case 'cc_EatBeans': return "Beans"; + case 'cc_ResidentEvil': + return "Fixed Cam"; + case 'cc_Radioactive': + return "Radiation"; + case 'cc_DoomMode': + return "Doom"; + default: PlayerMessage("Unknown timer name "$timerName); @@ -700,6 +765,10 @@ function bool decrementTimer(name timerName) { return false; } +function disableTimer(name timerName) { + setTimerFlag(timerName,0,False); +} + function startNewTimer(name timerName, int duration) { if (duration==0){ duration = getDefaultTimerTimeByName(timerName); @@ -798,6 +867,10 @@ function class getScriptedPawnClass(string type) { return class(ccLink.ccModule.GetClassFromString(type, class'ScriptedPawn')); } +function class<#var(DeusExPrefix)Weapon> getWeaponClass(string type) { + return class<#var(DeusExPrefix)Weapon>(ccLink.ccModule.GetClassFromString(type, class'#var(DeusExPrefix)Weapon')); +} + //"Why not just use "GivePlayerAugmentation", you ask. //While it works well to give the player an aug they don't @@ -826,7 +899,7 @@ function int GiveAug(Class giveClass, string viewer) { } class'DXRAugmentations'.static.UpgradeAug(anAug); - + class'DXRAugmentations'.static.RedrawAugMenu(player()); PlayerMessage(viewer@"upgraded "$anAug.AugmentationName$" to level "$anAug.CurrentLevel+1 $ shouldSave); return Success; } @@ -858,6 +931,9 @@ function int GiveAug(Class giveClass, string viewer) { if ((!anAug.bAlwaysActive) && (player().bHUDShowAllAugs)) player().AddAugmentationDisplay(anAug); + + class'DXRAugmentations'.static.RedrawAugMenu(player()); + PlayerMessage(viewer@"gave you the "$anAug.AugmentationName$" augmentation" $ shouldSave); return Success; } @@ -918,10 +994,12 @@ function int RemoveAug(Class giveClass, string viewer) { } PlayerMessage(viewer@"downgraded "$anAug.AugmentationName$" to level "$anAug.CurrentLevel+1); + class'DXRAugmentations'.static.RedrawAugMenu(player()); return Success; } class'DXRAugmentations'.static.RemoveAug(player(),anAug); + class'DXRAugmentations'.static.RedrawAugMenu(player()); PlayerMessage(viewer@"removed your "$anAug.AugmentationName$" augmentation"); return Success; @@ -998,28 +1076,34 @@ function SetFloatyPhysics(bool enabled) { } } - if (enabled){ - //Get everything floating immediately - ForEach AllActors(class'Actor',A) - { - apply = False; - if (A.isa('ScriptedPawn')){ - apply = (A.GetStateName() != 'Patrolling' && - ScriptedPawn(A).Orders != 'Sitting'); - } else if (A.isa('PlayerPawn')) { - apply = True; - } else if (A.isa('Decoration')) { - apply = ((A.Base!=None && - A.Physics == PHYS_None && - A.bStatic == False && - Decoration(A).bPushable == True) || A.isa('Carcass')); - } else if (A.isa('Inventory')) { - apply = (Pawn(A.Owner) == None); - } - - if (apply) { + //Get everything floating immediately + ForEach AllActors(class'Actor',A) + { + apply = False; + if (A.isa('ScriptedPawn')){ + apply = (A.GetStateName() != 'Patrolling' && + ScriptedPawn(A).Orders != 'Sitting'); + } else if (A.isa('PlayerPawn')) { + apply = True; + } else if (A.isa('Decoration')) { + apply = ((A.Base!=None && + A.Physics == PHYS_None && + A.bStatic == False && + Decoration(A).bPushable == True) || A.isa('Carcass')); + } else if (A.isa('Inventory')) { + apply = (Pawn(A.Owner) == None); + } + + if (apply) { + if (enabled){ A.Velocity.Z+=Rand(10)+1; A.SetPhysics(PHYS_Falling); + } else { + if (Pawn(A)!=None && A.Region.Zone.bWaterZone){ + A.SetPhysics(PHYS_Swimming); + } else { + A.SetPhysics(PHYS_Falling); + } } } } @@ -1210,15 +1294,15 @@ function int GiveItem(string viewer, string type, optional int amount) { outMsg = viewer@"gave you"; if( amount > 1 && DeusExAmmo(item) != None ) { - outMsg = outMsg @amount@"cases of"@item.Default.ItemName; + outMsg = outMsg @amount@"cases of"@item.ItemName; } else if( DeusExAmmo(item) != None ) { - outMsg = outMsg @"a case of"@item.Default.ItemName; + outMsg = outMsg @"a case of"@item.ItemName; } else if( amount > 1 ) { - outMsg = outMsg @ amount @ item.Default.ItemName $ "s"; + outMsg = outMsg @ amount @ item.ItemName $ "s"; } else { - outMsg = outMsg @ item.Default.ItemArticle @ item.Default.ItemName; + outMsg = outMsg @ item.ItemArticle @ item.ItemName; } PlayerMessage(outMsg $ shouldSave); @@ -1252,7 +1336,7 @@ function int DropProjectile(string viewer, string type, optional int amount) return Success; } -function ScriptedPawn findOtherHuman() { +function ScriptedPawn findOtherHuman(bool bAllowImportant) { local int num; local ScriptedPawn p; local ScriptedPawn humans[512]; @@ -1261,7 +1345,9 @@ function ScriptedPawn findOtherHuman() { foreach AllActors(class'ScriptedPawn',p) { if (class'DXRActorsBase'.static.IsHuman(p.class) && p!=player() && !p.bHidden && !p.bStatic && p.bInWorld && p.Orders!='Sitting') { - humans[num++] = p; + if (!p.bImportant || bAllowImportant){ + humans[num++] = p; + } } } @@ -1272,7 +1358,7 @@ function ScriptedPawn findOtherHuman() { function bool swapPlayer(string viewer) { local ScriptedPawn a; - a = findOtherHuman(); + a = findOtherHuman(False); if (a == None) { return false; @@ -1344,6 +1430,7 @@ function int TriggerAllAlarms(String viewer) { local int numAlarms; local AlarmUnit au; local SecurityCamera sc; + local LaserTrigger lt; numAlarms = 0; @@ -1352,11 +1439,19 @@ function int TriggerAllAlarms(String viewer) { au.Trigger(self,player()); } foreach AllActors(class'SecurityCamera',sc){ + if (CCResidentEvilCam(sc)!=None){ continue; } //Skip Resident Evil cameras numAlarms+=1; sc.TriggerEvent(True); sc.bPlayerSeen=True; sc.lastSeenTimer=0; } + foreach AllActors(class'LaserTrigger',lt){ + if (lt.bIsOn==False){continue;} + if (lt.bNoAlarm){continue;} + if (lt.AmbientSound!=None){continue;} + numAlarms+=1; + lt.BeginAlarm(); + } if (numAlarms==0){ return TempFail; @@ -1391,6 +1486,57 @@ function int SpawnNastyRat(string viewer) return Success; } +function int DropPiano(string viewer) +{ + local Actor a; + local DXRActorsBase tracer; + local vector loc; + local float height, leading; + local #var(PlayerPawn) p; + + p = player(); + loc = p.Location; + leading = FRand() * 0.75 + 0.25; // minimum of 25% leading means keep moving, maximum of 100% leading means you need to stop moving (or just sidestep lol) + loc.X += p.Velocity.X * leading; + loc.Y += p.Velocity.Y * leading; + height = 800; + tracer = DXRActorsBase(dxr.FindModule(class'DXRActorsBase')); + if(tracer != None) { + height = tracer.GetDistanceFromSurface(loc, loc+vect(0,0,800)); + } + + //Make sure it is far enough off the ground (at LEAST twice the height of the player) + if (height < (2 * player().CollisionHeight)){ + return TempFail; + } + + loc.Z += height; + + //Make sure there's a reasonable line of sight between the piano spawnpoint and the player + if (!player().FastTrace(loc)){ + return TempFail; + } + + a = Spawn(class'#var(prefix)WHPiano',,, loc); + //Did it spawn successfully? + if(a == None) { + return TempFail; + } + + //Make sure there's still a line of sight from where it actually spawned + if (!a.FastTrace(player().Location)){ + a.Destroy(); //Pretend it never existed if there isn't + return TempFail; + } + + a.Velocity.Z -= 200; + a.Instigator = GetCrowdControlPawn(viewer); + a.FamiliarName=viewer$"'s Grand Piano"; + a.UnfamiliarName=a.FamiliarName; + PlayerMessage(viewer$" dropped a piano on you from "$int(height/16 + 0.5)$" feet with "$int(leading*100 + 0.5)$"% leading!"); + return Success; +} + function int SpawnPawnNearPlayer(DeusExPlayer p, class newclass, bool friendly, string viewer) { local int i; @@ -1503,6 +1649,403 @@ function bool canDropItem() { } +function bool CanSwapEnemies() +{ + local int numEnemies; + local ScriptedPawn a; + + numEnemies=0; + foreach AllActors(class'ScriptedPawn', a ) + { + if( a.bHidden || a.bStatic ) continue; + if( a.bImportant || a.bIsSecretGoal ) continue; + if( !ccLink.ccModule.IsRelevantPawn(a.class) ) continue; + if( !ccLink.ccModule.IsInitialEnemy(a) ) continue; + if( a.Region.Zone.bWaterZone || a.Region.Zone.bPainZone ) continue; + if( #var(prefix)Robot(a) != None && a.Orders == 'Idle' ) continue; +#ifdef gmdx + if( SpiderBot2(a) != None && SpiderBot2(a).bUpsideDown ) continue; +#endif + numEnemies++; + } + + //As long as there are two possible enemies... + return numEnemies > 1; +} + +function bool SwapAllEnemies(string viewer) +{ + local DXREnemiesShuffle enemies; + + foreach AllActors(class'DXREnemiesShuffle',enemies){break;} + + if (enemies==None) return False; //Failed to find DXREnemiesShuffle + + enemies.SwapScriptedPawns(100,true); + + PlayerMessage(viewer@"swapped the position of all the enemies in the level!"); + + return true; +} + +function bool CanSwapItems() +{ + local int numItems; + local Inventory inv; + + numItems=0; + foreach AllActors(class'Inventory',inv){ + if (!ccLink.ccModule.SkipActor(inv)){ + numItems++; + } + } + + return numItems>1; +} + +function bool SwapAllItems(string viewer) +{ + ccLink.ccModule.SwapAll("Engine.Inventory",100); + + PlayerMessage(viewer@"swapped the position of all the inventory items in the level!"); + + return true; +} + +function bool ToggleFlashlight(string viewer) +{ + local Augmentation aug; + + aug = player().AugmentationSystem.FindAugmentation(class'#var(prefix)AugLight'); + + if (aug==None) return False; + + if (aug.IsActive()){ + aug.Deactivate(); + } else { + aug.Activate(); + } + + PlayerMessage(viewer@"toggled your flashlight!"); + + return true; + +} + +function int GiveAllEnemiesWeapon(class<#var(DeusExPrefix)Weapon> w,string viewer) +{ + local int numEnemies; + local inventory inv; + local ScriptedPawn a; + + numEnemies=0; + + foreach AllActors(class'ScriptedPawn', a ) + { + if( a.bHidden || a.bStatic ) continue; + if( #var(prefix)Animal(a)!=None ) continue; + if( #var(prefix)Robot(a) != None ) continue; + if( !ccLink.ccModule.IsInitialEnemy(a) ) continue; + numEnemies++; + inv = ccLink.ccModule.GiveItem(a,w,1); + } + + if (numEnemies==0){ + return TempFail; + } + + PlayerMessage(viewer@"gave "$numEnemies$" enemies a "$inv.ItemName$"!"); + + return Success; +} + +function bool HealAllEnemies(string viewer) +{ + local int numEnemies; + local ScriptedPawn a; + + numEnemies=0; + + foreach AllActors(class'ScriptedPawn', a ) + { + if( a.bHidden || a.bStatic ) continue; + if( #var(prefix)Animal(a)!=None ) continue; + if( #var(prefix)Robot(a) != None ) continue; + if( !ccLink.ccModule.IsInitialEnemy(a) ) continue; + if ( a.IsInState('Dying') ) continue; //It's too late for this guy... + if ( a.bInvincible ) continue; + if ( a.Health >= a.Default.Health ) continue; //Nothing to heal + + numEnemies++; + a.Health = a.Default.Health; + a.HealthArmLeft = a.Default.HealthArmLeft; + a.HealthArmRight = a.Default.HealthArmRight; + a.HealthLegLeft = a.Default.HealthLegLeft; + a.HealthLegRight = a.Default.HealthLegRight; + a.HealthHead = a.Default.HealthHead; + a.HealthTorso = a.Default.HealthTorso; + + if (a.bOnFire){ + a.ExtinguishFire(); + } + + //Get back in the fight, soldier! + if (a.IsInState('Fleeing') || a.IsInState('Burning') || a.IsInState('RubbingEyes')){ + a.FearLevel=0; + a.FollowOrders(); + } + } + + if (numEnemies==0){ + return False; + } + + PlayerMessage(viewer@"healed "$numEnemies$" enemies to full health!"); + + return True; +} + +function bool RaiseDead(string viewer) +{ + local DeusExCarcass carc; + local int num,i; + + num=0; + + for (i=0;i<5;i++){ + carc = FindClosestCarcass(1000,false); + if (carc==None){ + break; + } + if (ResurrectCorpse(carc,viewer)){ + num++; + } + } + + if (num==0){ + return False; + } + + PlayerMessage(viewer@"resurrected "$num$" from the dead!"); + + return True; +} + +function bool ResurrectCorpse(DeusExCarcass carc, String viewer) +{ + local string livingClassName; + local class livingClass; + local vector respawnLoc; + local ScriptedPawn sp,otherSP; + local int i; + local Inventory item, nextItem; + local bool removeItem; + + //At least in vanilla, all carcasses are the original class name + Carcass + livingClassName = string(carc.class.Name); + livingClassName = class'DXRInfo'.static.ReplaceText(livingClassName,"Carcass",""); + + livingClass = ccLink.ccModule.GetClassFromString(livingClassName,class'ScriptedPawn'); + + if (livingClass==None){ + return False; + } + + respawnLoc = carc.Location; + respawnLoc.Z +=livingClass.Default.CollisionHeight; + + sp = ScriptedPawn(Spawn(livingClass,,,respawnLoc,carc.Rotation)); + + if (sp==None){ + return False; + } + + sp.FamiliarName = viewer$"'s Zombie"; + sp.UnfamiliarName = sp.FamiliarName; + sp.bInvincible = False; //If they died, they can't have been invincible + + //Clear out initial inventory (since that should all be in the carcass, except for native attacks) + for (i=0;i 0.2) + spawn(class'FleshFragment',,,carc.Location); + } + + carc.Destroy(); + + return True; +} + +function bool CorpseExplosion(string viewer) +{ + local DeusExCarcass carc; + local int num,i; + local DXRandoCrowdControlPawn viewerPawn; + + viewerPawn = GetCrowdControlPawn(viewer); + num=0; + + for (i=0;i<5;i++){ + carc = FindClosestCarcass(1000,true); + if (carc==None){ + break; + } + carc.Instigator = viewerPawn; + DetonateCarcass(carc); + num++; + } + + if (num==0){ + return False; + } + + PlayerMessage(viewer@"detonated "$num$" corpses!"); + + return True; + +} + +function DeusExCarcass FindClosestCarcass(float radius,optional bool bAllowAnimals) +{ + local DeusExCarcass carc,closest; + local float closeDist; + + closest = None; + closeDist = 2 * radius; + foreach player().RadiusActors(class'DeusExCarcass',carc,radius){ + if (carc.bNotDead){ + continue; //Skip unconscious bodies + } + if (!bAllowAnimals && carc.bAnimalCarcass){ + continue; + } + if (VSize(carc.Location-player().Location) < closeDist){ + closest = carc; + closeDist = VSize(carc.Location-player().Location); + } + } + + return closest; +} + +//Duped from MIB +function DetonateCarcass(DeusExCarcass carc) +{ + local SphereEffect sphere; + local ScorchMark s; + local ExplosionLight light; + local int i; + local float explosionDamage; + local float explosionRadius; + + explosionDamage = 100; + explosionRadius = 256; + + // alert NPCs that I'm exploding + AISendEvent('LoudNoise', EAITYPE_Audio, , explosionRadius*16); + PlaySound(Sound'LargeExplosion1', SLOT_None,,, explosionRadius*16); + + // draw a pretty explosion + light = Spawn(class'ExplosionLight',,, carc.Location); + if (light != None) + light.size = 4; + + Spawn(class'ExplosionSmall',,, carc.Location + 2*VRand()*carc.CollisionRadius); + Spawn(class'ExplosionMedium',,, carc.Location + 2*VRand()*carc.CollisionRadius); + Spawn(class'ExplosionMedium',,, carc.Location + 2*VRand()*carc.CollisionRadius); + Spawn(class'ExplosionLarge',,, carc.Location + 2*VRand()*carc.CollisionRadius); + + sphere = Spawn(class'SphereEffect',,, carc.Location); + if (sphere != None) + sphere.size = explosionRadius / 32.0; + + // spawn a mark + s = spawn(class'ScorchMark', carc.Base,, carc.Location-vect(0,0,1)*carc.CollisionHeight, carc.Rotation+rot(16384,0,0)); + if (s != None) + { + s.DrawScale = FClamp(explosionDamage/30, 0.1, 3.0); + s.ReattachDecal(); + } + + // spawn some rocks and flesh fragments + for (i=0; i trashBagType) { local Vector loc; - local #var(prefix)Rat vermin; local #var(prefix)Containers trashbag; local float scale, scaleCorrection; @@ -45,46 +52,66 @@ static function DestroyTrashCan(#var(prefix)Containers trashcan, class<#var(pref // maybe spawn a rat, but not if underwater if (!trashcan.Region.Zone.bWaterZone && FRand() < 0.17) // creates a final 50% chance of getting a rat - { - loc = trashcan.Location; - loc.Z -= trashcan.CollisionHeight; - vermin = trashcan.Spawn(class'#var(prefix)Rat',,, loc); - if (vermin != None) - vermin.bTransient = true; - } + SummonRat(trashcan); } } -static function GenerateTrashPaper(#var(prefix)Containers trashcan, float probability) +static function SummonRat(#var(prefix)Containers container) +{ + local Vector loc; + local #var(prefix)Rat vermin; + + loc = container.Location; + loc.Z -= container.CollisionHeight; + vermin = container.Spawn(class'#var(prefix)Rat',,, loc); + if (vermin != None) + vermin.bTransient = true; +} + +static function GenerateTrashPaper(#var(prefix)Containers trashContainer, float probability, optional bool onFire) { local Vector loc; local int i; local #var(prefix)TrashPaper trashPaper; + local int numPaperChances; + local Fire fire; + + onFire = onFire || trashContainer.IsInState('Burning'); + + if (onFire) + numPaperChances = 3; + else + numPaperChances = 4; // trace down to see if we are sitting on the ground loc = vect(0,0,0); - loc.Z -= trashcan.CollisionHeight + 8.0; - loc += trashcan.Location; + loc.Z -= trashContainer.CollisionHeight + 8.0; + loc += trashContainer.Location; // only generate trashpaper if we're on the ground - if (!trashcan.FastTrace(loc)) - { - for (i=0; i<4; i++) - { - if (FRand() < probability) - { - loc = trashcan.Location; - loc.X += (trashcan.CollisionRadius / 2) - FRand() * trashcan.CollisionRadius; - loc.Y += (trashcan.CollisionRadius / 2) - FRand() * trashcan.CollisionRadius; - loc.Z += (trashcan.CollisionHeight / 2) - FRand() * trashcan.CollisionHeight; - trashPaper = trashcan.Spawn(class'#var(prefix)TrashPaper',,, loc); - if (trashPaper != None) - { + if (!trashContainer.FastTrace(loc)) { + for (i=0; i < numPaperChances; i++) { + if (FRand() < probability) { + loc = trashContainer.Location; + loc.X += (trashContainer.CollisionRadius / 2) - FRand() * trashContainer.CollisionRadius; + loc.Y += (trashContainer.CollisionRadius / 2) - FRand() * trashContainer.CollisionRadius; + loc.Z += (trashContainer.CollisionHeight / 2) - FRand() * trashContainer.CollisionHeight; + trashPaper = trashContainer.Spawn(class'#var(prefix)TrashPaper',,, loc); + if (trashPaper != None) { trashPaper.SetPhysics(PHYS_Rolling); trashPaper.rot = RotRand(True); trashPaper.rot.Yaw = 0; trashPaper.dir = VRand() * 20 + vect(20,20,0); trashPaper.dir.Z = 0; + + if (onFire && FRand() < 0.5) { + fire = trashPaper.Spawn(class'SmokelessFire', trashPaper,, loc); + if (fire != None) { + fire.DrawScale = 0.25*FRand() + 0.5; + fire.AmbientSound = Sound'Ambient.Ambient.FireSmall1'; + fire.SoundVolume = 200; + } + } } } } diff --git a/DXRando/DeusEx/Classes/Trashbag.uc b/DXRando/DeusEx/Classes/Trashbag.uc index 1aca16eba..0c4d1851a 100644 --- a/DXRando/DeusEx/Classes/Trashbag.uc +++ b/DXRando/DeusEx/Classes/Trashbag.uc @@ -9,5 +9,22 @@ function Destroyed() class'DXREvents'.static.MarkBingo(dxr,"BurnTrash"); } } + + class'TrashContainerCommon'.static.DestroyTrashbag(self); + Super.Destroyed(); } + +function SupportActor(Actor standingActor) +{ + if (standingActor != None && standingActor.Mass>=35){ + bCanBeBase=False; + TakeDamage(HitPoints,standingActor.Instigator, standingActor.Location, 0.2*standingActor.Velocity, 'stomped'); + } + Super.SupportActor(standingActor); +} + +defaultproperties +{ + bGenerateTrash=False +} diff --git a/DXRando/DeusEx/Classes/Trashbag2.uc b/DXRando/DeusEx/Classes/Trashbag2.uc index b4a4d2606..c6d676c3d 100644 --- a/DXRando/DeusEx/Classes/Trashbag2.uc +++ b/DXRando/DeusEx/Classes/Trashbag2.uc @@ -9,5 +9,22 @@ function Destroyed() class'DXREvents'.static.MarkBingo(dxr,"BurnTrash"); } } + + class'TrashContainerCommon'.static.DestroyTrashbag(self); + Super.Destroyed(); } + +function SupportActor(Actor standingActor) +{ + if (standingActor != None && standingActor.Mass>=35){ + bCanBeBase=False; + TakeDamage(HitPoints,standingActor.Instigator, standingActor.Location, 0.2*standingActor.Velocity, 'stomped'); + } + Super.SupportActor(standingActor); +} + +defaultproperties +{ + bGenerateTrash=False +} diff --git a/DXRando/DeusEx/Classes/WHPiano.uc b/DXRando/DeusEx/Classes/WHPiano.uc index d161fa389..c50be68bd 100644 --- a/DXRando/DeusEx/Classes/WHPiano.uc +++ b/DXRando/DeusEx/Classes/WHPiano.uc @@ -24,6 +24,16 @@ function bool ValidSong(int i) return True; } +function Landed(vector HitNormal) +{ + Super.Landed(HitNormal); + + if (Velocity.Z <= -200) + { + soundHandle = PlaySound(sound'MaxPaynePianoJustBroke', SLOT_Misc,5.0,, 500); + } +} + simulated function Tick(float deltaTime) { if (bUsing){ @@ -98,7 +108,7 @@ function Frob(actor Frobber, Inventory frobWith) if ( !PianoIsBroken() ) { rnd = currentSong; while(rnd == currentSong) { - rnd = Rand(38); //make sure this matches the number of sounds below + rnd = Rand(46); //make sure this matches the number of sounds below } currentSong = rnd; switch(currentSong){ @@ -263,6 +273,38 @@ function Frob(actor Frobber, Inventory frobWith) SelectedSound = sound'TetrisThemeA'; duration = 8; break; + case 38: + SelectedSound = sound'NokiaRing'; + duration = 4; + break; + case 39: + SelectedSound = sound'AllStar'; + duration = 8; + break; + case 40: + SelectedSound = sound'BlasterMasterArea1'; + duration = 5; + break; + case 41: + SelectedSound = sound'DrMarioFever'; + duration = 5; + break; + case 42: + SelectedSound = sound'SML2SpaceZone2'; + duration = 7; + break; + case 43: + SelectedSound = sound'SimCity2kDowntownDance'; + duration = 7; + break; + case 44: + SelectedSound = sound'MoonlightSonata'; + duration = 10; + break; + case 45: + SelectedSound = sound'REMansionBasement'; + duration = 9; + break; default: log("DXRPiano went too far this time! Got "$currentSong); return; @@ -369,6 +411,22 @@ function string GetSongMessage(Sound SelectedSound) return "You played Guile's Theme from Street Fighter 2"; case sound'TetrisThemeA': return "You played Theme A from Tetris"; + case sound'NokiaRing': + return "You played the Nokia ringtone"; + case sound'AllStar': + return "You played All Star by Smash Mouth"; + case sound'BlasterMasterArea1': + return "You played the Area 1 theme from Blaster Master"; + case sound'DrMarioFever': + return "You played Fever from Dr. Mario"; + case sound'SML2SpaceZone2': + return "You played Space Zone 2 from Super Mario Land 2: Six Golden Coins"; + case sound'SimCity2kDowntownDance': + return "You played Downtown Dance from SimCity 2000"; + case sound'MoonlightSonata': + return "You played Moonlight Sonata by Beethoven"; + case sound'REMansionBasement': + return "You played the Basement theme from Resident Evil: Director's Cut... for some reason"; case sound'MaxPayneBrokenPianoPlay': return "You played a broken piano"; case sound'MaxPaynePianoJustBroke': diff --git a/DXRando/DeusEx/Classes/WeaponMegaChoice.uc b/DXRando/DeusEx/Classes/WeaponMegaChoice.uc new file mode 100644 index 000000000..5eba1d482 --- /dev/null +++ b/DXRando/DeusEx/Classes/WeaponMegaChoice.uc @@ -0,0 +1,71 @@ +class WeaponMegaChoice extends Info; + +var DXRActorsBase dxrAB; +var #var(PlayerPawn) p; +var Name convoName; + +static function WeaponMegaChoice Create(#var(PlayerPawn) p) +{ + local WeaponMegaChoice megaChoice; + local Actor a; + + a = p.Spawn(default.class,,default.convoName); + megaChoice = WeaponMegaChoice(a); + megaChoice.p = p; + + megaChoice.AddWeaponChoiceTrigger(); + + return megaChoice; +} + +event PostPostBeginPlay() +{ + Super.PostPostBeginPlay(); + + if (p==None){ + foreach AllActors(class'#var(PlayerPawn)',p){break;} + } + AddWeaponChoiceTrigger(); +} + +//Borrowed from DXRActorsBase +function Conversation GetConversation(Name conName) +{ + local Conversation c; + if (p.flagBase.GetBool('LDDPJCIsFemale')) { + conName = p.flagBase.StringToName("FemJC"$string(conName)); + } + foreach AllObjects(class'Conversation', c) { + if( c.conName == conName ) return c; + } + return None; +} + +function AddWeaponChoiceTrigger() +{ + local Conversation c; + local ConEventTrigger cet; + + //The idea is that the conversation starts, triggers this class, + //which goes and generates the weapon choices for the conversation + c = GetConversation(convoName); + + cet = new(c) class'ConEventTrigger'; + cet.eventType=ET_Trigger; + cet.triggerTag = tag; + + cet.nextEvent = c.eventList; + c.eventList = cet; +} + +function Trigger(Actor Other,Pawn Instigator) +{ + GenerateWeaponChoice(); +} + +function GenerateWeaponChoice(); + +defaultproperties +{ + convoName=InvalidConvoName +} diff --git a/DXRando/DeusEx/Classes/WeaponZombieSwipe.uc b/DXRando/DeusEx/Classes/WeaponZombieSwipe.uc new file mode 100644 index 000000000..89b54762e --- /dev/null +++ b/DXRando/DeusEx/Classes/WeaponZombieSwipe.uc @@ -0,0 +1,23 @@ +class WeaponZombieSwipe extends #var(prefix)WeaponNPCMelee; + +defaultproperties +{ + bOwnerWillNotify=false + FireSound=None + Misc1Sound=Sound'DeusExSounds.Animal.GrayAttack' + Misc2Sound=Sound'DeusExSounds.Animal.GrayAttack' + Misc3Sound=Sound'DeusExSounds.Animal.GrayAttack' + SelectSound=None + PlayerViewScale=0.001 + PickupViewScale=0.001 + ThirdPersonScale=0.001 + ShotTime=0.250000 + HitDamage=6 + maxRange=100 + AccurateRange=100 + BaseAccuracy=0.000000 + PlayerViewMesh=LodMesh'DeusExItems.CombatKnife' + PickupViewMesh=LodMesh'DeusExItems.CombatKnifePickup' + ThirdPersonMesh=LodMesh'DeusExItems.CombatKnife3rd' + Mesh=LodMesh'DeusExItems.CombatKnifePickup' +} diff --git a/DXRando/DeusEx/Sounds/AllStar.mp3 b/DXRando/DeusEx/Sounds/AllStar.mp3 new file mode 100644 index 000000000..81d5a59a0 Binary files /dev/null and b/DXRando/DeusEx/Sounds/AllStar.mp3 differ diff --git a/DXRando/DeusEx/Sounds/BlasterMasterArea1.mp3 b/DXRando/DeusEx/Sounds/BlasterMasterArea1.mp3 new file mode 100644 index 000000000..c6c57d716 Binary files /dev/null and b/DXRando/DeusEx/Sounds/BlasterMasterArea1.mp3 differ diff --git a/DXRando/DeusEx/Sounds/DrMarioFever.mp3 b/DXRando/DeusEx/Sounds/DrMarioFever.mp3 new file mode 100644 index 000000000..d83b7916a Binary files /dev/null and b/DXRando/DeusEx/Sounds/DrMarioFever.mp3 differ diff --git a/DXRando/DeusEx/Sounds/MoonlightSonata.mp3 b/DXRando/DeusEx/Sounds/MoonlightSonata.mp3 new file mode 100644 index 000000000..6c513a4a9 Binary files /dev/null and b/DXRando/DeusEx/Sounds/MoonlightSonata.mp3 differ diff --git a/DXRando/DeusEx/Sounds/NokiaRing.mp3 b/DXRando/DeusEx/Sounds/NokiaRing.mp3 new file mode 100644 index 000000000..14072916a Binary files /dev/null and b/DXRando/DeusEx/Sounds/NokiaRing.mp3 differ diff --git a/DXRando/DeusEx/Sounds/REMansionBasement.mp3 b/DXRando/DeusEx/Sounds/REMansionBasement.mp3 new file mode 100644 index 000000000..a159654e1 Binary files /dev/null and b/DXRando/DeusEx/Sounds/REMansionBasement.mp3 differ diff --git a/DXRando/DeusEx/Sounds/SML2SpaceZone2.mp3 b/DXRando/DeusEx/Sounds/SML2SpaceZone2.mp3 new file mode 100644 index 000000000..cb4d1f730 Binary files /dev/null and b/DXRando/DeusEx/Sounds/SML2SpaceZone2.mp3 differ diff --git a/DXRando/DeusEx/Sounds/SimCity2kDowntownDance.mp3 b/DXRando/DeusEx/Sounds/SimCity2kDowntownDance.mp3 new file mode 100644 index 000000000..f9fa8c004 Binary files /dev/null and b/DXRando/DeusEx/Sounds/SimCity2kDowntownDance.mp3 differ diff --git a/DeusEx.u b/DeusEx.u index d2ed953b3..de262e672 100644 Binary files a/DeusEx.u and b/DeusEx.u differ diff --git a/GMDXRandomizer.u b/GMDXRandomizer.u index c50268ca6..07a92b97f 100644 Binary files a/GMDXRandomizer.u and b/GMDXRandomizer.u differ diff --git a/GUI/DeusEx/Classes/ColorThemeHUD_Dynamic.uc b/GUI/DeusEx/Classes/ColorThemeHUD_Dynamic.uc new file mode 100644 index 000000000..809b2c88a --- /dev/null +++ b/GUI/DeusEx/Classes/ColorThemeHUD_Dynamic.uc @@ -0,0 +1,47 @@ +class ColorThemeHUD_Dynamic extends ColorThemeHUD abstract; + +var DeusExPlayer player; +var travel ColorThemeManager ThemeManager; +var float UpdateTime; + +function BeginPlay() +{ + Super.BeginPlay(); + foreach AllActors(class'DeusExPlayer', player) { + ThemeManager = player.ThemeManager; + break; + } + UpdateColours(); + SetTimer(UpdateTime, true); +} + +function Timer() +{ + if(ThemeManager != None && ThemeManager.currentHUDTheme == self) { + UpdateColours(); + } +} + +function UpdateColours(); + +defaultproperties +{ + themeName="Dynamic" + bSystemTheme=True + bAlwaysTick=True + UpdateTime=1 + Colors(0)=(R=0,G=0,B=0,A=0), + Colors(1)=(R=0,G=0,B=0,A=0), + Colors(2)=(R=0,G=0,B=0,A=0), + Colors(3)=(R=0,G=0,B=0,A=0), + Colors(4)=(R=0,G=0,B=0,A=0), + Colors(5)=(R=0,G=0,B=0,A=0), + Colors(6)=(R=0,G=0,B=0,A=0), + Colors(7)=(R=0,G=0,B=0,A=0), + Colors(8)=(R=0,G=0,B=0,A=0), + Colors(9)=(R=0,G=0,B=0,A=0), + Colors(10)=(R=0,G=0,B=0,A=0), + Colors(11)=(R=0,G=0,B=0,A=0), + Colors(12)=(R=0,G=0,B=0,A=0), + Colors(13)=(R=0,G=0,B=0,A=0), +} diff --git a/GUI/DeusEx/Classes/ColorThemeHUD_Health.uc b/GUI/DeusEx/Classes/ColorThemeHUD_Health.uc index 9228acb2e..7a2b831a3 100644 --- a/GUI/DeusEx/Classes/ColorThemeHUD_Health.uc +++ b/GUI/DeusEx/Classes/ColorThemeHUD_Health.uc @@ -2,7 +2,7 @@ // ColorThemeHUD_Health //============================================================================= -class ColorThemeHUD_Health extends ColorThemeHUD; +class ColorThemeHUD_Health extends ColorThemeHUD_Dynamic; /* Colors! @@ -22,24 +22,15 @@ class ColorThemeHUD_Health extends ColorThemeHUD; colors(13) = HUDColor_Cursor */ -var DeusExPlayer player; -var float UpdateTime; - // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- -function FindHealthColour(float health) +function UpdateColours() { local int i; local Color healthColour; - if (health > 0 && player!=None && player.RootWindow!=None){ - healthColour = player.rootWindow.GetColorScaled(health/100.0); - } else { - healthColour.r=255; - healthColour.g=0; - healthColour.b=0; - } + healthColour = class'ColorThemeMenu_Health'.static.GetHealthColor(player); for (i=0;i<=13;i++){ Colors[i]=healthColour; @@ -49,51 +40,8 @@ function FindHealthColour(float health) } } -function SetUIColour() -{ - local float critHealth; - if (player!=None){ - critHealth = MIN(player.HealthHead, player.HealthTorso); - player.GenerateTotalHealth(); - - FindHealthColour(MIN(player.Health,critHealth)); - } else { - FindHealthColour(0); - } -} - -function Timer() -{ - SetUIColour(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - SetUIColour(); - SetTimer(UpdateTime,true); -} - defaultproperties { themeName="Health" - bSystemTheme=True - bAlwaysTick=True UpdateTime=0.1 - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), - Colors(13)=(R=0,G=0,B=0,A=0), } diff --git a/GUI/DeusEx/Classes/ColorThemeHUD_Rando.uc b/GUI/DeusEx/Classes/ColorThemeHUD_Rando.uc index 334dded78..a8305b169 100644 --- a/GUI/DeusEx/Classes/ColorThemeHUD_Rando.uc +++ b/GUI/DeusEx/Classes/ColorThemeHUD_Rando.uc @@ -2,7 +2,7 @@ // ColorThemeHUD_Rando //============================================================================= -class ColorThemeHUD_Rando extends ColorThemeHUD; +class ColorThemeHUD_Rando extends ColorThemeHUD_Dynamic; /* Colors! @@ -22,9 +22,6 @@ class ColorThemeHUD_Rando extends ColorThemeHUD; colors(13) = HUDColor_Cursor */ -var DeusExPlayer player; -var float UpdateTime; - // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- @@ -39,7 +36,7 @@ function Color RandomColor() return newColor; } -function RandomAllColors() +function UpdateColours() { local int i; for (i=0;i<=13;i++){ @@ -50,38 +47,8 @@ function RandomAllColors() } } -function Timer() -{ - RandomAllColors(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - RandomAllColors(); - SetTimer(UpdateTime,true); -} - defaultproperties { themeName="Rando" - bSystemTheme=True - bAlwaysTick=True UpdateTime=0.5 - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), - Colors(13)=(R=0,G=0,B=0,A=0), } diff --git a/GUI/DeusEx/Classes/ColorThemeHUD_Swirl.uc b/GUI/DeusEx/Classes/ColorThemeHUD_Swirl.uc index 9d767916f..3d5681358 100644 --- a/GUI/DeusEx/Classes/ColorThemeHUD_Swirl.uc +++ b/GUI/DeusEx/Classes/ColorThemeHUD_Swirl.uc @@ -2,7 +2,7 @@ // ColorThemeHUD_Swirl //============================================================================= -class ColorThemeHUD_Swirl extends ColorThemeHUD; +class ColorThemeHUD_Swirl extends ColorThemeHUD_Dynamic; /* Colors! @@ -22,7 +22,6 @@ class ColorThemeHUD_Swirl extends ColorThemeHUD; colors(13) = HUDColor_Cursor */ -var DeusExPlayer player; var int rgbAngle[15]; //One per theme segment // ---------------------------------------------------------------------- @@ -70,7 +69,7 @@ function Color GetColorFromAngle(int angle) return c; } -function UpdateAllColors() +function UpdateColours() { local int i; for (i=0;i<=13;i++){ @@ -82,37 +81,8 @@ function UpdateAllColors() } } -function Timer() -{ - UpdateAllColors(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - RandomAllAngles(); - SetTimer(0.1,true); -} - defaultproperties { themeName="Swirl" - bSystemTheme=True - bAlwaysTick=True - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), - Colors(13)=(R=0,G=0,B=0,A=0), + UpdateTime=0.1 } diff --git a/GUI/DeusEx/Classes/ColorThemeMenuDynamic.uc b/GUI/DeusEx/Classes/ColorThemeMenuDynamic.uc new file mode 100644 index 000000000..9dcba76c7 --- /dev/null +++ b/GUI/DeusEx/Classes/ColorThemeMenuDynamic.uc @@ -0,0 +1,46 @@ +class ColorThemeMenu_Dynamic extends ColorThemeMenu abstract; + +var DeusExPlayer player; +var travel ColorThemeManager ThemeManager; +var float UpdateTime; + +function BeginPlay() +{ + Super.BeginPlay(); + foreach AllActors(class'DeusExPlayer', player) { + ThemeManager = player.ThemeManager; + break; + } + UpdateColours(); + SetTimer(UpdateTime, true); +} + +function Timer() +{ + if(ThemeManager != None && ThemeManager.currentMenuTheme == self) { + UpdateColours(); + } +} + +function UpdateColours(); + +defaultproperties +{ + themeName="Dynamic" + bSystemTheme=True + bAlwaysTick=True + UpdateTime=1 + Colors(0)=(R=0,G=0,B=0,A=0), + Colors(1)=(R=0,G=0,B=0,A=0), + Colors(2)=(R=0,G=0,B=0,A=0), + Colors(3)=(R=0,G=0,B=0,A=0), + Colors(4)=(R=0,G=0,B=0,A=0), + Colors(5)=(R=0,G=0,B=0,A=0), + Colors(6)=(R=0,G=0,B=0,A=0), + Colors(7)=(R=0,G=0,B=0,A=0), + Colors(8)=(R=0,G=0,B=0,A=0), + Colors(9)=(R=0,G=0,B=0,A=0), + Colors(10)=(R=0,G=0,B=0,A=0), + Colors(11)=(R=0,G=0,B=0,A=0), + Colors(12)=(R=0,G=0,B=0,A=0), +} diff --git a/GUI/DeusEx/Classes/ColorThemeMenu_Health.uc b/GUI/DeusEx/Classes/ColorThemeMenu_Health.uc index 61ae605ff..b821da579 100644 --- a/GUI/DeusEx/Classes/ColorThemeMenu_Health.uc +++ b/GUI/DeusEx/Classes/ColorThemeMenu_Health.uc @@ -2,7 +2,7 @@ // ColorThemeMenu_Health //============================================================================= -class ColorThemeMenu_Health extends ColorThemeMenu; +class ColorThemeMenu_Health extends ColorThemeMenu_Dynamic; /* Colors! @@ -21,17 +21,22 @@ class ColorThemeMenu_Health extends ColorThemeMenu; colorNames(11)=MenuColor_ListFocus */ -var DeusExPlayer player; -var float UpdateTime; - // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- -function FindHealthColour(float health) +static function Color GetHealthColor(DeusExPlayer player) { - local int i; + local float health; local Color healthColour; + if(player.Health > 0) + player.GenerateTotalHealth(); + + health = player.Health; + health = MIN(health, player.HealthHead); + health = MIN(health, player.HealthTorso); + health = MAX(health, 0); + if (health > 0 && player!=None && player.RootWindow!=None){ healthColour = player.rootWindow.GetColorScaled(health/100.0); } else { @@ -40,6 +45,16 @@ function FindHealthColour(float health) healthColour.b=0; } + return healthColour; +} + +function UpdateColours() +{ + local int i; + local Color healthColour; + + healthColour = GetHealthColor(player); + for (i=0;i<=13;i++){ Colors[i]=healthColour; } @@ -48,50 +63,8 @@ function FindHealthColour(float health) } } -function SetUIColour() -{ - local float critHealth; - if (player!=None){ - critHealth = MIN(player.HealthHead, player.HealthTorso); - player.GenerateTotalHealth(); - - FindHealthColour(MIN(player.Health,critHealth)); - } else { - FindHealthColour(0); - } -} - -function Timer() -{ - SetUIColour(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - SetUIColour(); - SetTimer(UpdateTime,true); -} - defaultproperties { themeName="Health" - bSystemTheme=True - bAlwaysTick=True UpdateTime=0.1 - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), } diff --git a/GUI/DeusEx/Classes/ColorThemeMenu_Rando.uc b/GUI/DeusEx/Classes/ColorThemeMenu_Rando.uc index dc9d172ae..e47270532 100644 --- a/GUI/DeusEx/Classes/ColorThemeMenu_Rando.uc +++ b/GUI/DeusEx/Classes/ColorThemeMenu_Rando.uc @@ -2,7 +2,7 @@ // ColorThemeMenu_Rando //============================================================================= -class ColorThemeMenu_Rando extends ColorThemeMenu; +class ColorThemeMenu_Rando extends ColorThemeMenu_Dynamic; /* Colors! @@ -21,9 +21,6 @@ class ColorThemeMenu_Rando extends ColorThemeMenu; colorNames(11)=MenuColor_ListFocus */ -var DeusExPlayer player; -var float UpdateTime; - // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- @@ -38,7 +35,7 @@ function Color RandomColor() return newColor; } -function RandomAllColors() +function UpdateColours() { local int i; for (i=0;i<=12;i++){ @@ -49,37 +46,8 @@ function RandomAllColors() } } -function Timer() -{ - RandomAllColors(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - RandomAllColors(); - SetTimer(UpdateTime,true); -} - defaultproperties { themeName="Rando" - bSystemTheme=True - bAlwaysTick=True UpdateTime=0.5 - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), } diff --git a/GUI/DeusEx/Classes/ColorThemeMenu_Swirl.uc b/GUI/DeusEx/Classes/ColorThemeMenu_Swirl.uc index 1fa2f29db..c5ea6518d 100644 --- a/GUI/DeusEx/Classes/ColorThemeMenu_Swirl.uc +++ b/GUI/DeusEx/Classes/ColorThemeMenu_Swirl.uc @@ -2,7 +2,7 @@ // ColorThemeMenu_Swirl //============================================================================= -class ColorThemeMenu_Swirl extends ColorThemeMenu; +class ColorThemeMenu_Swirl extends ColorThemeMenu_Dynamic; /* Colors! @@ -21,7 +21,6 @@ class ColorThemeMenu_Swirl extends ColorThemeMenu; colorNames(11)=MenuColor_ListFocus */ -var DeusExPlayer player; var int rgbAngle[15]; //One per theme segment // ---------------------------------------------------------------------- @@ -69,7 +68,7 @@ function Color GetColorFromAngle(int angle) return c; } -function UpdateAllColors() +function UpdateColours() { local int i; for (i=0;i<=13;i++){ @@ -81,35 +80,8 @@ function UpdateAllColors() } } -function Timer() -{ - UpdateAllColors(); -} - -function BeginPlay() -{ - local DeusExPlayer p; - Super.BeginPlay(); - foreach AllActors(class'DeusExPlayer',p){player = p; } - RandomAllAngles(); - SetTimer(0.1,true); -} defaultproperties { themeName="Swirl" - bSystemTheme=True - bAlwaysTick=True - Colors(0)=(R=0,G=0,B=0,A=0), - Colors(1)=(R=0,G=0,B=0,A=0), - Colors(2)=(R=0,G=0,B=0,A=0), - Colors(3)=(R=0,G=0,B=0,A=0), - Colors(4)=(R=0,G=0,B=0,A=0), - Colors(5)=(R=0,G=0,B=0,A=0), - Colors(6)=(R=0,G=0,B=0,A=0), - Colors(7)=(R=0,G=0,B=0,A=0), - Colors(8)=(R=0,G=0,B=0,A=0), - Colors(9)=(R=0,G=0,B=0,A=0), - Colors(10)=(R=0,G=0,B=0,A=0), - Colors(11)=(R=0,G=0,B=0,A=0), - Colors(12)=(R=0,G=0,B=0,A=0), + UpdateTime=0.1 } diff --git a/GUI/DeusEx/Classes/DXREnumList.uc b/GUI/DeusEx/Classes/DXREnumList.uc new file mode 100644 index 000000000..47a1285c0 --- /dev/null +++ b/GUI/DeusEx/Classes/DXREnumList.uc @@ -0,0 +1,101 @@ +class DXREnumList extends MenuUIScreenWindow; + +var DXRMenuBase parent; +var MenuUIScrollAreaWindow winScroll; +var Window controlsParent; + +var int iEnum; +var int button_y_pos, x_pad, y_pad; + +function CreateControls() +{ + Super.CreateControls(); + + winClient.SetBackground(Texture'MaskTexture'); // Texture'Solid' + winClient.SetBackgroundStyle(DSTY_Normal); + winClient.SetTileColorRGB(0,0,0); + + winScroll = CreateScrollAreaWindow(winClient); + winScroll.vScale.SetThumbStep(20); + winScroll.SetPos(0, 0); + winScroll.SetSize(ClientWidth, ClientHeight); + winScroll.AutoHideScrollbars(false); + winScroll.EnableScrolling(false,true); + controlsParent = winScroll.clipWindow; + controlsParent = controlsParent.NewChild(class'MenuUIClientWindow'); + + winScroll.vScale.SetTickPosition(0); +} + +function Init(DXRMenuBase newparent, int NewiEnum, string title, string helptext, string current_value) +{ + parent = newparent; + iEnum = NewiEnum; + if(title != "") { + SetTitle(title); + } + if(helptext != "") { + CreateLabel(helptext); + } + if(current_value != "") { + CreateLabel("Current Selection: " $ current_value); + } +} + +function Finalize() +{ + winScroll.AutoHideScrollbars(true); +} + +function MenuUILabelWindow CreateLabel(string label) +{ + local MenuUILabelWindow winLabel; + winLabel = CreateMenuLabel(x_pad, button_y_pos, label, controlsParent); + winLabel.SetWidth(controlsParent.width - x_pad*2); + button_y_pos += winLabel.height + y_pad; + return winLabel; +} + +function AddButton(string text) +{ + local MenuUIActionButtonWindow btn; + + btn = MenuUIActionButtonWindow(controlsParent.NewChild(Class'MenuUIActionButtonWindow')); + btn.SetButtonText(text); + btn.SetPos(x_pad, button_y_pos); + button_y_pos += btn.height + y_pad; + btn.SetWidth(controlsParent.width - x_pad*2); + + if(button_y_pos > controlsParent.height) { + controlsParent.SetHeight(button_y_pos); + } + winScroll.vScale.SetTickPosition(0); +} + + +function bool ButtonActivated( Window buttonPressed ) +{ + local MenuUIActionButtonWindow button; + + button = MenuUIActionButtonWindow(buttonPressed); + if(button == None) { + return Super.ButtonActivated(buttonPressed); + } + + //SetTitle(button.buttonText); + parent.SetEnumValue(iEnum, button.buttonText); + root.PopWindow(); + return true; +} + +defaultproperties +{ + actionButtons(0)=(Align=HALIGN_Right,Action=AB_Cancel,Text="|&Cancel",Key="CANCEL") + //actionButtons(1)=(Align=HALIGN_Right,Action=AB_Other,Text="|&Open In Browser",Key="OPEN") + Title="Choose Option" + ClientWidth=400 + ClientHeight=350 + button_y_pos=20 + x_pad=20 + y_pad=10 +} diff --git a/GUI/DeusEx/Classes/DXRMenuScreenNewGame.uc b/GUI/DeusEx/Classes/DXRMenuScreenNewGame.uc index 5349d4ce3..1f076de5a 100644 --- a/GUI/DeusEx/Classes/DXRMenuScreenNewGame.uc +++ b/GUI/DeusEx/Classes/DXRMenuScreenNewGame.uc @@ -17,7 +17,7 @@ static function bool HasLDDPInstalled() local DeusExTextParser parser; local bool opened; - if(!#defined(injections)) return false;// just to be safe if you have a lot of mods installed in the same folder + if(!#defined(injections)) return false;// just to be safe if you have a lot of mods installed in the same folder, Revision and VMD still allow selecting FemJC if(default.hasCheckedLDDP) { return default.bFemaleEnabled; @@ -40,10 +40,10 @@ event InitWindow() { local int i; - Super(MenuUIScreenWindow).InitWindow(); - bFemaleEnabled = HasLDDPInstalled(); + Super(MenuUIScreenWindow).InitWindow(); + if (bFemaleEnabled) { TexPortraits[0] = Texture(DynamicLoadObject("FemJC.MenuPlayerSetupJCDentonMale_1", class'Texture', false)); diff --git a/GUI/DeusEx/Classes/DXRNews.uc b/GUI/DeusEx/Classes/DXRNews.uc index ce2eea30f..f7ffbbace 100644 --- a/GUI/DeusEx/Classes/DXRNews.uc +++ b/GUI/DeusEx/Classes/DXRNews.uc @@ -95,7 +95,7 @@ function Set(DXRTelemetry tele) function bool HasNews() { - if(!bool(player.ConsoleCommand("get MenuChoice_ShowNews enabled"))) + if(!class'MenuChoice_ShowNews'.default.enabled) return false; if(tel == None || tel.enabled == false) return false; if( tel.dxr.localURL == "DX" || tel.dxr.localURL == "DXONLY" ) return true; diff --git a/GUI/DeusEx/Classes/FrobDisplayWindow.uc b/GUI/DeusEx/Classes/FrobDisplayWindow.uc index 70745ae4e..84c382a18 100644 --- a/GUI/DeusEx/Classes/FrobDisplayWindow.uc +++ b/GUI/DeusEx/Classes/FrobDisplayWindow.uc @@ -5,11 +5,9 @@ var localized string msgShot; var localized string msgShots; var localized string msgHitPoints; +var DXRando dxr; + var transient bool inited; -var transient bool auto_codes; -var transient bool known_codes; -var transient bool show_keys; -var transient bool auto_weapon_mods; function DrawWindow(GC gc) { @@ -30,30 +28,13 @@ function DrawWindow(GC gc) function CheckSettings() { - local int codes_mode; - local DXRando dxr; if( player == None || player.FlagBase == None ) return; - inited = true; - - codes_mode = int(player.ConsoleCommand("get #var(package).MenuChoice_PasswordAutofill codes_mode")); - if( codes_mode == 2 ) { - auto_codes = true; - } else { - auto_codes = false; - } - if( codes_mode >= 1 ) { - known_codes = true; - } else { - known_codes = false; - } - - show_keys = bool(player.ConsoleCommand("get #var(package).MenuChoice_ShowKeys enabled")); foreach player.AllActors(class'DXRando',dxr){break;} if (dxr==None) return; - auto_weapon_mods = !dxr.flags.IsZeroRando() && bool(player.ConsoleCommand("get #var(package).MenuChoice_AutoWeaponMods enabled")); + inited = true; } function InitFlags() @@ -69,6 +50,28 @@ event StyleChanged() CheckSettings(); } +function bool GetAutoCodes() +{ + return class'MenuChoice_PasswordAutofill'.default.codes_mode == 2; + +} + +function bool GetKnownCodes() +{ + return class'MenuChoice_PasswordAutofill'.default.codes_mode >= 1; +} + +function bool GetShowKeys() +{ + return class'MenuChoice_ShowKeys'.default.enabled; +} + +function bool GetAutoWeaponMods() +{ + if (dxr==None) return False; + return !dxr.flags.IsZeroRando() && class'MenuChoice_AutoWeaponMods'.default.enabled; +} + static function GetActorBoundingBox(actor frobTarget, out vector centerLoc, out vector radius) { local Mover M; @@ -248,6 +251,10 @@ function string GetStrInfo(Actor a, out int numLines) return DeviceStrInfo(HackableDevices(a), numLines); else if ( #var(prefix)Computers(a) != None || #var(prefix)ATM(a) != None ) return ComputersStrInfo(#var(prefix)ElectronicDevices(a), numLines); + else if ( #var(prefix)Weapon(a)!=None ) + return WeaponStrInfo(#var(DeusExPrefix)Weapon(a),numLines); + else if ( #var(prefix)BeamTrigger(a)!=None || #var(prefix)LaserTrigger(a)!=None) + return LaserStrInfo(a,numLines); else if (!a.bStatic && player.bObjectNames) return OtherStrInfo(a, numLines); @@ -355,7 +362,7 @@ function string MoverStrInfo(Mover m, out int numLines) } } strInfo = msgLocked; - if (!(show_keys && keyAcq)) { + if (!(GetShowKeys() && keyAcq)) { numLines++; strInfo = strInfo $ CR() $ msgLockStr; if (dxMover.bPickable) @@ -378,7 +385,7 @@ function string MoverStrInfo(Mover m, out int numLines) } - if ( show_keys && dxMover.KeyIDNeeded != ''){ + if ( GetShowKeys() && dxMover.KeyIDNeeded != ''){ numLines++; if (keyAcq){ strInfo = strInfo $ CR() $ "KEY ACQUIRED"; @@ -417,7 +424,7 @@ function string DeviceStrInfo(HackableDevices device, out int numLines) strInfo = device.itemName; - if(!auto_codes || k==None || (auto_codes && k!=None && !k.bCodeKnown)){ + if(!GetAutoCodes() || k==None || (GetAutoCodes() && k!=None && !k.bCodeKnown)){ numLines++; strInfo = strInfo $ CR() $ msgHackStr; if (device.bHackable) @@ -435,18 +442,18 @@ function string DeviceStrInfo(HackableDevices device, out int numLines) if( k!=None && (k.bCodeKnown) ) { - if( auto_codes ) { + if( GetAutoCodes() ) { numLines++; strInfo = strInfo $ CR() $ "CODE KNOWN ("$k.validCode$")"; k.bHackable = False; k.msgNotHacked = "It's secure, but you already know the code!"; } - else if( known_codes ) { + else if( GetKnownCodes() ) { numLines++; strInfo = strInfo $ CR() $ "CODE KNOWN"; } } - else if( device.IsA('Keypad') && known_codes ) + else if( device.IsA('Keypad') && GetKnownCodes() ) { numLines++; strInfo = strInfo $ CR() $ "Unknown Code"; @@ -470,7 +477,7 @@ function string ComputersStrInfo(#var(prefix)ElectronicDevices d, out int numLin c = #var(prefix)Computers(d); a = #var(injectsprefix)ATM(d); - if( known_codes && c != None ) + if( GetKnownCodes() && c != None ) { if( #var(injectsprefix)ComputerPersonal(c) != None ) code_known = #var(injectsprefix)ComputerPersonal(c).HasKnownAccounts(); @@ -482,7 +489,7 @@ function string ComputersStrInfo(#var(prefix)ElectronicDevices d, out int numLin else strInfo = strInfo $ CR() $ "Unknown Password"; } - else if( known_codes && a != None ) + else if( GetKnownCodes() && a != None ) { if( a.HasKnownAccounts() ) strInfo = strInfo $ CR() $ "PIN Known"; @@ -492,14 +499,191 @@ function string ComputersStrInfo(#var(prefix)ElectronicDevices d, out int numLin return strInfo; } +function string WeaponStrInfo(#var(DeusExPrefix)Weapon w, out int numLines) +{ + local string strInfo; + local int dmg,compDmg,dmgDiff,compMode; + local string dmgDiffStr,fireRateDiffStr; + local float mod,fireRate,compFireRate,fireRateDiff; + local #var(DeusExPrefix)Weapon compW; + + // TODO: Maybe this should be a setting? + //0 = off + //1 = Compare to in-hand weapon + //2 = Compare to default values + compMode=1; + + numLines=1; + strInfo = w.itemName; + if (w.AmmoName != Class'DeusEx.AmmoNone' ) + strInfo = strInfo $ " (" $ w.PickupAmmoCount $ ")"; + + numLines++; //Damage + numLines++; //Fire rate + //Calculate the damage of the weapon you're looking at +#ifdef injections + dmg = DXRWeapon(w).GetDamage(true); + + if( class(w.ProjectileClass) != None && class(w.ProjectileClass).default.bExplodes==false ) + dmg /= float(DXRWeapon(w).GetNumHits()); + +#else + if (w.AreaOfEffect == AOE_Cone){ + if (w.bInstantHit) + { + dmg = w.HitDamage * 5; + }else{ + dmg = w.HitDamage * 3; + } + }else{ + dmg = w.HitDamage; + } + mod = 1.0 - w.GetWeaponSkill(); + dmg = mod * dmg; +#endif + fireRate = 1.0/w.ShotTime; + + //Calculate the damage of the weapon in your hand + if (#var(DeusExPrefix)Weapon(player.InHand)!=None && compMode==1){ + compW = #var(DeusExPrefix)Weapon(player.InHand); +#ifdef injections + compDmg = DXRWeapon(compW).GetDamage(true); + + if( class(compW.ProjectileClass) != None && class(compW.ProjectileClass).default.bExplodes==false ) + compDmg /= float(DXRWeapon(compW).GetNumHits()); +#else + if (compW.AreaOfEffect == AOE_Cone){ + if (compW.bInstantHit){ + compDmg = compW.HitDamage * 5; + }else{ + compDmg = compW.HitDamage * 3; + } + }else{ + compDmg = compW.HitDamage; + } + mod = 1.0 - compW.GetWeaponSkill(); + compDmg = mod * compDmg; +#endif + compFireRate = 1.0/compW.ShotTime; + } else if (compMode==2){ + //It's a lot more work to calculate the default weapon damage, + //since the convenience functions are all working with the configured + //values. I'm not bothering with that for right now. + //Maybe we could temporarily copy the default stats over to the actual weapon, + //run the calculations, then swap the stats back to the randomized ones, so + //that we could use the same calculations? + + compFireRate = 1.0/compW.Default.ShotTime; + } + + strInfo=strInfo $ CR() $"Damage: "$dmg; + + //Show the difference in damage with your current weapon + if (compDmg!=0){ + dmgDiff = dmg - compDmg; + dmgDiffStr = string(dmgDiff); + if (dmgDiff>0){ + dmgDiffStr="+"$dmgDiffStr; + } + + if (dmgDiff!=0){ + strInfo=strInfo$" ("$dmgDiffStr$")"; + } + } + + if (dxr!=None){ + strInfo=strInfo $ CR() $"Fire Rate: "$dxr.TruncateFloat(fireRate,1)$"/s"; + + if (compFireRate!=0){ + fireRateDiff = fireRate - compFireRate; + fireRateDiffStr = dxr.TruncateFloat(fireRateDiff,1); + if (fireRateDiff>0){ + fireRateDiffStr = "+"$fireRateDiffStr; + } + + if (fireRateDiff!=0){ + strInfo=strInfo$" ("$fireRateDiffStr$")"; + } + } + } + + return strInfo; + +} + +function string LaserStrInfo(Actor a, out int numLines) +{ + local #var(prefix)BeamTrigger bt; + local #var(prefix)LaserTrigger lt; + local int minDmg,hitpoints, numshots,damage; + local string strInfo,triggerName, numshotStr; +#ifdef vanilla + local DXRWeapon w; +#endif + + bt = #var(prefix)BeamTrigger(a); + lt = #var(prefix)LaserTrigger(a); + + if (bt!=None){ + triggerName="Laser Trap"; + minDmg = bt.minDamageThreshold; + hitpoints = bt.HitPoints; + } else if (lt!=None){ + triggerName="Alarm Laser"; + minDmg = lt.minDamageThreshold; + hitpoints = lt.HitPoints; + } else { + numLines=1; + return "SOME OTHER LASER ENDED UP IN HERE! REPORT AS BUG!"; + } + + numshotStr=""; +#ifdef vanilla + w = DXRWeapon(player.inHand); + if( w != None ) { + if (w.WeaponDamageType() != 'Exploded' && w.WeaponDamageType() != 'Shot'){ + damage = 0; //only exploded and shot damage actually hurt lasers + } else { + damage = w.GetDamage(); + if (damage 0 ) { + numshots = hitpoints/damage; + if (hitpoints % damage != 0){ + numshots++; + } + + if( numshots == 1 ) + numshotStr = " (" $ numshots @ msgShot $ ")"; + else + numshotStr = " (" $ numshots @ msgShots $ ")"; + } else { + numshotStr = " (" $ msgInf @ msgShots $ ")"; + } + } +#endif + + + numLines = 3; + strInfo = triggerName $ CR(); + strInfo = strInfo $ msgDamageThreshold @ minDmg $ CR(); + strInfo = strInfo $ msgHitPoints @ hitpoints $ numshotStr; + + return strInfo; +} + + function bool WeaponModAutoApply(WeaponMod wm) { if (wm==None) return False; if (player.InHand==None) return False; if (player.InHand.IsA('DeusExWeapon')==False) return False; if (wm.CanUpgradeWeapon(DeusExWeapon(player.InHand))==False) return False; - if (auto_weapon_mods==False) return False; - + if (GetAutoWeaponMods()==False) return False; return True; } @@ -582,7 +766,7 @@ function MoverDrawBars(GC gc, Mover m, float infoX, float infoY, float infoW, fl dxMover = DeusExMover(m); // draw colored bars for each value - if ((dxMover != None) && dxMover.bLocked && !(show_keys && keyAcq)) + if ((dxMover != None) && dxMover.bLocked && !(GetShowKeys() && keyAcq)) { gc.SetStyle(DSTY_Translucent); col = GetColorScaled(dxMover.lockStrength); @@ -594,7 +778,7 @@ function MoverDrawBars(GC gc, Mover m, float infoX, float infoY, float infoW, fl } // draw the absolute number of lockpicks on top of the colored bar - if ((dxMover != None) && dxMover.bLocked && dxMover.bPickable && !(show_keys && keyAcq)) + if ((dxMover != None) && dxMover.bLocked && dxMover.bPickable && !(GetShowKeys() && keyAcq)) { numTools = GetNumTools(dxMover.lockStrength, player.SkillSystem.GetSkillLevelValue(class'SkillLockpicking')); if (numTools == 1) @@ -604,7 +788,7 @@ function MoverDrawBars(GC gc, Mover m, float infoX, float infoY, float infoW, fl } #ifdef vanilla - if ((dxMover != None) && dxMover.bLocked && dxMover.bBreakable && !(show_keys && keyAcq)) + if ((dxMover != None) && dxMover.bLocked && dxMover.bBreakable && !(GetShowKeys() && keyAcq)) { w = DXRWeapon(player.inHand); if( w != None ) { @@ -624,7 +808,7 @@ function MoverDrawBars(GC gc, Mover m, float infoX, float infoY, float infoW, fl gc.DrawText(infoX+(infoW-barLength-2), infoY+4+(infoH-8)/numLines, barLength, ((infoH-8)/numLines)*2-2, strInfo); //Put a green or red bar next to key status if the door is locked and has a key - if (show_keys && dxMover.bLocked && dxMover.KeyIDNeeded != ''){ + if (GetShowKeys() && dxMover.bLocked && dxMover.KeyIDNeeded != ''){ gc.SetStyle(DSTY_Translucent); col.r = 0; col.g = 0; @@ -660,10 +844,10 @@ function DeviceDrawBars(GC gc, HackableDevices device, float infoX, float infoY, #endif // Alignment changes based on the number of lines? - if ((auto_codes || known_codes) && k!=None){ + if ((GetAutoCodes() || GetKnownCodes()) && k!=None){ infoY += 2; } - if(!auto_codes || k==None || (auto_codes && k!=None && !k.bCodeKnown)){ + if(!GetAutoCodes() || k==None || (GetAutoCodes() && k!=None && !k.bCodeKnown)){ // draw a colored bar if (device.hackStrength != 0.0) { @@ -685,7 +869,7 @@ function DeviceDrawBars(GC gc, HackableDevices device, float infoX, float infoY, } } - if (auto_codes && k!=None){ + if (GetAutoCodes() && k!=None){ gc.SetStyle(DSTY_Translucent); col.r = 0; col.g = 0; diff --git a/GUI/DeusEx/Classes/HUDEnergyDisplay.uc b/GUI/DeusEx/Classes/HUDEnergyDisplay.uc index 55c8ec954..109d49f26 100644 --- a/GUI/DeusEx/Classes/HUDEnergyDisplay.uc +++ b/GUI/DeusEx/Classes/HUDEnergyDisplay.uc @@ -199,7 +199,7 @@ function SetVisibility( bool bNewVisibility ) function bool IsDisabled() { - return bool(player.ConsoleCommand("get #var(package).MenuChoice_EnergyDisplay bEnergyDisplayHidden")); + return class'MenuChoice_EnergyDisplay'.default.bEnergyDisplayHidden; } // ---------------------------------------------------------------------- diff --git a/GUI/DeusEx/Classes/HUDMedBotAddAugsScreen.uc b/GUI/DeusEx/Classes/HUDMedBotAddAugsScreen.uc index 699cabbe6..6ef86ed01 100644 --- a/GUI/DeusEx/Classes/HUDMedBotAddAugsScreen.uc +++ b/GUI/DeusEx/Classes/HUDMedBotAddAugsScreen.uc @@ -1,13 +1,9 @@ -#ifdef injections class DXRHUDMedBotAddAugsScreen injects HUDMedBotAddAugsScreen; -#elseif hx -class DXRHUDMedBotAddAugsScreen extends HXPersonaScreenAugmentationsMedBot; -#else -class DXRHUDMedBotAddAugsScreen extends HUDMedBotAddAugsScreen; -#endif var PersonaActionButtonWindow btnRemove; +function CreateMedbotLabel() {} + function CreateButtons() { local PersonaButtonBarWindow winActionButtons; @@ -19,13 +15,8 @@ function CreateButtons() btnRemove = PersonaActionButtonWindow(winActionButtons.NewChild(Class'DXRPersonaActionButtonWindow')); btnRemove.SetButtonText("|&Remove"); -#ifdef hx - InstallButton = PersonaActionButtonWindow(winActionButtons.NewChild(Class'DXRPersonaActionButtonWindow')); - InstallButton.SetButtonText(InstallButtonLabel); -#else btnInstall = PersonaActionButtonWindow(winActionButtons.NewChild(Class'DXRPersonaActionButtonWindow')); btnInstall.SetButtonText(InstallButtonLabel); -#endif } function EnableButtons() @@ -52,11 +43,7 @@ function bool ButtonActivated(Window buttonPressed) RemoveAugmentation(); break; -#ifdef hx - case InstallButton: -#else case btnInstall: -#endif InstallAugmentation(); break; default: @@ -72,7 +59,6 @@ function bool ButtonActivated(Window buttonPressed) return bHandled; } - function RemoveAugmentation() { class'DXRAugmentations'.static.RemoveAug(player,selectedAug); @@ -97,7 +83,6 @@ function RemoveAugmentation() return; } - function DestroyAugmentationButtons() { local int buttonIndex,highlightIndex; @@ -113,6 +98,17 @@ function DestroyAugmentationButtons() for(highlightIndex=0;highlightIndex 0){ if (dxrMissions.MapHasGoalMarkers(image.class)){ - btnShowSpoilers.Show(True); + if (dxrMissions.dxr.flags.settings.spoilers==1){ + btnShowSpoilers.Show(True); + } btnGoalLocations.Show(True); } } - + Super.EnableButtons(); } @@ -200,7 +229,6 @@ function ClearViewedImageFlags() } } - function MarkViewed(DataVaultImage newImage) { local string bingoName; @@ -221,8 +249,18 @@ function MarkViewed(DataVaultImage newImage) newImage.bPlayerViewedImage = True; } } + +function SetImage(DataVaultImage newImage) +{ + class'#var(injectsprefix)DataVaultImage'.static.UpdateDataVaultImageTextures(newImage); + Super.SetImage(newImage); +} + + defaultproperties { - GoalSpoilersText="Goal |&Spoilers" - GoalLocationsText="Goal |&Locations" + GoalSpoilersText="Goal S|&poilers" + GoalLocationsText="Goal Loca|&tions" + GoalSpoilerWindowHeader="Spoilers?" + GoalSpoilerWindowText="Do you want to see spoilers for the goal randomization? This will impact your score! Click Goal Locations instead if you don't want to hurt your score." } diff --git a/HXRandomizer.u b/HXRandomizer.u index d227b9ca3..f96cfb298 100644 Binary files a/HXRandomizer.u and b/HXRandomizer.u differ diff --git a/Pawns/DeusEx/Classes/DXRSecurityBot4.uc b/Pawns/DeusEx/Classes/DXRSecurityBot4.uc new file mode 100644 index 000000000..6b142b3cb --- /dev/null +++ b/Pawns/DeusEx/Classes/DXRSecurityBot4.uc @@ -0,0 +1,47 @@ +//============================================================================= +// DXRSecurityBot4. +//============================================================================= +class DXRSecurityBot4 extends #var(prefix)SecurityBot3; + +function bool Facelift(bool bOn) +{ + return false; +} + +//SecurityBot3 modifies the skin in here, so skip over that +function BeginPlay() +{ + Super(Robot).BeginPlay(); +} + +defaultproperties +{ + SpeechTargetAcquired=Sound'DeusExSounds.Robot.SecurityBot3TargetAcquired' + SpeechTargetLost=Sound'DeusExSounds.Robot.SecurityBot3TargetLost' + SpeechOutOfAmmo=Sound'DeusExSounds.Robot.SecurityBot3OutOfAmmo' + SpeechCriticalDamage=Sound'DeusExSounds.Robot.SecurityBot3CriticalDamage' + SpeechScanning=Sound'DeusExSounds.Robot.SecurityBot3Scanning' + WalkingSpeed=1.000000 + bEmitDistress=True + InitialInventory(0)=(Inventory=Class'DeusEx.WeaponRobotMachinegun') + InitialInventory(1)=(Inventory=Class'DeusEx.Ammo762mm',Count=50) + GroundSpeed=95.000000 + WaterSpeed=50.000000 + AirSpeed=144.000000 + AccelRate=500.000000 + Health=150 + UnderWaterTime=20.000000 + AttitudeToPlayer=ATTITUDE_Ignore + DrawType=DT_Mesh + Mesh=LodMesh'DeusExCharacters.SecurityBot4' + SoundRadius=16 + SoundVolume=128 + AmbientSound=Sound'DeusExSounds.Robot.SecurityBot4Move' + CollisionRadius=27.500000 + CollisionHeight=28.500000 + Mass=1000.000000 + Buoyancy=100.000000 + BindName="SecurityBot4" + FamiliarName="Security Bot" + UnfamiliarName="Security Bot" +} diff --git a/Pawns/DeusEx/Classes/LeMerchantCarcass.uc b/Pawns/DeusEx/Classes/LeMerchantCarcass.uc index 8c1c7a0b4..2bbb3fd3b 100644 --- a/Pawns/DeusEx/Classes/LeMerchantCarcass.uc +++ b/Pawns/DeusEx/Classes/LeMerchantCarcass.uc @@ -1,7 +1,7 @@ //============================================================================= // LeMerchantCarcass //============================================================================= -class LeMerchantCarcass extends #var(prefix)Businessman3Carcass; +class LeMerchantCarcass extends MerchantCarcass; defaultproperties { diff --git a/Pawns/DeusEx/Classes/Merchant.uc b/Pawns/DeusEx/Classes/Merchant.uc index eb856e318..7631436f2 100644 --- a/Pawns/DeusEx/Classes/Merchant.uc +++ b/Pawns/DeusEx/Classes/Merchant.uc @@ -31,6 +31,7 @@ function bool FilterDamageType(Pawn instigatedBy, Vector hitLocation, defaultproperties { + CarcassType=Class'MerchantCarcass' bImportant=True bDetectable=false bIgnore=true diff --git a/Pawns/DeusEx/Classes/MerchantCarcass.uc b/Pawns/DeusEx/Classes/MerchantCarcass.uc new file mode 100644 index 000000000..14c0a31af --- /dev/null +++ b/Pawns/DeusEx/Classes/MerchantCarcass.uc @@ -0,0 +1,11 @@ +//============================================================================= +// MerchantCarcass +//============================================================================= +class MerchantCarcass extends #var(prefix)Businessman3Carcass; + +defaultproperties +{ +#ifdef injections + dropsAmmo=true +#endif +} diff --git a/Pawns/DeusEx/Classes/NSFThugMale.uc b/Pawns/DeusEx/Classes/NSFThugMale.uc new file mode 100644 index 000000000..31fdd53b9 --- /dev/null +++ b/Pawns/DeusEx/Classes/NSFThugMale.uc @@ -0,0 +1,29 @@ +//============================================================================= +// NSFThugMale. +//============================================================================= +class NSFThugMale extends DXRTerroristBase; + +defaultproperties +{ + CarcassType=Class'DeusEx.ThugMaleCarcass' + WalkingSpeed=0.213333 + BaseAssHeight=-23.000000 + InitialInventory(0)=(Inventory=Class'DeusEx.WeaponPistol') + InitialInventory(1)=(Inventory=Class'DeusEx.Ammo10mm',Count=6) + InitialInventory(2)=(Inventory=Class'DeusEx.WeaponCrowbar') + GroundSpeed=180.000000 + Mesh=LodMesh'DeusExCharacters.GM_Trench' + MultiSkins(0)=Texture'DeusExCharacters.Skins.ThugMaleTex0' + MultiSkins(1)=Texture'DeusExCharacters.Skins.ThugMaleTex2' + MultiSkins(2)=Texture'DeusExCharacters.Skins.ThugMaleTex3' + MultiSkins(3)=Texture'DeusExCharacters.Skins.ThugMaleTex0' + MultiSkins(4)=Texture'DeusExCharacters.Skins.ThugMaleTex1' + MultiSkins(5)=Texture'DeusExItems.Skins.PinkMaskTex' + MultiSkins(6)=Texture'DeusExItems.Skins.GrayMaskTex' + MultiSkins(7)=Texture'DeusExItems.Skins.BlackMaskTex' + CollisionRadius=20.000000 + CollisionHeight=47.500000 + BindName="Thug" + FamiliarName="Thug" + UnfamiliarName="Thug" +} diff --git a/Pawns/DeusEx/Classes/NSFThugMale2.uc b/Pawns/DeusEx/Classes/NSFThugMale2.uc new file mode 100644 index 000000000..88c85bc2e --- /dev/null +++ b/Pawns/DeusEx/Classes/NSFThugMale2.uc @@ -0,0 +1,29 @@ +//============================================================================= +// NSFThugMale2. +//============================================================================= +class NSFThugMale2 extends DXRTerroristBase; + +defaultproperties +{ + CarcassType=Class'DeusEx.ThugMale2Carcass' + WalkingSpeed=0.296000 + InitialInventory(0)=(Inventory=Class'DeusEx.WeaponPistol') + InitialInventory(1)=(Inventory=Class'DeusEx.Ammo10mm',Count=6) + InitialInventory(2)=(Inventory=Class'DeusEx.WeaponCrowbar') + walkAnimMult=0.800000 + GroundSpeed=200.000000 + Mesh=LodMesh'DeusExCharacters.GM_DressShirt' + MultiSkins(0)=Texture'DeusExCharacters.Skins.ThugMale2Tex0' + MultiSkins(1)=Texture'DeusExItems.Skins.PinkMaskTex' + MultiSkins(2)=Texture'DeusExItems.Skins.PinkMaskTex' + MultiSkins(3)=Texture'DeusExCharacters.Skins.ThugMale2Tex2' + MultiSkins(4)=Texture'DeusExCharacters.Skins.ThugMale2Tex0' + MultiSkins(5)=Texture'DeusExCharacters.Skins.ThugMale2Tex1' + MultiSkins(6)=Texture'DeusExItems.Skins.GrayMaskTex' + MultiSkins(7)=Texture'DeusExItems.Skins.BlackMaskTex' + CollisionRadius=20.000000 + CollisionHeight=47.500000 + BindName="Thug" + FamiliarName="Thug" + UnfamiliarName="Thug" +} diff --git a/Pawns/DeusEx/Classes/NSFThugMale3.uc b/Pawns/DeusEx/Classes/NSFThugMale3.uc new file mode 100644 index 000000000..b33c464c8 --- /dev/null +++ b/Pawns/DeusEx/Classes/NSFThugMale3.uc @@ -0,0 +1,27 @@ +//============================================================================= +// NSFThugMale3. +//============================================================================= +class NSFThugMale3 extends DXRTerroristBase; + +defaultproperties +{ + CarcassType=Class'DeusEx.ThugMale3Carcass' + WalkingSpeed=0.350000 + walkAnimMult=0.750000 + GroundSpeed=210.000000 + Texture=Texture'DeusExItems.Skins.BlackMaskTex' + Mesh=LodMesh'DeusExCharacters.GM_DressShirt_B' + MultiSkins(0)=Texture'DeusExCharacters.Skins.ThugMale3Tex1' + MultiSkins(1)=Texture'DeusExCharacters.Skins.ThugMale3Tex2' + MultiSkins(2)=Texture'DeusExCharacters.Skins.ThugMale3Tex0' + MultiSkins(3)=Texture'DeusExCharacters.Skins.ThugMale3Tex0' + MultiSkins(4)=Texture'DeusExCharacters.Skins.ThugMale3Tex3' + MultiSkins(5)=Texture'DeusExItems.Skins.GrayMaskTex' + MultiSkins(6)=Texture'DeusExItems.Skins.BlackMaskTex' + MultiSkins(7)=Texture'DeusExItems.Skins.BlackMaskTex' + CollisionRadius=20.000000 + CollisionHeight=47.500000 + BindName="ThugMale3" + FamiliarName="Thug" + UnfamiliarName="Thug" +} diff --git a/Pawns/DeusEx/Classes/NastyRat.uc b/Pawns/DeusEx/Classes/NastyRat.uc index 3c60b1186..9d77af5be 100644 --- a/Pawns/DeusEx/Classes/NastyRat.uc +++ b/Pawns/DeusEx/Classes/NastyRat.uc @@ -37,7 +37,7 @@ function Tick(float deltaSeconds) if (CheckTime < Level.TimeSeconds) { if (CheckTime == 0.0) { //Don't throw a grenade the moment we spawn... - NextThrowTime = Level.TimeSeconds + ThrowFrequency; + CalcNextThrowTime(); } CheckTime = Level.TimeSeconds + CheckFrequency; @@ -79,11 +79,16 @@ function Tick(float deltaSeconds) ThrowPoint = Location + vect(0,0,20); Aim = rotator(closestTarget.Location - ThrowPoint); Spawn(PickAGrenade(closestTarget),self,,ThrowPoint,Aim); - NextThrowTime = Level.TimeSeconds + ThrowFrequency; + CalcNextThrowTime(); } } } +function CalcNextThrowTime() +{ + NextThrowTime = Level.TimeSeconds + (ThrowFrequency * (float(Health)/float(Default.Health))); +} + function class PickAGrenade(Actor closestTarget) { local int i; @@ -139,7 +144,7 @@ defaultproperties CheckTime=0.00000 NextThrowTime=0.0000 ThrowFrequency=6.0 - CheckFrequency=2.0 + CheckFrequency=1.0 CollisionRadius=20.000000 CollisionHeight=17.50000 DrawScale=4.000000 @@ -160,8 +165,9 @@ defaultproperties MaxStepHeight=25.00000 BaseEyeHeight=3.000000 JumpZ=30.000000 - WalkingSpeed=1.0 - GroundSpeed=100.000000 + WalkingSpeed=1.5 + GroundSpeed=150.000000 + WalkAnimMult=1.5 WaterSpeed=24.000000 AirSpeed=60.000000 Mass=30.000 diff --git a/Pawns/DeusEx/Classes/PlaceholderEnemy.uc b/Pawns/DeusEx/Classes/PlaceholderEnemy.uc index 30203fec1..ab300b83d 100644 --- a/Pawns/DeusEx/Classes/PlaceholderEnemy.uc +++ b/Pawns/DeusEx/Classes/PlaceholderEnemy.uc @@ -1,12 +1,23 @@ class PlaceholderEnemy extends #var(prefix)ThugMale; -static function PlaceholderEnemy Create(DXRBase a, vector loc, optional int yaw, optional Name orders, optional Name ordertag, optional Name Alliance) +static function PlaceholderEnemy Create(DXRBase a, vector loc, optional int yaw, optional Name orders, optional Name ordertag, optional Name Alliance, optional float playerAllianceLevel) { local PlaceholderEnemy e; local rotator r; + + if (orders=='Shitting'){ + if (!a.IsAprilFools()){ + return None; + } + orders = 'Sitting'; + } + r = a.rotm(0, yaw, 0, 16384);// Pawns need an offset of 16384 e = a.Spawn(class'PlaceholderEnemy',,, loc, r); e.Alliance = Alliance; + if(playerAllianceLevel != 0) { + e.InitialAlliances[0].AllianceLevel = playerAllianceLevel; + } e.InitializeAlliances(); //Needed to populate Alliance table in time for enemy shuffling if(orders!='') { e.SetOrders(orders, ordertag, false); @@ -16,9 +27,18 @@ static function PlaceholderEnemy Create(DXRBase a, vector loc, optional int yaw, return e; } +function PostPostBeginPlay() +{ + Super.PostPostBeginPlay(); + + if(!class'DXRVersion'.static.VersionIsStable()) { + Mesh=LodMesh'DeusExItems.TestBox'; + } +} + defaultproperties { - Mesh=LodMesh'DeusExItems.TestBox' + Mesh=None InitialAlliances(0)=(AllianceName=Player,AllianceLevel=-1.000000) orders=DynamicPatrolling } diff --git a/RevRandomizer.u b/RevRandomizer.u index d3508bb9a..c1f5f47de 100644 Binary files a/RevRandomizer.u and b/RevRandomizer.u differ diff --git a/VMDRandomizer.u b/VMDRandomizer.u index 8264b927f..364a0671e 100644 Binary files a/VMDRandomizer.u and b/VMDRandomizer.u differ diff --git a/installer/Install/Install.py b/installer/Install/Install.py index 4a29ed853..504ef279e 100644 --- a/installer/Install/Install.py +++ b/installer/Install/Install.py @@ -152,7 +152,7 @@ def VanillaFixConfigs(system, exename, kentie, Vulkan, OGL2, speedupfix, sourceI oldconfig = DXRandoini.read_text() oldconfig = Config.ReadConfig(oldconfig) changes = Config.RetainConfigSections( - set(('WinDrv.WindowsClient', 'DeusEx.DXRFlags', 'DeusEx.DXRTelemetry', 'Galaxy.GalaxyAudioSubsystem', 'DeusExe')), + set(('WinDrv.WindowsClient', 'DeusEx.DXRando', 'DeusEx.DXRFlags', 'DeusEx.DXRTelemetry', 'Galaxy.GalaxyAudioSubsystem', 'DeusExe')), oldconfig, changes ) elif not Vulkan and IsWindows(): diff --git a/installer/Install/__init__.py b/installer/Install/__init__.py index 088955372..edb48ce09 100644 --- a/installer/Install/__init__.py +++ b/installer/Install/__init__.py @@ -349,7 +349,7 @@ def MD5(bytes:bytes) -> str: return ret -def DownloadFile(url, dest, callback): +def DownloadFile(url, dest, callback=None): # still do this on dryrun because it writes to temp? sslcontext = ssl.create_default_context(cafile=certifi.where()) old_func = ssl._create_default_https_context diff --git a/installer/build.py b/installer/build.py new file mode 100644 index 000000000..430bfa01a --- /dev/null +++ b/installer/build.py @@ -0,0 +1,96 @@ +# -*- mode: python ; coding: utf-8 -*- +from pathlib import Path +import re +import os +from Install import DownloadFile, WriteBytes +from zipfile import ZipFile +import tarfile +import PyInstaller.__main__ + +Community_Update_url = "https://github.com/Defaultplayer001/Deus-Ex-Universe-Community-Update-/raw/a662f6ed177dba52ad3a0d8141fa2ac72f8af034/%5B1.0%5D%20Deus%20Ex%20-%20Windows-Linux-macOS-Android/" +downloads = { + # Launchers + "DXCU%20Installer%20Source/Mods/Community%20Update/System/Alternative%20EXEs/Kentie's%20DeusExe.exe": "KentieDeusExe.exe", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/DeusExe.u": "DeusExe.u", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/Alternative%20EXEs/Launch.exe": "Launch.exe", + + # Renderers + "DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.dll": "D3D9Drv.dll", + # "DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.hut": "D3D9Drv.hut", + # "DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D9Drv.int": "D3D9Drv.int", + + "CommunityUpdateFileArchiveDXPC/OpenGL/dxglr21.zip": "dxglr21.zip", + + # D3D10 + "DXCU%20Installer%20Source/Mods/Community%20Update/System/D3D10Drv.int": "D3D10Drv.int", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv.dll": "d3d10drv.dll", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/common.fxh": "d3d10drv/common.fxh", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/complexsurface.fx": "d3d10drv/complexsurface.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/finalpass.fx": "d3d10drv/finalpass.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/firstpass.fx": "d3d10drv/firstpass.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/fogsurface.fx": "d3d10drv/fogsurface.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/gouraudpolygon.fx": "d3d10drv/gouraudpolygon.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/hdr%20(original).fx": "d3d10drv/hdr.original.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/hdr.fx": "d3d10drv/hdr.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/polyflags.fxh": "d3d10drv/polyflags.fxh", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/postprocessing.fxh": "d3d10drv/postprocessing.fxh", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/states.fxh": "d3d10drv/states.fxh", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/tile.fx": "d3d10drv/tile.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/unreal_pom.fx": "d3d10drv/unreal_pom.fx", + "DXCU%20Installer%20Source/Mods/Community%20Update/System/d3d10drv/unrealpool.fxh": "d3d10drv/unrealpool.fxh", +} + +base = Path() + +if Path('installer/add_lib_path.py').exists(): + base = Path('installer') +elif Path('add_lib_path.py').exists(): + pass +else: + raise RuntimeError("Can't find root folder for installer") + +basedest = base / '3rdParty' + +basedest.mkdir(exist_ok=True) +(basedest/'d3d10drv').mkdir(exist_ok=True) +(basedest/'dxvk').mkdir(exist_ok=True) + +for (url, dest) in downloads.items(): + p = basedest/dest + if not p.exists(): + DownloadFile(Community_Update_url + url, basedest/dest) + +# TODO: unzip dxglr21.zip +zip = ZipFile(basedest/'dxglr21.zip', 'r') +zip.extractall(basedest) +zip.close() +(basedest/'dxglr21.zip').unlink() + + +# # LDDP minimal install +if not (basedest/'FemJC.u').exists(): + DownloadFile('https://github.com/LayDDentonProject/Lay-D-Denton-Project/releases/download/v1.1/FemJC.u', basedest/'FemJC.u') + +# DXVK 32bit +if not (basedest/'dxvk.tar.gz').exists(): + DownloadFile('https://github.com/doitsujin/dxvk/releases/download/v2.3/dxvk-2.3.tar.gz', basedest/'dxvk.tar.gz') +tar = tarfile.open(basedest/'dxvk.tar.gz') +for f in tar.getmembers(): + if '/x32/' in f.path and f.isfile(): + p = Path(f.name).name + p = basedest/'dxvk'/p + data = tar.extractfile(f).read() + WriteBytes(p, data) +tar.close() +(basedest/'dxvk.tar.gz').unlink() + +spec = base/'installer.spec' +print("building spec file:", spec) +(base/'dist').mkdir(exist_ok=True) +(base/'build').mkdir(exist_ok=True) +PyInstaller.__main__.run([ + #'--clean', + '--distpath=' + str(base/'dist'), + '--workpath=' + str(base/'build'), + str(spec), +]) diff --git a/notes/missiondistribution.py b/notes/missiondistribution.py index 8880fc342..d6d0e9802 100644 --- a/notes/missiondistribution.py +++ b/notes/missiondistribution.py @@ -2,7 +2,7 @@ mission=[] for i in range(0,16): - mission.append(0) + mission.append([]) def parseBingoLine(line): if "missions" in line: @@ -11,14 +11,14 @@ def parseBingoLine(line): for i in range(0,16): if(missionVal & 1): - mission[i]+=1 + mission[i].append(line) if (i==7 or i==13): print(line) missionVal = missionVal >> 1 - + else: - mission[0]+=1 - + mission[0].append(line) + f = open(eventfile) defprops=False @@ -31,9 +31,16 @@ def parseBingoLine(line): if "bingo_options" in line: parseBingoLine(line) -print("Any mission: "+str(mission[0])) + +for i in range(0,16): + print("##################") + print("Mission "+str(i)+": "+str(len(mission[i]))) + for g in mission[i]: + print(g) + +print("Any mission: "+str(len(mission[0]))) for i in range(1,16): - print("Mission "+str(i)+": "+str(mission[i])) + print("Mission "+str(i)+": "+str(len(mission[i]))) f.close()