1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-10-31 23:45:55 +00:00

Merge branch 'master' into MoreLanguages

# Conflicts:
#	src/core/Frontend.cpp
#	src/core/MenuScreens.h
#	src/render/Font.cpp
#	src/render/Font.h
#	src/text/Messages.cpp
#	src/text/Text.cpp
This commit is contained in:
Sergeanur 2020-04-26 22:03:15 +03:00
commit f0890b1112
350 changed files with 22460 additions and 16767 deletions

View file

@ -10,38 +10,17 @@ install:
- cmd: >- - cmd: >-
git submodule update --init --recursive git submodule update --init --recursive
premake-vs2019.cmd copy premake5.exe "librw/premake5.exe"
cd "librw" && premake5 vs2019 && msbuild "build/librw.sln" /property:Configuration=%CONFIGURATION% /property:Platform="win-x86-d3d9"
cd "%APPVEYOR_BUILD_FOLDER%" && premake5 vs2019
build: build:
project: build/re3.sln project: build/re3.sln
verbosity: minimal verbosity: minimal
after_build:
# downloading latest release of UAL to make release with UAL and ASI.
- ps: >-
$releases = "https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases"
$name = "Ultimate-ASI-Loader.zip"
$latestRelease = Invoke-WebRequest $releases/latest -Headers @{"Accept"="application/json"}
$json = $latestRelease.Content | ConvertFrom-Json
$latestVersion = $json.tag_name
$url = "$releases/download/$latestVersion/$name"
Start-FileDownload $url -FileName 'C:\Ultimate-ASI-Loader.zip'
7z e c:\Ultimate-ASI-Loader.zip -oc:\Projects\re3\bin\${env:CONFIGURATION}
cd "bin\${env:CONFIGURATION}"
copy re3.dll re3.asi
7z u "RE3_${env:CONFIGURATION}+UAL.zip" re3.asi dinput8.dll
Get-ChildItem .\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
artifacts: artifacts:
- path: bin/%CONFIGURATION%/re3.dll - path: bin/%CONFIGURATION%/re3.exe
name: re3.dll name: re3.exe
- path: bin/%CONFIGURATION%/re3.pdb - path: bin/%CONFIGURATION%/re3.pdb
name: re3.pdb name: re3.pdb

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "librw"]
path = librw
url = https://github.com/aap/librw

View file

@ -1,8 +1,8 @@
# re3 # re3
[![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master)
<a href="https://discord.gg/jYpXxTm"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a> <a href="https://discord.gg/jYpXxTm"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Debug/re3.dll?branch=master&job=Configuration%3A+Debug"><img src="https://img.shields.io/badge/download-debug-9cf.svg" /></a> <a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Debug/re3.exe?branch=master&job=Configuration%3A+Debug"><img src="https://img.shields.io/badge/download-debug-9cf.svg" /></a>
<a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Release/re3.dll?branch=master&job=Configuration%3A+Release"><img src="https://img.shields.io/badge/download-release-blue.svg" /></a> <a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Release/re3.exe?branch=master&job=Configuration%3A+Release"><img src="https://img.shields.io/badge/download-release-blue.svg" /></a>
## Intro ## Intro
@ -12,37 +12,24 @@ such that we have a working game at all times.
## How can I try it? ## How can I try it?
- re3 requires game assets to work, so you need to own a copy of GTA III. - re3 requires game assets to work, so you **must** own a copy of GTA III.
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
- Build re3 or download it from one of the above links (Debug or Release). - Build re3 or download it from one of the above links (Debug or Release).
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`. - (Optional) If you want to use optional features like Russian language or menu map, copy the files in /gamefiles folder to your game root folder.
- Move re3.exe to GTA 3 directory and run it.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it** > :information_source: **Rendering engine** re3 uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of re3, but you also can use LIBRW enviorenment variable to specify path to your own librw.
There are various settings at the very bottom of `config.h`, you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across. > :warning: **Notice for builders** There are various settings at the very bottom of `config.h`, you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
https://github.com/GTAmodding/re3/tree/master/src/core/config.h https://github.com/GTAmodding/re3/tree/master/src/core/config.h
## I want to contribute, where should I start? ## Contributing
A good approach is to start at the fringes of the code base,
i.e. classes that don't depend on code that we don't have reversed yet.
If a function uses only few unreversed functions that would be inconvenient
to reverse at the time, calling the original functions is acceptable.
### Unreversed / incomplete classes (at least the ones we know) ### Unreversed / incomplete classes (at least the ones we know)
```
CBulletInfo
CPedPath
CWeapon
CWorld
```
The following classes have only unused or practically unused code left: The following classes have only unused or practically unused code left:
``` ```
CCullZone - only mobile stuff CCullZone - only mobile stuff
CCullZones - only mobile stuff CCullZones - only mobile stuff
CSceneEdit
``` ```
### Coding style ### Coding style
@ -158,4 +145,5 @@ Here you can find a list of variables that you might need to set in windows:
``` ```
"GTA_III_RE_DIR" * path to "gta3_re" game folder usually where this plugin run. "GTA_III_RE_DIR" * path to "gta3_re" game folder usually where this plugin run.
"GTA_III_DIR" * path to "GTAIII" game folder. "GTA_III_DIR" * path to "GTAIII" game folder.
"LIBRW" * path to LIBRW.
``` ```

BIN
gamefiles/TEXT/american.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/french.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/german.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/italian.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/polish.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/russian.gxt Normal file

Binary file not shown.

BIN
gamefiles/TEXT/spanish.gxt Normal file

Binary file not shown.

363
gamefiles/data/PARTICLE.CFG Normal file
View file

@ -0,0 +1,363 @@
; Author: Alexander Roger
; Date: 21/12/2000
;
; Author: Andrzej Madajczyk
; Date: 26/02/2001
; 14/03/2001 - Alpha (opacity) support added;
; 10/05/2001 - Drag/Friction Decceleration changed to constants;
; 28/08/2001 - Initial Color Variation added;
;
;
;
;
; Note! Last line of the file MUST BE ";the end\n", otherwise you'll get parsing error(s) of the file;
;
;
;
;Particle Systems Configuration Data:: Format
;
;
;A: Particle Type Name (max 20 chars)
;
;B/C/D: Render Colouring (r,g,b) (0-255)
;
;CV: Initial Color Variation (for r,g,b only, in %) (0-100);
; (i.e. Color=(100,100,100) and CV=20, then v=random(-20,20), real_color=(100+v, 100+v, 100+v));
;
;
;
;B2/C2/D2: Fade Destination Color (r,g,b) (0-255)
;
;FT: Color Fade Time for (B,C,D)->(B2,C2,D2), (0 for none);
;
;
;
;
;E: Default Initial Radius (float)
;F: Expansion Rate (float)
;
;
; Color "Fade-to-Black" options:
;G: Initial Intensity (0-255)
;H: Fade Time (time between fade steps in frames)
;I: Fade Amount (-255 to 255) can get brighter or dimmer
;
; "Fade Alpha" options:
;GA: Initial Intensity (0-255)
;HA: Fade Time (time between fade steps in frames)
;IA: Fade Amount
;
; "Z Rotation" options:
;GZA: Initial Angle (0-1023)
;HZA: Change Time (time between steps in frames)
;IZA: Angle Change Amount
;
;GZR: Initial Z Radius
;HZR: Change Time (time between steps in frames)
;IZR: Z Radius Change Amount
;
;
;J: Animation Speed (0=no animation)(time between steps msec)
;K: Start Animation Frame ( 0 -> )
;L: Final Animation Frame ( H -> )
;
;
;M: Rotation Speed (0=None,i-deg/frame)
;N: Gravitational Acceleration (0=none, float)
;O: Drag/Friction Decceleration (int: 0=none, 50=0.50, 80=0.80, 90=0.90, 95=0.95, 96=0.96, 99=0.99)
;
;P: Default Life-Span of Particle (msec)
;
;Q: Position Random Error [position += (+/-)rand(a)]
;R: Velocity Random Error [velocity += (+/-)rand(b)]
;S: Expansion Rate Error [exp_rate += (+)rand(c)]
;T: Rotation Rate Error [rot_speed = (+/-)rand(d)]
;U: Life-Span Error Shape [shape distribution, e=0->all at default, e->Inf then shape->0] (max=255!!)
;V: Trail Length Multiplier [length *= (float) multiplier] (only used if trail flag active)
;
;CR:Particle Create Range (in meters: 0=no check); if particles are created enough far away from camera, they are deleted (not added to particle system);
;
;
;Z: Flags! Guide: 1=ZCHECK_FIRST, 2=ZCHECK_STEP, 4=DRAW_OPAQUE, 8=SCREEN_TRAIL,
; 16=SPEED_TRAIL, 32=RAND_VERT_V, 64=CYCLE_ANIM, 128=DRAW_DARK, 256=VERT_TRAIL
; 1024=DRAWTOP2D, 2048=CLIPOUT2D
; 4096=ZCHECK_BUMP, 8192=ZCHECK_BUMP_FIRST
;
;
;
;default:
;GUNFLASH 255 255 255 0 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
;
;good idea for fire-smudge?
;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
;
;current:
;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
;
;
;SPARK_SMALL 255 255 128 0 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.5 40
;
;
;
;
;
;
;
; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
;
SPARK 255 128 64 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 300 0.0 0.07 0.0 0 0 1.0 20.0 48
SPARK_SMALL 255 255 128 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 500 0.0 0.05 0.0 0 0 0.6 20.0 40
;
WHEEL_DIRT 8 24 8 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 30.0 4
;
;
;WHEEL_WATER 24 24 24 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 0
WHEEL_WATER 24 24 32 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.004 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 1
;
;
BLOOD 128 128 128 0 0 0 0 0 0.02 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.03 1 2000 0.3 0.05 0.0 0 0 1.0 50.0 5
BLOOD_SMALL 255 32 32 0 0 0 0 0 0.007 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.05 0.05 0.0 0 0 1.0 50.0 53
;BLOOD_SPLAT 128 128 128 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 200 0.3 0.0 0.0 0 0 1.0 400.0 36
BLOOD_SPURT 255 32 32 0 0 0 0 0 0.008 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.0 0.01 0.0 0 0 2.0 50.0 52
DEBRIS 64 64 64 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 95 1000 0.2 0.0 0.0 0 0 1.0 50.0 4
DEBRIS2 64 64 64 0 0 0 0 0 0.04 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 5 0.01 99 1000 0.03 0.04 0.0 0 0 1.0 50.0 38
WATER 64 64 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 2000 0.0 0.0 0.0 0 0 1.0 100.0 0
;
;
;FLAME 255 74 30 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 100 0.05 0.0 0.0 0 0 1.0 400.0 0
;FLAME 255 74 30 0 0 255 0 400 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
FLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
;
;
;
;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.04 255 1 8 255 0 0 0 0 0 0.0 0 0.0 32 0 7 0 0.0 96 1000 0.1 0.0 0.0 0 0 1.0 400.0 0
;
;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.05 255 0 6 255 0 0 0 0 0 0.0 0 0.0 1 0 7 0 -0.002 96 2000 0.1 0.02 0.02 3 0 1.0 200.0 0
FIREBALL 255 74 30 0 0 0 0 0 0.1 0.02 255 0 6 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.003 96 2000 0.1 0.03 0.014 2.5 0 1.0 200.0 0
;
;
;
GUNFLASH 170 170 170 0 0 0 0 0 0.1 0.0 255 1 50 255 0 0 0 0 0 0.0 0 0.0 51 0 3 0 0.0 1 250 0.0 0.0 0.0 0 0 1.0 35.0 0
GUNFLASH_NOANIM 128 128 128 0 0 0 0 0 0.1 0.0 255 1 128 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 25 0.0 0.0 0.0 0 0 1.0 35.0 0
;
GUNSMOKE 64 64 64 0 0 0 0 0 0.15 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 2 0 7 0 -0.002 95 1000 0.0 0.0 0.0 0 0 1.0 60.0 0
GUNSMOKE2 255 255 255 0 0 0 0 0 0.05 0.02 255 0 0 255 0 8 0 0 0 0.0 0 0.0 0 0 3 4 -0.001 80 1400 0.05 0.05 0.01 3 0 1.0 60.0 4
;
;
SMOKE 32 32 32 0 0 0 0 0 0.15 0.015 255 5 25 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.01 95 1000 0.05 0.05 0.01 3 0 1.0 150.0 0
;SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 255 5 15 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 1000 0.05 0.05 0.01 3 0 1.0 400.0 0
SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 128 5 11 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 3000 0.05 0.05 0.01 3 0 1.0 150.0 0
;
;
;
;GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.001 95 2000 0.05 0.05 0.01 3 0 1.0 400.0 0
GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.0005 95 4000 0.05 0.05 0.01 3 0 1.0 100.0 0
SHARD 255 255 255 0 0 0 0 0 0.03 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
SPLASH 64 64 128 0 0 0 0 0 0.1 0.007 255 1 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 100.0 0
;BLOOD_SPLASH 24 64 0 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
;
;
;CARFLAME 255 74 30 0 0 0 0 0 0.5 0.04 255 2 20 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 1000 0.4 0.0 0.0 0 0 1.0 400.0 64
;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
;
CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 100.0 0
;
;
STEAM 64 64 64 0 0 0 0 0 0.5 0.05 255 1 16 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 85.0 0
;
;default:
;STEAM2 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
STEAM2 255 255 255 0 0 0 0 0 0.5 0.015 255 0 0 192 0 1 0 0 10 0.5 1 0.02 32 0 4 0 -0.002 95 8000 0.01 0.03 0.0 0 0 1.0 85.0 4
;
;
;STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
STEAM_NY_SLOWMOTION 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.0015 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
;
;
;ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 2 16 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 250.0 4
ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 0 10 0 0 0 0.0 0 0.0 32 0 4 1 -0.005 95 4000 0.03 0.03 0.02 0 0 1.0 85.0 4
;
;
;RAINDROP 32 32 32 0 0 0 0 0 0.6 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.025 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
RAINDROP 64 64 64 0 0 0 0 0 0.4 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
RAINDROP_SMALL 16 16 16 0 0 0 0 0 0.3 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
RAIN_SPLASH 32 32 32 0 0 0 0 0 0.08 0.0 255 0 5 255 0 0 0 0 0 0.0 0 0.0 1 0 4 0 0.0 1 500 0.0 0.0 0.0 0 0 1.0 15.0 0
RAIN_SPLASH_BIGGROW 128 128 128 0 0 0 0 0 0.5 0.06 255 0 2 255 0 0 0 0 0 0.0 0 0.0 2 1 4 0 0.0 1 5500 0.0 0.0 0.0 0 0 1.0 15.0 0
RAIN_SPLASHUP 48 48 48 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 1 0 0.0 1 50 0.0 0.0 0.0 0 0 1.0 15.0 0
;
WATERSPRAY 64 64 64 0 0 0 0 0 0.2 0.0 255 0 25 255 0 0 0 0 0 0.0 0 0.0 3 0 2 0 0.002 1 800 0.05 0.0 0.01 0 0 1.0 20.0 0
;
;
;
;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.2 0.0 0.0 3 0 1.0 400.0 0
;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.8 0.0 0.0 3 0 1.0 400.0 0
;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.2 0.0 0.0 0 0 1.0 400.0 0
;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.8 0.0 0.0 0 0 1.0 400.0 0
;
;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 400.0 0
;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 400.0 0
EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 200.0 0
EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 200.0 0
EXPLOSION_MFAST 80 80 80 0 0 0 0 0 0.6 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.2 0.0 0.0 0 0 1.0 200.0 0
EXPLOSION_LFAST 80 80 80 0 0 0 0 0 1.1 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.8 0.0 0.0 0 0 1.0 200.0 0
;
;
;
;
;BOAT_SPLASH 32 64 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
;BOAT_THRUSTJET 24 32 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
;BOAT_SPLASH 16 32 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
;BOAT_THRUSTJET 8 24 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 250.0 0
;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.04 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.35 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.25 255 0 0 180 0 5 0 0 0 0.0 0 0.0 2 1 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 12
;
;
;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.15 255 0 0 180 0 2 0 0 0 0.0 0 0.0 2 0 3 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 12
;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.15 96 0 0 255 0 0 0 0 0 0.0 0 0.0 6 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.05 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
CAR_SPLASH 48 48 60 0 0 0 0 0 1.0 0.00 128 1 4 128 0 0 0 0 0 0.0 0 0.0 0 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 150.0 272
;
;
;
;BOAT_SPLASH 70 70 70 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
BOAT_SPLASH 64 64 64 0 0 0 0 0 0.2 0.2 255 0 2 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
;
;
;BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.8 0.1 255 0 0 120 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.4 0.06 255 0 0 96 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
;
;
;BOAT_WAKE 255 255 255 0 0 0 0 0 2.0 0.2 255 0 0 128 0 1 0 0 0 0.0 0 0.0 0 0 0 0 0.03 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
BOAT_WAKE 255 255 255 0 0 0 0 0 1.5 0.45 255 0 0 192 0 2 0 0 0 0.0 0 0.0 0 0 0 0 0.0 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
;
;
;
;
;
; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
WATER_HYDRANT 64 64 64 0 0 0 0 0 0.8 0.01 255 1 16 255 1 16 0 0 0 0.0 0 0.0 0 0 2 0 0.007 99 500 0.02 0.08 0.0 0 4 1.0 85.0 16
WATER_CANNON 64 64 128 0 0 0 0 0 0.03 0.03 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
EXTINGUISH_STEAM 32 32 32 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
;
;
;
;PED_SPLASH 32 32 64 0 0 0 0 0 0.1 0.05 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
PED_SPLASH 48 48 60 0 0 0 0 0 0.1 0.06 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 50.0 256
;
;
PEDFOOT_DUST 170 166 150 0 0 0 0 0 0.01 0.015 255 0 0 63 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0005 1 1000 0.0 0.0 0.0 0 0 1.0 6.0 4
;
HELI_DUST 17 15 9 0 0 0 0 0 0.2 0.1 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 1 1000 0.2 0.05 0.0 0 0 1.0 85.0 0
HELI_ATTACK 255 255 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 500 0.0 0.0 0.0 0 0 0.5 85.0 10
;
;
;ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 150.0 4
;ENGINE_SMOKE2 8 8 8 0 0 0 0 0 1.0 0.2 128 2 4 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 1000 0.0 0.0 0.0 0 3 1.0 150.0 4
ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 52 0 2 10 0 80 0.0 0 0.0 0 0 5 2 -0.009 95 2000 0.11 0.03 0.01 1 0 1.0 85.0 4
ENGINE_SMOKE2 9 9 9 80 0 0 0 0 1.0 0.06 128 0 1 140 0 5 10 0 80 0.0 0 0.0 0 0 0 2 0.002 1 1300 0.0 0.01 0.0 3 3 1.0 85.0 4
;
;
CARFLAME_SMOKE 32 32 32 0 0 0 0 0 0.05 0.01 255 0 0 64 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.008 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
FIREBALL_SMOKE 32 32 32 0 0 0 0 0 0.05 0.03 255 0 0 128 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.004 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
;
PAINT_SMOKE 255 0 0 0 0 0 0 0 0.1 0.01 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 95 3000 0.0 0.005 0.0 0 0 1.0 85.0 0
TREE_LEAVES 64 64 64 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
;
;
;CARCOLLISION_DUST 224 224 224 0 0 0 0 0 0.15 0.04 255 0 0 127 1 8 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 80.0 4
CARCOLLISION_DUST 76 76 76 0 0 0 0 0 0.10 0.02 255 0 0 160 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0015 90 2000 0.02 0.02 0.0 0 0 1.0 30.0 4
;
;
CAR_DEBRIS 32 32 32 0 0 0 0 0 0.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 50.0 4
HELI_DEBRIS 32 32 32 0 0 0 0 0 1.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.065 90 1500 0.02 0.02 0.0 0 0 1.0 150.0 4
;
;
;
;EXHAUST_FUMES 80 80 80 0 0 0 0 0 0.03 0.03 255 0 0 122 0 4 0 0 0 0.0 0 0.0 2 0 4 0 -0.001 95 1500 0.01 0.03 0.0 0 0 1.0 50.0 4
EXHAUST_FUMES 98 98 108 0 0 0 0 0 0.03 0.06 255 0 0 152 0 12 0 0 0 0.0 0 0.0 2 0 4 0 -0.002 96 1000 0.01 0.03 0.0 0 0 1.0 25.0 4
;
;
;RUBBER 40 40 40 0 0 0 0 0 0.4 0.005 255 21 20 255 0 0 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 400.0 4
RUBBER_SMOKE 255 255 255 0 0 0 0 0 0.4 0.005 255 0 0 127 1 8 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 50.0 4
;BURNINGRUBBER_SMOKE128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 192 1 6 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 4000 0.02 0.02 0.0 0 0 1.0 400.0 4
BURNINGRUBBER_SMOKE 128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 128 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 50.0 4
;
;
BULLETHIT_SMOKE 192 192 192 0 0 0 0 0 0.15 0.03 70 0 2 255 1 10 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 90 2000 0.04 0.02 0.0 0 0 1.0 150.0 0
;
;
GUNSHELL_FIRST 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 0.0 12292
GUNSHELL 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 12.0 4100
GUNSHELL_BUMP1 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 8.0 4100
GUNSHELL_BUMP2 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 400 0.02 0.02 0.0 0 0 1.0 8.0 4100
;
;
TEST 255 64 64 0 0 0 0 0 0.2 0.025 255 1 20 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 3000 0.0 0.0 0.0 0 0 1.0 400.0 128
;
;
;Particles with flag DRAWTOP2D should be placed last and VR (Visibility Range) set to 0!
;
;BIRD_FRONT 8 8 8 0 0 0 0 0 0.05 0.0 255 0 0 255 2 1 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 10000 0.0 0.0 0.0 0 0 1.0 0.0 3140
BIRD_FRONT 8 8 8 0 0 0 0 0 1.05 0.0 255 0 0 255 2 2 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 8000 0.0 0.0 0.0 0 0 1.0 0.0 68
;
RAINDROP_2D 32 32 32 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 0.0 3072
;
;
;
;
;
;
;
;
;
;
;
;
; below is just backup of above values:
;
;SPARK 255 128 64 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 300 0.0 0.07 0.0 0 0 1.0 48
;SPARK_SMALL 255 255 128 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.6 40
;BLOOD 128 128 128 0.02 0.0 255 0 0 0 0 0 0 0.03 1.0 2000 0.3 0.05 0.0 0 0 1.0 6
;BLOOD_SMALL 255 32 32 0.007 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.05 0.05 0.0 0 0 1.0 54
;BLOOD_SPLAT 128 128 128 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 200 0.3 0.0 0.0 0 0 1.0 36
;BLOOD_SPURT 255 32 32 0.008 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.0 0.01 0.0 0 0 2.0 52
;DEBRIS 64 64 64 0.5 0.0 255 0 0 0 0 0 0 0.01 0.95 1000 0.2 0.0 0.0 0 0 1.0 4
;DEBRIS2 64 64 64 0.04 0.0 255 0 0 0 0 0 5 0.01 0.99 1000 0.03 0.04 0.0 0 0 1.0 38
;WATER 64 64 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
;FLAME 255 74 30 0.2 0.0 255 0 0 31 0 5 0 0.0 1.0 100 0.05 0.0 0.0 0 0 1.0 0
;FIREBALL 255 74 30 0.1 0.04 255 0 8 31 0 8 0 0.0 0.96 1000 0.1 0.0 0.0 0 0 1.0 0
;GUNFLASH 255 255 255 0.1 0.0 255 0 50 50 0 3 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
;GUNFLASHSTATIC 255 255 255 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 25 0.0 0.0 0.0 0 0 1.0 0
;SMOKE 32 32 32 0.15 0.015 255 4 25 31 0 5 0 -0.01 0.95 1000 0.05 0.05 0.01 3 0 1.0 0
;SHARD 255 255 255 0.03 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
;SPLASH 64 64 128 0.1 0.007 255 0 10 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;BLOOD_SPLASH 24 64 0 0.1 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
;RUBBER 40 40 40 0.4 0.005 255 1 25 31 0 5 0 0.0 1.0 1000 0.02 0.0 0.0 0 0 1.0 0
;CARFLAME 255 74 30 0.5 0.04 255 1 20 31 0 5 0 0.0 1.0 1000 0.4 0.0 0.0 0 0 1.0 64
;STEAM 64 64 64 0.5 0.05 255 0 16 31 0 5 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 0
;RAINDROP 32 32 32 0.6 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
;RAIN_SPLASH 32 32 32 0.08 0.0 255 0 0 1 0 4 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;RAINDROP_SMALL 32 32 32 0.3 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
;EXPLOSION_MEDIUM 80 80 80 0.6 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.2 0.0 0.0 3 0 1.0 0
;EXPLOSION_LARGE 80 80 80 1.1 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.8 0.0 0.0 3 0 1.0 0
;BOAT_SPLASH 32 64 32 0.2 0.2 255 0 0 0 0 0 0 0.01 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
;BOAT_THRUSTJET 24 32 24 0.5 0.1 255 0 0 250 0 5 0 0.01 0.5 1000 0.0 0.0 0.0 0 4 1.0 8
;WATER_HYDRANT 64 64 128 0.4 0.01 255 1 2 20 0 5 0 0.007 0.99 500 0.02 0.05 0.0 0 4 1.0 256
;WATER_CANNON 64 64 128 0.03 0.03 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;EXTINGUISH_STEAM 32 32 32 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;PED_SPLASH 32 32 64 0.1 0.05 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;HELI_DUST 17 15 9 0.2 0.1 255 0 8 0 0 0 0 -0.001 1.0 1000 0.2 0.05 0.0 0 0 1.0 0
;HELI_ATTACK 255 255 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.0 0.0 0 0 0.5 10
;ENGINE_SMOKE 16 16 16 0.5 0.04 255 0 0 0 0 0 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 4
;ENGINE_SMOKE2 4 4 4 1.0 0.2 255 1 4 0 0 0 0 0.001 1.0 1000 0.0 0.0 0.0 0 3 1.0 4
;PAINT_SMOKE 255 0 0 0.1 0.01 255 0 8 0 0 0 0 0.0 0.95 3000 0.0 0.005 0.0 0 0 1.0 0
;TREE_LEAVES 64 64 64 0.2 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
;TEST 255 64 64 0.2 0.05 255 0 16 0 0 0 0 0.0 1.0 3000 0.0 0.0 0.0 0 0 1.0 128
;
;
;the end

Binary file not shown.

Binary file not shown.

1
librw Submodule

@ -0,0 +1 @@
Subproject commit 09b0b36e7de9866a92a504728f78c780c0d7b8e1

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -1,5 +1,7 @@
Librw = os.getenv("LIBRW") or "librw"
workspace "re3" workspace "re3"
configurations { "Debug", "Release", "ReleaseFH", "DebugRW", "ReleaseRW" } configurations { "Debug", "Release", "ReleaseFH", "DebugRW", "ReleaseRW", "ReleaseGLFW" }
location "build" location "build"
files { "src/*.*" } files { "src/*.*" }
@ -17,9 +19,11 @@ workspace "re3"
files { "src/save/*.*" } files { "src/save/*.*" }
files { "src/skel/*.*" } files { "src/skel/*.*" }
files { "src/skel/win/*.*" } files { "src/skel/win/*.*" }
files { "src/skel/glfw/*.*" }
files { "src/text/*.*" } files { "src/text/*.*" }
files { "src/vehicles/*.*" } files { "src/vehicles/*.*" }
files { "src/weapons/*.*" } files { "src/weapons/*.*" }
files { "src/extras/*.*" }
files { "eax/*.*" } files { "eax/*.*" }
includedirs { "src" } includedirs { "src" }
@ -37,23 +41,48 @@ workspace "re3"
includedirs { "src/save/" } includedirs { "src/save/" }
includedirs { "src/skel/" } includedirs { "src/skel/" }
includedirs { "src/skel/win" } includedirs { "src/skel/win" }
includedirs { "src/skel/glfw" }
includedirs { "src/text" } includedirs { "src/text" }
includedirs { "src/vehicles" } includedirs { "src/vehicles" }
includedirs { "src/weapons" } includedirs { "src/weapons" }
includedirs { "src/extras" }
includedirs { "eax" } includedirs { "eax" }
includedirs { "dxsdk/include" } includedirs { "dxsdk/include" }
includedirs { "rwsdk/include/d3d8" }
includedirs { "milessdk/include" } includedirs { "milessdk/include" }
includedirs { "eax" } includedirs { "eax" }
libdirs { "dxsdk/lib" } libdirs { "dxsdk/lib" }
libdirs { "milessdk/lib" } libdirs { "milessdk/lib" }
filter "configurations:DebugRW or configurations:ReleaseRW" filter "configurations:Debug or Release"
defines { "RWLIBS" } files { "src/fakerw/*.*" }
libdirs { "rwsdk/lib/d3d8/release" } includedirs { "src/fakerw" }
links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp" } includedirs { Librw }
libdirs { path.join(Librw, "lib/win-x86-d3d9/%{cfg.buildcfg}") }
links { "rw", "d3d9" }
filter {}
filter "configurations:DebugRW or ReleaseRW"
includedirs { "rwsdk/include/d3d8" }
libdirs { "rwsdk/lib/d3d8/release" }
links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse" }
filter {}
filter "configurations:ReleaseGLFW"
defines { "GLEW_STATIC", "GLFW_DLL" }
files { "src/fakerw/*.*" }
includedirs { "src/fakerw" }
includedirs { Librw }
includedirs { "glfw-3.3.2.bin.WIN32/include" }
includedirs { "glew-2.1.0/include" }
libdirs { path.join(Librw, "lib/win-x86-gl3/Release") }
libdirs { "glew-2.1.0/lib/Release/Win32" }
libdirs { "glfw-3.3.2.bin.WIN32/lib-vc2015" }
links { "opengl32" }
links { "glew32s" }
links { "glfw3dll" }
links { "rw" }
filter {} filter {}
pbcommands = { pbcommands = {
@ -63,7 +92,7 @@ workspace "re3"
"set filename=%%~ni", "set filename=%%~ni",
"set fileextension=%%~xi", "set fileextension=%%~xi",
"set target=!path!!filename!!fileextension!", "set target=!path!!filename!!fileextension!",
"if exist \"!target!\" copy /y \"!file!\" \"!target!\"", "copy /y \"!file!\" \"!target!\"",
")" } ")" }
function setpaths (gamepath, exepath, scriptspath) function setpaths (gamepath, exepath, scriptspath)
@ -83,43 +112,41 @@ workspace "re3"
end end
project "re3" project "re3"
kind "SharedLib" kind "WindowedApp"
language "C++" language "C++"
targetname "re3" targetname "re3"
targetdir "bin/%{cfg.buildcfg}" targetdir "bin/%{cfg.buildcfg}"
targetextension ".dll" targetextension ".exe"
characterset ("MBCS") characterset ("MBCS")
linkoptions "/SAFESEH:NO" linkoptions "/SAFESEH:NO"
filter "configurations:Debug" setpaths("$(GTA_III_RE_DIR)/", "$(TargetFileName)", "")
defines { "DEBUG" } symbols "Full"
staticruntime "off"
filter "configurations:Debug or Release or ReleaseFH"
prebuildcommands { "cd \"../librw\" && premake5 " .. _ACTION .. " && msbuild \"build/librw.sln\" /property:Configuration=%{cfg.longname} /property:Platform=\"win-x86-d3d9\"" }
defines { "LIBRW", "RW_D3D9" }
filter "configurations:*RW"
defines { "RWLIBS" }
staticruntime "on" staticruntime "on"
symbols "Full" linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")
filter "configurations:Release" filter "configurations:*GLFW"
prebuildcommands { "cd \"../librw\" && premake5 " .. _ACTION .. " && msbuild \"build/librw.sln\" /property:Configuration=Release /property:Platform=\"win-x86-gl3\"" }
defines { "LIBRW", "RW_GL3" }
filter "configurations:Debug*"
defines { "DEBUG" }
filter "configurations:Release*"
defines { "NDEBUG" } defines { "NDEBUG" }
optimize "On" optimize "On"
staticruntime "on"
symbols "Full"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")
filter "configurations:ReleaseFH" filter "configurations:ReleaseFH"
defines { "NDEBUG" } prebuildcommands {}
symbols "Full"
optimize "off" optimize "off"
staticruntime "on" staticruntime "on"
targetextension ".asi"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "scripts/")
filter "configurations:DebugRW"
defines { "DEBUG" }
staticruntime "on"
symbols "On"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")
filter "configurations:ReleaseRW"
defines { "NDEBUG" }
optimize "On"
staticruntime "on"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")

View file

@ -1,5 +1,7 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "ctype.h"
#include "General.h" #include "General.h"
#include "ModelInfo.h" #include "ModelInfo.h"
#include "AnimManager.h" #include "AnimManager.h"
@ -75,12 +77,21 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
c2 = *s2; c2 = *s2;
if(c1) s1++; if(c1) s1++;
if(c2) s2++; if(c2) s2++;
if(c1 == '\0' && c2 == '\0') if(c1 == '\0' && c2 == '\0') return true;
return true; #if defined _WIN32 && !defined __MINGW32__
if(__ascii_iswdigit(c1) && __ascii_iswdigit(c2)) if(__ascii_iswdigit(c1) && __ascii_iswdigit(c2))
#else
if(iswdigit(c1) && iswdigit(c2))
#endif
continue; continue;
#if defined _WIN32 && !defined __MINGW32__
c1 = __ascii_toupper(c1); c1 = __ascii_toupper(c1);
c2 = __ascii_toupper(c2); c2 = __ascii_toupper(c2);
#else
c1 = toupper(c1);
c2 = toupper(c2);
#endif
if(c1 != c2) if(c1 != c2)
return false; return false;
} }
@ -148,15 +159,3 @@ CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump,
} }
numAssociations = numAssocs; numAssociations = numAssocs;
} }
STARTPATCHES
InjectHook(0x4012D0, &CAnimBlendAssocGroup::DestroyAssociations, PATCH_JUMP);
InjectHook(0x4013D0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
InjectHook(0x401300, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
InjectHook(0x401420, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
InjectHook(0x4013E0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
InjectHook(0x401130, (void (CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
InjectHook(0x401220, (void (CAnimBlendAssocGroup::*)(const char*, RpClump*, const char**, int))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendHierarchy.h" #include "AnimBlendHierarchy.h"
#include "AnimBlendClumpData.h" #include "AnimBlendClumpData.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
@ -185,7 +185,7 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
if(blendAmount <= 0.0f && blendDelta < 0.0f){ if(blendAmount <= 0.0f && blendDelta < 0.0f){
// We're faded out and are not fading in // We're faded out and are not fading in
blendAmount = 0.0f; blendAmount = 0.0f;
blendDelta = max(0.0f, blendDelta); blendDelta = Max(0.0f, blendDelta);
if(flags & ASSOC_DELETEFADEDOUT){ if(flags & ASSOC_DELETEFADEDOUT){
if(callbackType == CB_FINISH || callbackType == CB_DELETE) if(callbackType == CB_FINISH || callbackType == CB_DELETE)
callback(this, callbackArg); callback(this, callbackArg);
@ -197,38 +197,8 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
if(blendAmount > 1.0f){ if(blendAmount > 1.0f){
// Maximally faded in, clamp values // Maximally faded in, clamp values
blendAmount = 1.0f; blendAmount = 1.0f;
blendDelta = min(0.0f, blendDelta); blendDelta = Min(0.0f, blendDelta);
} }
return true; return true;
} }
#include <new>
class CAnimBlendAssociation_ : public CAnimBlendAssociation
{
public:
CAnimBlendAssociation *ctor1(void) { return ::new (this) CAnimBlendAssociation(); }
CAnimBlendAssociation *ctor2(CAnimBlendAssociation &other) { return ::new (this) CAnimBlendAssociation(other); }
void dtor(void) { this->CAnimBlendAssociation::~CAnimBlendAssociation(); }
};
STARTPATCHES
InjectHook(0x4016A0, &CAnimBlendAssociation::AllocateAnimBlendNodeArray, PATCH_JUMP);
InjectHook(0x4016F0, &CAnimBlendAssociation::FreeAnimBlendNodeArray, PATCH_JUMP);
InjectHook(0x4017B0, &CAnimBlendAssociation::GetNode, PATCH_JUMP);
InjectHook(0x401560, (void (CAnimBlendAssociation::*)(RpClump*, CAnimBlendHierarchy*))&CAnimBlendAssociation::Init, PATCH_JUMP);
InjectHook(0x401620, (void (CAnimBlendAssociation::*)(CAnimBlendAssociation&))&CAnimBlendAssociation::Init, PATCH_JUMP);
InjectHook(0x4017E0, &CAnimBlendAssociation::SetBlend, PATCH_JUMP);
InjectHook(0x401820, &CAnimBlendAssociation::SetFinishCallback, PATCH_JUMP);
InjectHook(0x401800, &CAnimBlendAssociation::SetDeleteCallback, PATCH_JUMP);
InjectHook(0x401700, &CAnimBlendAssociation::SetCurrentTime, PATCH_JUMP);
InjectHook(0x401780, &CAnimBlendAssociation::SyncAnimation, PATCH_JUMP);
InjectHook(0x4017D0, &CAnimBlendAssociation::Start, PATCH_JUMP);
InjectHook(0x4031F0, &CAnimBlendAssociation::UpdateTime, PATCH_JUMP);
InjectHook(0x4032B0, &CAnimBlendAssociation::UpdateBlend, PATCH_JUMP);
InjectHook(0x401460, &CAnimBlendAssociation_::ctor1, PATCH_JUMP);
InjectHook(0x4014C0, &CAnimBlendAssociation_::ctor2, PATCH_JUMP);
InjectHook(0x401520, &CAnimBlendAssociation_::dtor, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendClumpData.h" #include "AnimBlendClumpData.h"
#include "RwHelper.h" #include "RwHelper.h"
@ -35,20 +35,3 @@ CAnimBlendClumpData::ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *
for(i = 0; i < numFrames; i++) for(i = 0; i < numFrames; i++)
cb(&frames[i], arg); cb(&frames[i], arg);
} }
#include <new>
class CAnimBlendClumpData_ : public CAnimBlendClumpData
{
public:
CAnimBlendClumpData *ctor(void) { return ::new (this) CAnimBlendClumpData(); }
void dtor(void) { this->CAnimBlendClumpData::~CAnimBlendClumpData(); }
};
STARTPATCHES
InjectHook(0x401880, &CAnimBlendClumpData_::ctor, PATCH_JUMP);
InjectHook(0x4018B0, &CAnimBlendClumpData_::dtor, PATCH_JUMP);
InjectHook(0x4018F0, &CAnimBlendClumpData::SetNumberOfFrames, PATCH_JUMP);
InjectHook(0x401930, &CAnimBlendClumpData::ForAllFrames, PATCH_JUMP);
ENDPATCHES

View file

@ -18,7 +18,7 @@ struct AnimBlendFrameData
#ifdef PED_SKIN #ifdef PED_SKIN
union { union {
RwFrame *frame; RwFrame *frame;
RpHAnimStdKeyFrame *hanimframe; RpHAnimStdKeyFrame *hanimFrame;
}; };
int32 nodeID; int32 nodeID;
#else #else
@ -50,4 +50,6 @@ public:
#endif #endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg); void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
}; };
#ifndef PED_SKIN
static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error"); static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error");
#endif

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendSequence.h" #include "AnimBlendSequence.h"
#include "AnimBlendHierarchy.h" #include "AnimBlendHierarchy.h"
@ -36,7 +36,7 @@ CAnimBlendHierarchy::CalcTotalTime(void)
float seqTime = 0.0f; float seqTime = 0.0f;
for(j = 0; j < sequences[i].numFrames; j++) for(j = 0; j < sequences[i].numFrames; j++)
seqTime += sequences[i].GetKeyFrame(j)->deltaTime; seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
totalTime = max(totalTime, seqTime); totalTime = Max(totalTime, seqTime);
} }
totalLength = totalTime; totalLength = totalTime;
} }
@ -72,13 +72,3 @@ CAnimBlendHierarchy::RemoveUncompressedData(void)
// useless // useless
compressed = 1; compressed = 1;
} }
STARTPATCHES
InjectHook(0x4019A0, &CAnimBlendHierarchy::Shutdown, PATCH_JUMP);
InjectHook(0x4019C0, &CAnimBlendHierarchy::SetName, PATCH_JUMP);
InjectHook(0x4019E0, &CAnimBlendHierarchy::CalcTotalTime, PATCH_JUMP);
InjectHook(0x401A80, &CAnimBlendHierarchy::RemoveQuaternionFlips, PATCH_JUMP);
InjectHook(0x401AB0, &CAnimBlendHierarchy::RemoveAnimSequences, PATCH_JUMP);
InjectHook(0x401AD0, &CAnimBlendHierarchy::Uncompress, PATCH_JUMP);
InjectHook(0x401B00, &CAnimBlendHierarchy::RemoveUncompressedData, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#include "AnimBlendNode.h" #include "AnimBlendNode.h"
@ -158,13 +158,3 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
trans = kf->translation * blend; trans = kf->translation * blend;
} }
} }
STARTPATCHES
InjectHook(0x401B10, &CAnimBlendNode::Init, PATCH_JUMP);
InjectHook(0x401B30, &CAnimBlendNode::Update, PATCH_JUMP);
InjectHook(0x401DC0, &CAnimBlendNode::NextKeyFrame, PATCH_JUMP);
InjectHook(0x4021B0, &CAnimBlendNode::FindKeyFrame, PATCH_JUMP);
InjectHook(0x401E70, &CAnimBlendNode::CalcDeltas, PATCH_JUMP);
InjectHook(0x401FE0, &CAnimBlendNode::GetCurrentTranslation, PATCH_JUMP);
InjectHook(0x402110, &CAnimBlendNode::GetEndTranslation, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendSequence.h" #include "AnimBlendSequence.h"
CAnimBlendSequence::CAnimBlendSequence(void) CAnimBlendSequence::CAnimBlendSequence(void)
@ -60,9 +60,3 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
last = frame->rotation; last = frame->rotation;
} }
} }
STARTPATCHES
InjectHook(0x402330, &CAnimBlendSequence::SetName, PATCH_JUMP);
InjectHook(0x402350, &CAnimBlendSequence::SetNumFrames, PATCH_JUMP);
InjectHook(0x4023A0, &CAnimBlendSequence::RemoveQuaternionFlips, PATCH_JUMP);
ENDPATCHES

View file

@ -1,6 +1,7 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "General.h" #include "General.h"
#include "RwHelper.h"
#include "ModelInfo.h" #include "ModelInfo.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "FileMgr.h" #include "FileMgr.h"
@ -10,12 +11,12 @@
#include "AnimBlendAssocGroup.h" #include "AnimBlendAssocGroup.h"
#include "AnimManager.h" #include "AnimManager.h"
CAnimBlock *CAnimManager::ms_aAnimBlocks = (CAnimBlock*)0x6F01A0; CAnimBlock CAnimManager::ms_aAnimBlocks[2];
CAnimBlendHierarchy *CAnimManager::ms_aAnimations = (CAnimBlendHierarchy*)0x70F430; CAnimBlendHierarchy CAnimManager::ms_aAnimations[250];
int32 &CAnimManager::ms_numAnimBlocks = *(int32*)0x885AF8; int32 CAnimManager::ms_numAnimBlocks;
int32 &CAnimManager::ms_numAnimations = *(int32*)0x8E2DD4; int32 CAnimManager::ms_numAnimations;
CAnimBlendAssocGroup *&CAnimManager::ms_aAnimAssocGroups = *(CAnimBlendAssocGroup**)0x8F583C; CAnimBlendAssocGroup *CAnimManager::ms_aAnimAssocGroups;
CLinkList<CAnimBlendHierarchy*> &CAnimManager::ms_animCache = *(CLinkList<CAnimBlendHierarchy*>*)0x9414DC; CLinkList<CAnimBlendHierarchy*> CAnimManager::ms_animCache;
AnimAssocDesc aStdAnimDescs[] = { AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_FLAG80 }, { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_FLAG80 },
@ -754,6 +755,11 @@ CAnimManager::LoadAnimFiles(void)
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims); group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++) for(j = 0; j < group->numAssociations; j++)
group->GetAnimation(j)->flags |= def->animDescs[j].flags; group->GetAnimation(j)->flags |= def->animDescs[j].flags;
#ifdef PED_SKIN
// forgot on xbox/android
if(IsClumpSkinned(clump))
RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
#endif
RpClumpDestroy(clump); RpClumpDestroy(clump);
} }
} }
@ -909,23 +915,3 @@ CAnimManager::RemoveLastAnimFile(void)
for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++) for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++)
ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences(); ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences();
} }
STARTPATCHES
InjectHook(0x403380, CAnimManager::Initialise, PATCH_JUMP);
InjectHook(0x4033B0, CAnimManager::Shutdown, PATCH_JUMP);
InjectHook(0x403410, CAnimManager::UncompressAnimation, PATCH_JUMP);
InjectHook(0x4034A0, CAnimManager::GetAnimationBlock, PATCH_JUMP);
InjectHook(0x4034F0, (CAnimBlendHierarchy *(*)(const char*, CAnimBlock*))CAnimManager::GetAnimation, PATCH_JUMP);
InjectHook(0x4035B0, CAnimManager::GetAnimGroupName, PATCH_JUMP);
InjectHook(0x4035C0, CAnimManager::CreateAnimAssociation, PATCH_JUMP);
InjectHook(0x4035E0, (CAnimBlendAssociation *(*)(AssocGroupId, AnimationId))CAnimManager::GetAnimAssociation, PATCH_JUMP);
InjectHook(0x403600, (CAnimBlendAssociation *(*)(AssocGroupId, const char*))CAnimManager::GetAnimAssociation, PATCH_JUMP);
InjectHook(0x403620, CAnimManager::AddAnimation, PATCH_JUMP);
InjectHook(0x4036A0, CAnimManager::AddAnimationAndSync, PATCH_JUMP);
InjectHook(0x403710, CAnimManager::BlendAnimation, PATCH_JUMP);
InjectHook(0x4038F0, CAnimManager::LoadAnimFiles, PATCH_JUMP);
InjectHook(0x403A10, (void (*)(const char *))CAnimManager::LoadAnimFile, PATCH_JUMP);
InjectHook(0x403A40, (void (*)(int, bool))CAnimManager::LoadAnimFile, PATCH_JUMP);
InjectHook(0x404320, CAnimManager::RemoveLastAnimFile, PATCH_JUMP);
ENDPATCHES

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "AnimBlendHierarchy.h" #include "AnimBlendHierarchy.h"
#include "AnimationId.h"
enum AssocGroupId enum AssocGroupId
{ {
@ -33,185 +34,6 @@ enum AssocGroupId
NUM_ANIM_ASSOC_GROUPS NUM_ANIM_ASSOC_GROUPS
}; };
enum AnimationId
{
ANIM_WALK,
ANIM_RUN,
ANIM_SPRINT,
ANIM_IDLE_STANCE,
ANIM_WALK_START,
ANIM_RUN_STOP,
ANIM_RUN_STOP_R,
ANIM_IDLE_CAM,
ANIM_IDLE_HBHB,
ANIM_IDLE_TIRED,
ANIM_IDLE_ARMED,
ANIM_IDLE_CHAT,
ANIM_IDLE_TAXI,
ANIM_KO_SHOT_FRONT1,
ANIM_KO_SHOT_FRONT2,
ANIM_KO_SHOT_FRONT3,
ANIM_KO_SHOT_FRONT4,
ANIM_KO_SHOT_FACE,
ANIM_KO_SHOT_STOM,
ANIM_KO_SHOT_ARML,
ANIM_KO_SHOT_ARMR,
ANIM_KO_SHOT_LEGL,
ANIM_KO_SHOT_LEGR,
ANIM_KD_LEFT,
ANIM_KD_RIGHT,
ANIM_KO_SKID_FRONT,
ANIM_KO_SPIN_R, // named left in VC
ANIM_KO_SKID_BACK,
ANIM_KO_SPIN_L, // named right in VC
ANIM_SHOT_FRONT_PARTIAL,
ANIM_SHOT_LEFT_PARTIAL,
ANIM_SHOT_BACK_PARTIAL,
ANIM_SHOT_RIGHT_PARTIAL,
ANIM_HIT_FRONT,
ANIM_HIT_LEFT,
ANIM_HIT_BACK,
ANIM_HIT_RIGHT,
ANIM_FLOOR_HIT,
ANIM_HIT_BODYBLOW,
ANIM_HIT_CHEST,
ANIM_HIT_HEAD,
ANIM_HIT_WALK,
ANIM_HIT_WALL,
ANIM_FLOOR_HIT_F,
ANIM_HIT_BEHIND,
ANIM_PUNCH_R,
ANIM_KICK_FLOOR,
ANIM_WEAPON_BAT_H,
ANIM_WEAPON_BAT_V,
ANIM_WEAPON_HGUN_BODY,
ANIM_WEAPON_AK_BODY,
ANIM_WEAPON_PUMP,
ANIM_WEAPON_SNIPER,
ANIM_WEAPON_THROW,
ANIM_WEAPON_THROWU,
ANIM_WEAPON_START_THROW,
ANIM_BOMBER,
ANIM_HGUN_RELOAD,
ANIM_AK_RELOAD,
ANIM_FPS_PUNCH,
ANIM_FPS_BAT,
ANIM_FPS_UZI,
ANIM_FPS_PUMP,
ANIM_FPS_AK,
ANIM_FPS_M16,
ANIM_FPS_ROCKET,
ANIM_FIGHT_IDLE,
ANIM_FIGHT2_IDLE,
ANIM_FIGHT_SH_F,
ANIM_FIGHT_BODYBLOW,
ANIM_FIGHT_HEAD,
ANIM_FIGHT_KICK,
ANIM_FIGHT_KNEE,
ANIM_FIGHT_LHOOK,
ANIM_FIGHT_PUNCH,
ANIM_FIGHT_ROUNDHOUSE,
ANIM_FIGHT_LONGKICK,
ANIM_FIGHT_PPUNCH,
ANIM_CAR_JACKED_RHS,
ANIM_CAR_LJACKED_RHS,
ANIM_CAR_JACKED_LHS,
ANIM_CAR_LJACKED_LHS,
ANIM_CAR_QJACK,
ANIM_CAR_QJACKED,
ANIM_CAR_ALIGN_LHS,
ANIM_CAR_ALIGNHI_LHS,
ANIM_CAR_OPEN_LHS,
ANIM_CAR_DOORLOCKED_LHS,
ANIM_CAR_PULLOUT_LHS,
ANIM_CAR_PULLOUT_LOW_LHS,
ANIM_CAR_GETIN_LHS,
ANIM_CAR_GETIN_LOW_LHS,
ANIM_CAR_CLOSEDOOR_LHS,
ANIM_CAR_CLOSEDOOR_LOW_LHS,
ANIM_CAR_ROLLDOOR,
ANIM_CAR_ROLLDOOR_LOW,
ANIM_CAR_GETOUT_LHS,
ANIM_CAR_GETOUT_LOW_LHS,
ANIM_CAR_CLOSE_LHS,
ANIM_CAR_ALIGN_RHS,
ANIM_CAR_ALIGNHI_RHS,
ANIM_CAR_OPEN_RHS,
ANIM_CAR_DOORLOCKED_RHS,
ANIM_CAR_PULLOUT_RHS,
ANIM_CAR_PULLOUT_LOW_RHS,
ANIM_CAR_GETIN_RHS,
ANIM_CAR_GETIN_LOW_RHS,
ANIM_CAR_CLOSEDOOR_RHS,
ANIM_CAR_CLOSEDOOR_LOW_RHS,
ANIM_CAR_SHUFFLE_RHS,
ANIM_CAR_LSHUFFLE_RHS,
ANIM_CAR_SIT,
ANIM_CAR_LSIT,
ANIM_CAR_SITP,
ANIM_CAR_SITPLO,
ANIM_DRIVE_L,
ANIM_DRIVE_R,
ANIM_DRIVE_LOW_L,
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
ANIM_CAR_GETOUT_RHS,
ANIM_CAR_GETOUT_LOW_RHS,
ANIM_CAR_CLOSE_RHS,
ANIM_CAR_HOOKERTALK,
ANIM_COACH_OPEN_L,
ANIM_COACH_OPEN_R,
ANIM_COACH_IN_L,
ANIM_COACH_IN_R,
ANIM_COACH_OUT_L,
ANIM_TRAIN_GETIN,
ANIM_TRAIN_GETOUT,
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
ANIM_VAN_OPEN_L,
ANIM_VAN_GETIN_L,
ANIM_VAN_CLOSE_L,
ANIM_VAN_GETOUT_L,
ANIM_VAN_OPEN,
ANIM_VAN_GETIN,
ANIM_VAN_CLOSE,
ANIM_VAN_GETOUT,
ANIM_GETUP1,
ANIM_GETUP2,
ANIM_GETUP3,
ANIM_GETUP_FRONT,
ANIM_JUMP_LAUNCH,
ANIM_JUMP_GLIDE,
ANIM_JUMP_LAND,
ANIM_FALL_FALL,
ANIM_FALL_GLIDE,
ANIM_FALL_LAND,
ANIM_FALL_COLLAPSE,
ANIM_EV_STEP,
ANIM_EV_DIVE,
ANIM_XPRESS_SCRATCH,
ANIM_ROAD_CROSS,
ANIM_TURN_180,
ANIM_ARREST_GUN,
ANIM_DROWN,
ANIM_CPR,
ANIM_DUCK_DOWN,
ANIM_DUCK_LOW,
ANIM_RBLOCK_CSHOOT,
ANIM_WEAPON_THROWU2,
ANIM_HANDSUP,
ANIM_HANDSCOWER,
ANIM_FUCKU,
ANIM_PHONE_IN,
ANIM_PHONE_OUT,
ANIM_PHONE_TALK,
NUM_ANIMS
};
class CAnimBlendAssociation; class CAnimBlendAssociation;
class CAnimBlendAssocGroup; class CAnimBlendAssocGroup;
@ -242,12 +64,12 @@ struct AnimAssocDefinition
class CAnimManager class CAnimManager
{ {
static const AnimAssocDefinition ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS]; static const AnimAssocDefinition ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS];
static CAnimBlock *ms_aAnimBlocks; //[2] static CAnimBlock ms_aAnimBlocks[2];
static CAnimBlendHierarchy *ms_aAnimations; //[250] static CAnimBlendHierarchy ms_aAnimations[250];
static int32 &ms_numAnimBlocks; static int32 ms_numAnimBlocks;
static int32 &ms_numAnimations; static int32 ms_numAnimations;
static CAnimBlendAssocGroup *&ms_aAnimAssocGroups; static CAnimBlendAssocGroup *ms_aAnimAssocGroups;
static CLinkList<CAnimBlendHierarchy*> &ms_animCache; static CLinkList<CAnimBlendHierarchy*> ms_animCache;
public: public:
static void Initialise(void); static void Initialise(void);

180
src/animation/AnimationId.h Normal file
View file

@ -0,0 +1,180 @@
#pragma once
enum AnimationId
{
ANIM_WALK,
ANIM_RUN,
ANIM_SPRINT,
ANIM_IDLE_STANCE,
ANIM_WALK_START,
ANIM_RUN_STOP,
ANIM_RUN_STOP_R,
ANIM_IDLE_CAM,
ANIM_IDLE_HBHB,
ANIM_IDLE_TIRED,
ANIM_IDLE_ARMED,
ANIM_IDLE_CHAT,
ANIM_IDLE_TAXI,
ANIM_KO_SHOT_FRONT1,
ANIM_KO_SHOT_FRONT2,
ANIM_KO_SHOT_FRONT3,
ANIM_KO_SHOT_FRONT4,
ANIM_KO_SHOT_FACE,
ANIM_KO_SHOT_STOM,
ANIM_KO_SHOT_ARML,
ANIM_KO_SHOT_ARMR,
ANIM_KO_SHOT_LEGL,
ANIM_KO_SHOT_LEGR,
ANIM_KD_LEFT,
ANIM_KD_RIGHT,
ANIM_KO_SKID_FRONT,
ANIM_KO_SPIN_R, // named left in VC
ANIM_KO_SKID_BACK,
ANIM_KO_SPIN_L, // named right in VC
ANIM_SHOT_FRONT_PARTIAL,
ANIM_SHOT_LEFT_PARTIAL,
ANIM_SHOT_BACK_PARTIAL,
ANIM_SHOT_RIGHT_PARTIAL,
ANIM_HIT_FRONT,
ANIM_HIT_LEFT,
ANIM_HIT_BACK,
ANIM_HIT_RIGHT,
ANIM_FLOOR_HIT,
ANIM_HIT_BODYBLOW,
ANIM_HIT_CHEST,
ANIM_HIT_HEAD,
ANIM_HIT_WALK,
ANIM_HIT_WALL,
ANIM_FLOOR_HIT_F,
ANIM_HIT_BEHIND,
ANIM_PUNCH_R,
ANIM_KICK_FLOOR,
ANIM_WEAPON_BAT_H,
ANIM_WEAPON_BAT_V,
ANIM_WEAPON_HGUN_BODY,
ANIM_WEAPON_AK_BODY,
ANIM_WEAPON_PUMP,
ANIM_WEAPON_SNIPER,
ANIM_WEAPON_THROW,
ANIM_WEAPON_THROWU,
ANIM_WEAPON_START_THROW,
ANIM_BOMBER,
ANIM_HGUN_RELOAD,
ANIM_AK_RELOAD,
ANIM_FPS_PUNCH,
ANIM_FPS_BAT,
ANIM_FPS_UZI,
ANIM_FPS_PUMP,
ANIM_FPS_AK,
ANIM_FPS_M16,
ANIM_FPS_ROCKET,
ANIM_FIGHT_IDLE,
ANIM_FIGHT2_IDLE,
ANIM_FIGHT_SH_F,
ANIM_FIGHT_BODYBLOW,
ANIM_FIGHT_HEAD,
ANIM_FIGHT_KICK,
ANIM_FIGHT_KNEE,
ANIM_FIGHT_LHOOK,
ANIM_FIGHT_PUNCH,
ANIM_FIGHT_ROUNDHOUSE,
ANIM_FIGHT_LONGKICK,
ANIM_FIGHT_PPUNCH,
ANIM_CAR_JACKED_RHS,
ANIM_CAR_LJACKED_RHS,
ANIM_CAR_JACKED_LHS,
ANIM_CAR_LJACKED_LHS,
ANIM_CAR_QJACK,
ANIM_CAR_QJACKED,
ANIM_CAR_ALIGN_LHS,
ANIM_CAR_ALIGNHI_LHS,
ANIM_CAR_OPEN_LHS,
ANIM_CAR_DOORLOCKED_LHS,
ANIM_CAR_PULLOUT_LHS,
ANIM_CAR_PULLOUT_LOW_LHS,
ANIM_CAR_GETIN_LHS,
ANIM_CAR_GETIN_LOW_LHS,
ANIM_CAR_CLOSEDOOR_LHS,
ANIM_CAR_CLOSEDOOR_LOW_LHS,
ANIM_CAR_ROLLDOOR,
ANIM_CAR_ROLLDOOR_LOW,
ANIM_CAR_GETOUT_LHS,
ANIM_CAR_GETOUT_LOW_LHS,
ANIM_CAR_CLOSE_LHS,
ANIM_CAR_ALIGN_RHS,
ANIM_CAR_ALIGNHI_RHS,
ANIM_CAR_OPEN_RHS,
ANIM_CAR_DOORLOCKED_RHS,
ANIM_CAR_PULLOUT_RHS,
ANIM_CAR_PULLOUT_LOW_RHS,
ANIM_CAR_GETIN_RHS,
ANIM_CAR_GETIN_LOW_RHS,
ANIM_CAR_CLOSEDOOR_RHS,
ANIM_CAR_CLOSEDOOR_LOW_RHS,
ANIM_CAR_SHUFFLE_RHS,
ANIM_CAR_LSHUFFLE_RHS,
ANIM_CAR_SIT,
ANIM_CAR_LSIT,
ANIM_CAR_SITP,
ANIM_CAR_SITPLO,
ANIM_DRIVE_L,
ANIM_DRIVE_R,
ANIM_DRIVE_LOW_L,
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
ANIM_CAR_GETOUT_RHS,
ANIM_CAR_GETOUT_LOW_RHS,
ANIM_CAR_CLOSE_RHS,
ANIM_CAR_HOOKERTALK,
ANIM_COACH_OPEN_L,
ANIM_COACH_OPEN_R,
ANIM_COACH_IN_L,
ANIM_COACH_IN_R,
ANIM_COACH_OUT_L,
ANIM_TRAIN_GETIN,
ANIM_TRAIN_GETOUT,
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
ANIM_VAN_OPEN_L,
ANIM_VAN_GETIN_L,
ANIM_VAN_CLOSE_L,
ANIM_VAN_GETOUT_L,
ANIM_VAN_OPEN,
ANIM_VAN_GETIN,
ANIM_VAN_CLOSE,
ANIM_VAN_GETOUT,
ANIM_GETUP1,
ANIM_GETUP2,
ANIM_GETUP3,
ANIM_GETUP_FRONT,
ANIM_JUMP_LAUNCH,
ANIM_JUMP_GLIDE,
ANIM_JUMP_LAND,
ANIM_FALL_FALL,
ANIM_FALL_GLIDE,
ANIM_FALL_LAND,
ANIM_FALL_COLLAPSE,
ANIM_EV_STEP,
ANIM_EV_DIVE,
ANIM_XPRESS_SCRATCH,
ANIM_ROAD_CROSS,
ANIM_TURN_180,
ANIM_ARREST_GUN,
ANIM_DROWN,
ANIM_CPR,
ANIM_DUCK_DOWN,
ANIM_DUCK_LOW,
ANIM_RBLOCK_CSHOOT,
ANIM_WEAPON_THROWU2,
ANIM_HANDSUP,
ANIM_HANDSCOWER,
ANIM_FUCKU,
ANIM_PHONE_IN,
ANIM_PHONE_OUT,
ANIM_PHONE_TALK,
NUM_ANIMS
};

52
src/animation/Bones.cpp Normal file
View file

@ -0,0 +1,52 @@
#include "common.h"
#include "PedModelInfo.h"
#include "Bones.h"
#ifdef PED_SKIN
int
ConvertPedNode2BoneTag(int node)
{
switch(node){
case PED_TORSO: return BONE_waist;
case PED_MID: return BONE_torso; // this is what Xbox/Mobile use
// return BONE_mid; // this is what PS2/PC use
case PED_HEAD: return BONE_head;
case PED_UPPERARML: return BONE_upperarml;
case PED_UPPERARMR: return BONE_upperarmr;
case PED_HANDL: return BONE_Lhand;
case PED_HANDR: return BONE_Rhand;
case PED_UPPERLEGL: return BONE_upperlegl;
case PED_UPPERLEGR: return BONE_upperlegr;
case PED_FOOTL: return BONE_footl;
case PED_FOOTR: return BONE_footr;
case PED_LOWERLEGR: return BONE_lowerlegl;
}
return -1;
}
const char*
ConvertBoneTag2BoneName(int tag)
{
switch(tag){
case BONE_waist: return "Swaist";
case BONE_upperlegr: return "Supperlegr";
case BONE_lowerlegr: return "Slowerlegr";
case BONE_footr: return "Sfootr";
case BONE_upperlegl: return "Supperlegl";
case BONE_lowerlegl: return "Slowerlegl";
case BONE_footl: return "Sfootl";
case BONE_mid: return "Smid";
case BONE_torso: return "Storso";
case BONE_head: return "Shead";
case BONE_upperarmr: return "Supperarmr";
case BONE_lowerarmr: return "Slowerarmr";
case BONE_Rhand: return "SRhand";
case BONE_upperarml: return "Supperarml";
case BONE_lowerarml: return "Slowerarml";
case BONE_Lhand: return "SLhand";
}
return nil;
}
#endif

24
src/animation/Bones.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
enum BoneTag
{
BONE_waist,
BONE_upperlegr,
BONE_lowerlegr,
BONE_footr,
BONE_upperlegl,
BONE_lowerlegl,
BONE_footl,
BONE_mid,
BONE_torso,
BONE_head,
BONE_upperarmr,
BONE_lowerarmr,
BONE_Rhand,
BONE_upperarml,
BONE_lowerarml,
BONE_Lhand,
};
int ConvertPedNode2BoneTag(int node);
const char *ConvertBoneTag2BoneName(int tag);

View file

@ -1,6 +1,5 @@
#define WITHWINDOWS // just for VK_SPACE
#include "common.h" #include "common.h"
#include "patcher.h"
#include "General.h" #include "General.h"
#include "CutsceneMgr.h" #include "CutsceneMgr.h"
#include "Directory.h" #include "Directory.h"
@ -117,19 +116,19 @@ FindCutsceneAudioTrackId(const char *szCutsceneName)
return -1; return -1;
} }
bool &CCutsceneMgr::ms_running = *(bool*)0x95CCF5; bool CCutsceneMgr::ms_running;
bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F; bool CCutsceneMgr::ms_cutsceneProcessing;
CDirectory *&CCutsceneMgr::ms_pCutsceneDir = *(CDirectory**)0x8F5F88; CDirectory *CCutsceneMgr::ms_pCutsceneDir;
CCutsceneObject *(&CCutsceneMgr::ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS] = *(CCutsceneObject*(*)[NUMCUTSCENEOBJECTS]) *(uintptr*) 0x862170; CCutsceneObject *CCutsceneMgr::ms_pCutsceneObjects[NUMCUTSCENEOBJECTS];
int32 &CCutsceneMgr::ms_numCutsceneObjs = *(int32*)0x942FA4; int32 CCutsceneMgr::ms_numCutsceneObjs;
bool &CCutsceneMgr::ms_loaded = *(bool*)0x95CD95; bool CCutsceneMgr::ms_loaded;
bool &CCutsceneMgr::ms_animLoaded = *(bool*)0x95CDA0; bool CCutsceneMgr::ms_animLoaded;
bool &CCutsceneMgr::ms_useLodMultiplier = *(bool*)0x95CD74; bool CCutsceneMgr::ms_useLodMultiplier;
char(&CCutsceneMgr::ms_cutsceneName)[CUTSCENENAMESIZE] = *(char(*)[CUTSCENENAMESIZE]) *(uintptr*)0x70D9D0; char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
CAnimBlendAssocGroup &CCutsceneMgr::ms_cutsceneAssociations = *(CAnimBlendAssocGroup*)0x709C58; CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector &CCutsceneMgr::ms_cutsceneOffset = *(CVector*)0x8F2C0C; CVector CCutsceneMgr::ms_cutsceneOffset;
float &CCutsceneMgr::ms_cutsceneTimer = *(float*)0x941548; float CCutsceneMgr::ms_cutsceneTimer;
uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40; uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
RpAtomic * RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data) CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@ -416,26 +415,10 @@ CCutsceneMgr::Update(void)
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown()) || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|| CPad::GetPad(0)->GetLeftMouseJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()
|| CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetEnterJustDown()
|| CPad::GetPad(0)->GetCharJustDown(VK_SPACE)) || CPad::GetPad(0)->GetCharJustDown(' '))
FinishCutscene(); FinishCutscene();
} }
} }
bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; } bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; }
STARTPATCHES
InjectHook(0x4045D0, &CCutsceneMgr::Initialise, PATCH_JUMP);
InjectHook(0x404630, &CCutsceneMgr::Shutdown, PATCH_JUMP);
InjectHook(0x404650, &CCutsceneMgr::LoadCutsceneData, PATCH_JUMP);
InjectHook(0x405140, &CCutsceneMgr::FinishCutscene, PATCH_JUMP);
InjectHook(0x404D80, &CCutsceneMgr::SetHeadAnim, PATCH_JUMP);
InjectHook(0x404DC0, &CCutsceneMgr::SetupCutsceneToStart, PATCH_JUMP);
InjectHook(0x404D20, &CCutsceneMgr::SetCutsceneAnim, PATCH_JUMP);
InjectHook(0x404CD0, &CCutsceneMgr::AddCutsceneHead, PATCH_JUMP);
InjectHook(0x404BE0, &CCutsceneMgr::CreateCutsceneObject, PATCH_JUMP);
InjectHook(0x4048E0, &CCutsceneMgr::DeleteCutsceneData, PATCH_JUMP);
InjectHook(0x404EE0, &CCutsceneMgr::Update, PATCH_JUMP);
InjectHook(0x4051B0, &CCutsceneMgr::GetCutsceneTimeInMilleseconds, PATCH_JUMP);
InjectHook(0x4051F0, &CCutsceneMgr::HasCutsceneFinished, PATCH_JUMP);
InjectHook(0x404B40, &CalculateBoundingSphereRadiusCB, PATCH_JUMP);
ENDPATCHES

View file

@ -9,25 +9,26 @@ class CCutsceneHead;
class CCutsceneMgr class CCutsceneMgr
{ {
static bool &ms_running; static bool ms_running;
static CCutsceneObject *(&ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS]; static CCutsceneObject *ms_pCutsceneObjects[NUMCUTSCENEOBJECTS];
static int32 &ms_numCutsceneObjs; static int32 ms_numCutsceneObjs;
static bool &ms_loaded; static bool ms_loaded;
static bool &ms_animLoaded; static bool ms_animLoaded;
static bool &ms_useLodMultiplier; static bool ms_useLodMultiplier;
static char(&ms_cutsceneName)[CUTSCENENAMESIZE]; static char ms_cutsceneName[CUTSCENENAMESIZE];
static CAnimBlendAssocGroup &ms_cutsceneAssociations; static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector &ms_cutsceneOffset; static CVector ms_cutsceneOffset;
static float &ms_cutsceneTimer; static float ms_cutsceneTimer;
static bool &ms_cutsceneProcessing; static bool ms_cutsceneProcessing;
public: public:
static CDirectory *&ms_pCutsceneDir; static CDirectory *ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus; static uint32 ms_cutsceneLoadStatus;
static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; } static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; } static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; } static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; } static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }

View file

@ -1,19 +1,25 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "NodeName.h" #include "NodeName.h"
#include "VisibilityPlugins.h" #include "VisibilityPlugins.h"
#include "AnimBlendClumpData.h" #include "AnimBlendClumpData.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
CAnimBlendClumpData *&gpAnimBlendClump = *(CAnimBlendClumpData**)0x621000; CAnimBlendClumpData *gpAnimBlendClump;
// PS2 names without "NonSkinned"
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg);
void void
FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg) FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{ {
CVector vec, pos(0.0f, 0.0f, 0.0f); CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@ -25,9 +31,9 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
gpAnimBlendClump->velocity){ gpAnimBlendClump->velocity){
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D) if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
FrameUpdateCallBackWith3dVelocityExtraction(frame, arg); FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(frame, arg);
else else
FrameUpdateCallBackWithVelocityExtraction(frame, arg); FrameUpdateCallBackWithVelocityExtractionNonSkinned(frame, arg);
return; return;
} }
@ -48,12 +54,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat); RwMatrixSetIdentity(mat);
rot.Normalise();
float norm = rot.MagnitudeSqr();
if(norm == 0.0f)
rot.w = 1.0f;
else
rot *= 1.0f/Sqrt(norm);
rot.Get(mat); rot.Get(mat);
} }
@ -69,7 +70,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
} }
void void
FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg) FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
{ {
CVector vec, pos(0.0f, 0.0f, 0.0f); CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@ -122,12 +123,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat); RwMatrixSetIdentity(mat);
rot.Normalise();
float norm = rot.MagnitudeSqr();
if(norm == 0.0f)
rot.w = 1.0f;
else
rot *= 1.0f/Sqrt(norm);
rot.Get(mat); rot.Get(mat);
} }
@ -154,7 +150,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
// original code uses do loops? // original code uses do loops?
void void
FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg) FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
{ {
CVector vec, pos(0.0f, 0.0f, 0.0f); CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@ -201,12 +197,7 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat); RwMatrixSetIdentity(mat);
rot.Normalise();
float norm = rot.MagnitudeSqr();
if(norm == 0.0f)
rot.w = 1.0f;
else
rot *= 1.0f/Sqrt(norm);
rot.Get(mat); rot.Get(mat);
} }
@ -221,8 +212,202 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
RwMatrixUpdate(mat); RwMatrixUpdate(mat);
} }
STARTPATCHES #ifdef PED_SKIN
InjectHook(0x4025F0, FrameUpdateCallBack, PATCH_JUMP);
InjectHook(0x4028B0, FrameUpdateCallBackWithVelocityExtraction, PATCH_JUMP); void
InjectHook(0x402D40, FrameUpdateCallBackWith3dVelocityExtraction, PATCH_JUMP); FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
ENDPATCHES {
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
gpAnimBlendClump->velocity){
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
FrameUpdateCallBackWith3dVelocityExtractionSkinned(frame, arg);
else
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
return;
}
if(updateData->foobar)
for(node = updateData->nodes; *node; node++)
if((*node)->sequence && (*node)->association->IsPartial())
totalBlendAmount += (*node)->association->blendAmount;
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
(*node)->Update(vec, q, 1.0f-totalBlendAmount);
if((*node)->sequence->HasTranslation())
pos += vec;
rot += q;
}
++*node;
}
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
rot.Normalise();
xform->q.imag.x = rot.x;
xform->q.imag.y = rot.y;
xform->q.imag.z = rot.z;
xform->q.real = rot.w;
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
xform->t.x = pos.x;
xform->t.y = pos.y;
xform->t.z = pos.z;
xform->t.x += frame->resetPos.x;
xform->t.y += frame->resetPos.y;
xform->t.z += frame->resetPos.z;
}
}
void
FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
float transx = 0.0f, transy = 0.0f;
float curx = 0.0f, cury = 0.0f;
float endx = 0.0f, endy = 0.0f;
bool looped = false;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
if(updateData->foobar)
for(node = updateData->nodes; *node; node++)
if((*node)->sequence && (*node)->association->IsPartial())
totalBlendAmount += (*node)->association->blendAmount;
for(node = updateData->nodes; *node; node++)
if((*node)->sequence && (*node)->sequence->HasTranslation()){
if((*node)->association->HasTranslation()){
(*node)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
cury += vec.y;
if((*node)->association->HasXTranslation())
curx += vec.x;
}
}
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
rot += q;
if((*node)->sequence->HasTranslation()){
pos += vec;
if((*node)->association->HasTranslation()){
transy += vec.y;
if((*node)->association->HasXTranslation())
transx += vec.x;
looped |= nodelooped;
if(nodelooped){
(*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
endy += vec.y;
if((*node)->association->HasXTranslation())
endx += vec.x;
}
}
}
}
++*node;
}
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
rot.Normalise();
xform->q.imag.x = rot.x;
xform->q.imag.y = rot.y;
xform->q.imag.z = rot.z;
xform->q.real = rot.w;
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
gpAnimBlendClump->velocity->x = transx - curx;
gpAnimBlendClump->velocity->y = transy - cury;
if(looped){
gpAnimBlendClump->velocity->x += endx;
gpAnimBlendClump->velocity->y += endy;
}
xform->t.x = pos.x - transx;
xform->t.y = pos.y - transy;
xform->t.z = pos.z;
if(xform->t.z >= -0.8f)
if(xform->t.z < -0.4f)
xform->t.z += (2.5f * xform->t.z + 2.0f) * frame->resetPos.z;
else
xform->t.z += frame->resetPos.z;
xform->t.x += frame->resetPos.x;
xform->t.y += frame->resetPos.y;
}
}
void
FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
CVector trans(0.0f, 0.0f, 0.0f);
CVector cur(0.0f, 0.0f, 0.0f);
CVector end(0.0f, 0.0f, 0.0f);
bool looped = false;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
if(updateData->foobar)
for(node = updateData->nodes; *node; node++)
if((*node)->sequence && (*node)->association->IsPartial())
totalBlendAmount += (*node)->association->blendAmount;
for(node = updateData->nodes; *node; node++)
if((*node)->sequence && (*node)->sequence->HasTranslation()){
if((*node)->association->HasTranslation()){
(*node)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
cur += vec;
}
}
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
rot += q;
if((*node)->sequence->HasTranslation()){
pos += vec;
if((*node)->association->HasTranslation()){
trans += vec;
looped |= nodelooped;
if(nodelooped){
(*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
end += vec;
}
}
}
}
++*node;
}
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
rot.Normalise();
xform->q.imag.x = rot.x;
xform->q.imag.y = rot.y;
xform->q.imag.z = rot.z;
xform->q.real = rot.w;
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
*gpAnimBlendClump->velocity = trans - cur;
if(looped)
*gpAnimBlendClump->velocity += end;
xform->t.x = (pos - trans).x + frame->resetPos.x;
xform->t.y = (pos - trans).y + frame->resetPos.y;
xform->t.z = (pos - trans).z + frame->resetPos.z;
}
}
#endif

View file

@ -1,14 +1,19 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "RwHelper.h"
#include "General.h" #include "General.h"
#include "NodeName.h" #include "NodeName.h"
#include "VisibilityPlugins.h" #include "VisibilityPlugins.h"
#include "Bones.h"
#include "AnimBlendClumpData.h" #include "AnimBlendClumpData.h"
#include "AnimBlendHierarchy.h" #include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
#ifdef PED_SKIN
#include "PedModelInfo.h"
#endif
RwInt32 &ClumpOffset = *(RwInt32*)0x8F1B84; RwInt32 ClumpOffset;
enum enum
{ {
@ -122,19 +127,59 @@ FrameForAllChildrenFillFrameArrayCallBack(RwFrame *frame, void *data)
return frame; return frame;
} }
// FrameInitCallBack on PS2
void void
FrameInitCallBack(AnimBlendFrameData *frameData, void*) FrameInitCBnonskin(AnimBlendFrameData *frameData, void*)
{ {
frameData->flag = 0; frameData->flag = 0;
frameData->resetPos = *RwMatrixGetPos(RwFrameGetMatrix(frameData->frame)); frameData->resetPos = *RwMatrixGetPos(RwFrameGetMatrix(frameData->frame));
} }
void void
RpAnimBlendClumpInit(RpClump *clump) FrameInitCBskin(AnimBlendFrameData *frameData, void*)
{ {
frameData->flag = 0;
}
#ifdef PED_SKIN #ifdef PED_SKIN
TODO void
#else RpAnimBlendClumpInitSkinned(RpClump *clump)
{
int i;
RwV3d boneTab[64];
CAnimBlendClumpData *clumpData;
RpAtomic *atomic;
RpSkin *skin;
RpHAnimHierarchy *hier;
int numBones;
RpAnimBlendAllocateData(clump);
clumpData = *RPANIMBLENDCLUMPDATA(clump);
atomic = IsClumpSkinned(clump);
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
numBones = RpSkinGetNumBones(skin);
clumpData->SetNumberOfBones(numBones);
hier = GetAnimHierarchyFromSkinClump(clump);
assert(hier);
memset(boneTab, 0, sizeof(boneTab));
SkinGetBonePositionsToTable(clump, boneTab);
AnimBlendFrameData *frames = clumpData->frames;
for(i = 0; i < numBones; i++){
frames[i].nodeID = HIERNODEID(hier, i);
frames[i].resetPos = boneTab[i];
frames[i].hanimFrame = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
}
clumpData->ForAllFrames(FrameInitCBskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
}
#endif
void
RpAnimBlendClumpInitNotSkinned(RpClump *clump)
{
int numFrames = 0; int numFrames = 0;
CAnimBlendClumpData *clumpData; CAnimBlendClumpData *clumpData;
RwFrame *root; RwFrame *root;
@ -147,9 +192,19 @@ RpAnimBlendClumpInit(RpClump *clump)
clumpData->SetNumberOfFrames(numFrames); clumpData->SetNumberOfFrames(numFrames);
frames = clumpData->frames; frames = clumpData->frames;
RwFrameForAllChildren(root, FrameForAllChildrenFillFrameArrayCallBack, &frames); RwFrameForAllChildren(root, FrameForAllChildrenFillFrameArrayCallBack, &frames);
clumpData->ForAllFrames(FrameInitCallBack, nil); clumpData->ForAllFrames(FrameInitCBnonskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION; clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
}
void
RpAnimBlendClumpInit(RpClump *clump)
{
#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpInitSkinned(clump);
else
#endif #endif
RpAnimBlendClumpInitNotSkinned(clump);
} }
bool bool
@ -298,42 +353,68 @@ RpAnimBlendClumpGetFirstAssociation(RpClump *clump)
return CAnimBlendAssociation::FromLink(clumpData->link.next); return CAnimBlendAssociation::FromLink(clumpData->link.next);
} }
// FillFrameArrayCallBack on PS2
void void
FillFrameArrayCallBack(AnimBlendFrameData *frame, void *arg) FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
{ {
AnimBlendFrameData **frames = (AnimBlendFrameData**)arg; AnimBlendFrameData **frames = (AnimBlendFrameData**)arg;
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame; frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
} }
#ifdef PED_SKIN
void
RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
{
int i;
CAnimBlendClumpData *clumpData = *RPANIMBLENDCLUMPDATA(clump);
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
for(i = PED_MID; i < PED_NODE_MAX; i++)
frames[i] = &clumpData->frames[RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(i))];
}
#endif
void void
RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames) RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames)
{ {
#ifdef PED_SKIN #ifdef PED_SKIN
TODO if(IsClumpSkinned(clump))
#else RpAnimBlendClumpFillFrameArraySkin(clump, frames);
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCallBack, frames); else
#endif #endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCBnonskin, frames);
} }
AnimBlendFrameData *pFrameDataFound; AnimBlendFrameData *pFrameDataFound;
// FrameFindCallBack on PS2
void void
FrameFindCallBack(AnimBlendFrameData *frame, void *arg) FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
{ {
char *nodename = GetFrameNodeName(frame->frame); char *nodename = GetFrameNodeName(frame->frame);
if(!CGeneral::faststricmp(nodename, (char*)arg)) if(!CGeneral::faststricmp(nodename, (char*)arg))
pFrameDataFound = frame; pFrameDataFound = frame;
} }
#ifdef PED_SKIN
void
FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
{
const char *name = ConvertBoneTag2BoneName(frame->nodeID);
if(name && CGeneral::faststricmp(name, (char*)arg) == 0)
pFrameDataFound = frame;
}
#endif
AnimBlendFrameData* AnimBlendFrameData*
RpAnimBlendClumpFindFrame(RpClump *clump, const char *name) RpAnimBlendClumpFindFrame(RpClump *clump, const char *name)
{ {
pFrameDataFound = nil; pFrameDataFound = nil;
#ifdef PED_SKIN #ifdef PED_SKIN
TODO if(IsClumpSkinned(clump))
#else (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBskin, (void*)name);
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindCallBack, (void*)name); else
#endif #endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBnonskin, (void*)name);
return pFrameDataFound; return pFrameDataFound;
} }
@ -369,7 +450,12 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
} }
updateData.nodes[i] = nil; updateData.nodes[i] = nil;
clumpData->ForAllFrames(FrameUpdateCallBack, &updateData); #ifdef PED_SKIN
if(IsClumpSkinned(clump))
clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
else
#endif
clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
for(link = clumpData->link.next; link; link = link->next){ for(link = clumpData->link.next; link; link = link->next){
CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link); CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
@ -378,26 +464,3 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
} }
RwFrameUpdateObjects(RpClumpGetFrame(clump)); RwFrameUpdateObjects(RpClumpGetFrame(clump));
} }
STARTPATCHES
InjectHook(0x4052D0, RpAnimBlendPluginAttach, PATCH_JUMP);
InjectHook(0x4052A0, RpAnimBlendAllocateData, PATCH_JUMP);
InjectHook(0x405780, (CAnimBlendAssociation *(*)(CAnimBlendAssociation*))RpAnimBlendGetNextAssociation, PATCH_JUMP);
InjectHook(0x4057A0, (CAnimBlendAssociation *(*)(CAnimBlendAssociation*,uint32))RpAnimBlendGetNextAssociation, PATCH_JUMP);
InjectHook(0x405520, RpAnimBlendClumpSetBlendDeltas, PATCH_JUMP);
InjectHook(0x405560, RpAnimBlendClumpRemoveAllAssociations, PATCH_JUMP);
InjectHook(0x405570, RpAnimBlendClumpRemoveAssociations, PATCH_JUMP);
InjectHook(0x405480, RpAnimBlendClumpInit, PATCH_JUMP);
InjectHook(0x405500, RpAnimBlendClumpIsInitialized, PATCH_JUMP);
InjectHook(0x4055C0, RpAnimBlendClumpGetAssociation, PATCH_JUMP);
InjectHook(0x4055F0, RpAnimBlendClumpGetMainAssociation, PATCH_JUMP);
InjectHook(0x405680, RpAnimBlendClumpGetMainPartialAssociation, PATCH_JUMP);
InjectHook(0x4056D0, RpAnimBlendClumpGetMainAssociation_N, PATCH_JUMP);
InjectHook(0x405710, RpAnimBlendClumpGetMainPartialAssociation_N, PATCH_JUMP);
InjectHook(0x405750, (CAnimBlendAssociation *(*)(RpClump*, uint32))RpAnimBlendClumpGetFirstAssociation, PATCH_JUMP);
InjectHook(0x4031B0, (CAnimBlendAssociation *(*)(RpClump*))RpAnimBlendClumpGetFirstAssociation, PATCH_JUMP);
InjectHook(0x405460, RpAnimBlendClumpFillFrameArray, PATCH_JUMP);
InjectHook(0x4024B0, RpAnimBlendClumpUpdateAnimations, PATCH_JUMP);
ENDPATCHES

View file

@ -7,11 +7,11 @@ struct AnimBlendFrameData;
struct AnimBlendFrameUpdateData struct AnimBlendFrameUpdateData
{ {
int foobar; int foobar; // TODO: figure out what this actually means
CAnimBlendNode *nodes[16]; CAnimBlendNode *nodes[16];
}; };
extern RwInt32 &ClumpOffset; extern RwInt32 ClumpOffset;
#define RPANIMBLENDCLUMPDATA(o) (RWPLUGINOFFSET(CAnimBlendClumpData*, o, ClumpOffset)) #define RPANIMBLENDCLUMPDATA(o) (RWPLUGINOFFSET(CAnimBlendClumpData*, o, ClumpOffset))
bool RpAnimBlendPluginAttach(void); bool RpAnimBlendPluginAttach(void);
@ -37,5 +37,6 @@ CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump);
void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta); void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta);
extern CAnimBlendClumpData *&gpAnimBlendClump; extern CAnimBlendClumpData *gpAnimBlendClump;
void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "Entity.h" #include "Entity.h"
#include "AudioCollision.h" #include "AudioCollision.h"
@ -226,7 +226,7 @@ cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio; if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
if(s1 == SURFACE_METAL6 && ratio < 0.6f) { if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
s1 = SURFACE_BILLBOARD; s1 = SURFACE_BILLBOARD;
ratio = min(1.f, 2.f * ratio); ratio = Min(1.f, 2.f * ratio);
} }
emittingVol = 40.f * ratio; emittingVol = 40.f * ratio;
if(emittingVol) { if(emittingVol) {
@ -406,14 +406,3 @@ cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface
m_sCollisionManager.AddCollisionToRequestedQueue(); m_sCollisionManager.AddCollisionToRequestedQueue();
} }
} }
STARTPATCHES
InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "audio_enums.h" #include "audio_enums.h"
#include "AudioManager.h" #include "AudioManager.h"
@ -40,18 +40,18 @@
#include "sampman.h" #include "sampman.h"
cAudioManager AudioManager; cAudioManager AudioManager;
uint32 gPornNextTime; // = *(uint32*)0x6508A0; uint32 gPornNextTime;
uint32 gSawMillNextTime; // = *(uint32*)0x6508A4; uint32 gSawMillNextTime;
uint32 gShopNextTime; // = *(uint32*)0x6508A8; uint32 gShopNextTime;
uint32 gAirportNextTime; // = *(uint32*)0x6508AC; uint32 gAirportNextTime;
uint32 gCinemaNextTime; //= *(uint32*)0x6508B0; uint32 gCinemaNextTime;
uint32 gDocksNextTime; // = *(uint32*)0x6508B4; uint32 gDocksNextTime;
uint32 gHomeNextTime; // = *(uint32*)0x6508B8; uint32 gHomeNextTime;
uint32 gCellNextTime; // = *(uint32*)0x6508BC; uint32 gCellNextTime;
uint32 gNextCryTime; // = *(uint32*)0x6508C0; uint32 gNextCryTime;
uint8 gJumboVolOffsetPercentage; // = *(uint8 *)0x6508ED; uint8 gJumboVolOffsetPercentage;
bool bPlayerJustEnteredCar; // = *(bool *)0x6508C4; bool bPlayerJustEnteredCar;
bool g_bMissionAudioLoadFailed; // = *(bool *)0x95CD8E; bool g_bMissionAudioLoadFailed;
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
const int policeChannel = channels + 1; const int policeChannel = channels + 1;
@ -635,9 +635,9 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
float speedOfSource = (dist / m_bTimeSpent) * speedMultiplier; float speedOfSource = (dist / m_bTimeSpent) * speedMultiplier;
if(m_fSpeedOfSound > Abs(speedOfSource)) { if(m_fSpeedOfSound > Abs(speedOfSource)) {
if(speedOfSource < 0.0f) { if(speedOfSource < 0.0f) {
speedOfSource = max(speedOfSource, -1.5f); speedOfSource = Max(speedOfSource, -1.5f);
} else { } else {
speedOfSource = min(speedOfSource, 1.5f); speedOfSource = Min(speedOfSource, 1.5f);
} }
newFreq = newFreq =
(oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound); (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound);
@ -650,10 +650,10 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
int32 int32
cAudioManager::ComputePan(float dist, CVector *vec) cAudioManager::ComputePan(float dist, CVector *vec)
{ {
int32 index = min(63, Abs(vec->x / (dist / 64.f))); int32 index = Min(63, Abs(vec->x / (dist / 64.f)));
if(vec->x > 0.f) return max(20, 63 - panTable[index]); if(vec->x > 0.f) return Max(20, 63 - panTable[index]);
return min(107, panTable[index] + 63); return Min(107, panTable[index] + 63);
} }
uint8 uint8
@ -2894,7 +2894,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f; relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f;
} else if(wheelState == WHEEL_STATE_SKIDDING) { } else if(wheelState == WHEEL_STATE_SKIDDING) {
relativeVelChange = min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
} else if(wheelState == WHEEL_STATE_FIXED) { } else if(wheelState == WHEEL_STATE_FIXED) {
modificator = 0.4f; modificator = 0.4f;
relativeVelChange = gasPedalAudio; relativeVelChange = gasPedalAudio;
@ -2905,7 +2905,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
velChange = Abs(velocityChange); velChange = Abs(velocityChange);
if(relativeVelChange > 0.4f) relativeVelChange = relativeVelChange * modificator; if(relativeVelChange > 0.4f) relativeVelChange = relativeVelChange * modificator;
if(velChange > 0.04f) { if(velChange > 0.04f) {
relativeVel = min(1.0f, velChange / transmission->fMaxVelocity); relativeVel = Min(1.0f, velChange / transmission->fMaxVelocity);
} else { } else {
relativeVel = 0.0f; relativeVel = 0.0f;
} }
@ -2914,7 +2914,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
relativeVelChange = 0.0f; relativeVelChange = 0.0f;
} }
return max(relativeVelChange, min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
} }
float float
@ -2924,12 +2924,12 @@ cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automo
float relativeVelChange; float relativeVelChange;
if(automobile->m_aWheelState[wheel] == 2) { if(automobile->m_aWheelState[wheel] == 2) {
relativeVelChange = min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
} else { } else {
relativeVelChange = 0.0f; relativeVelChange = 0.0f;
} }
return max(relativeVelChange, min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
} }
bool bool
@ -3326,7 +3326,7 @@ cAudioManager::ProcessActiveQueues()
if(field_4) { if(field_4) {
emittingVol = emittingVol =
2 * 2 *
min(63, Min(63,
sample.m_bEmittingVolume); sample.m_bEmittingVolume);
} else { } else {
emittingVol = emittingVol =
@ -3353,13 +3353,13 @@ cAudioManager::ProcessActiveQueues()
if(sample.m_nFrequency <= if(sample.m_nFrequency <=
m_asActiveSamples[j] m_asActiveSamples[j]
.m_nFrequency) { .m_nFrequency) {
freq = max( freq = Max(
sample.m_nFrequency, sample.m_nFrequency,
m_asActiveSamples[j] m_asActiveSamples[j]
.m_nFrequency - .m_nFrequency -
6000); 6000);
} else { } else {
freq = min( freq = Min(
sample.m_nFrequency, sample.m_nFrequency,
m_asActiveSamples[j] m_asActiveSamples[j]
.m_nFrequency + .m_nFrequency +
@ -3376,14 +3376,14 @@ cAudioManager::ProcessActiveQueues()
if(sample.m_bEmittingVolume <= if(sample.m_bEmittingVolume <=
m_asActiveSamples[j] m_asActiveSamples[j]
.m_bEmittingVolume) { .m_bEmittingVolume) {
vol = max( vol = Max(
m_asActiveSamples[j] m_asActiveSamples[j]
.m_bEmittingVolume - .m_bEmittingVolume -
10, 10,
sample sample
.m_bEmittingVolume); .m_bEmittingVolume);
} else { } else {
vol = min( vol = Min(
m_asActiveSamples[j] m_asActiveSamples[j]
.m_bEmittingVolume + .m_bEmittingVolume +
10, 10,
@ -3394,7 +3394,7 @@ cAudioManager::ProcessActiveQueues()
uint8 emittingVol; uint8 emittingVol;
if(field_4) { if(field_4) {
emittingVol = emittingVol =
2 * min(63, vol); 2 * Min(63, vol);
} else { } else {
emittingVol = vol; emittingVol = vol;
} }
@ -3461,7 +3461,7 @@ cAudioManager::ProcessActiveQueues()
&position); &position);
if(field_4) { if(field_4) {
emittingVol = emittingVol =
2 * min(63, m_asActiveSamples[j] 2 * Min(63, m_asActiveSamples[j]
.m_bEmittingVolume); .m_bEmittingVolume);
} else { } else {
emittingVol = emittingVol =
@ -3783,7 +3783,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params)
velocityChange = Abs(params->m_fVelocityChange); velocityChange = Abs(params->m_fVelocityChange);
if(velocityChange <= 0.0005f && params->m_pVehicle->GetPosition().y) return true; if(velocityChange <= 0.0005f && params->m_pVehicle->GetPosition().y) return true;
velocityChange = min(0.75f, velocityChange); velocityChange = Min(0.75f, velocityChange);
multiplier = (velocityChange - 0.0005f) * 1.3342f; multiplier = (velocityChange - 0.0005f) * 1.3342f;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
vol = (30.f * multiplier); vol = (30.f * multiplier);
@ -5044,7 +5044,7 @@ void
cAudioManager::ProcessJumboDecel(CPlane *plane) cAudioManager::ProcessJumboDecel(CPlane *plane)
{ {
if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) {
const float modificator = min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f); const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000); SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000);
SetupJumboWhineSound(18, 29500); SetupJumboWhineSound(18, 29500);
} }
@ -6269,7 +6269,7 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
emittingVol = 10; emittingVol = 10;
veh = (CAutomobile *)ped->m_pMyVehicle; veh = (CAutomobile *)ped->m_pMyVehicle;
if(veh && veh->IsCar()) { if(veh && veh->IsCar()) {
for(int32 i = 2; i < ARRAYSIZE(veh->Doors); i++) { for(int32 i = 2; i < ARRAY_SIZE(veh->Doors); i++) {
if(!veh->IsDoorClosed((eDoors)i) || if(!veh->IsDoorClosed((eDoors)i) ||
veh->IsDoorMissing((eDoors)i)) { veh->IsDoorMissing((eDoors)i)) {
emittingVol = 42; emittingVol = 42;
@ -7259,7 +7259,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
CurrentPretendGear = 1; CurrentPretendGear = 1;
} }
if(CReplay::IsPlayingBack()) { if(CReplay::IsPlayingBack()) {
accelerateState = 255.f * max(0.0f, min(1.0f, automobile->m_fGasPedal)); accelerateState = 255.f * Max(0.0f, Min(1.0f, automobile->m_fGasPedal));
} else { } else {
accelerateState = Pads->GetAccelerate(); accelerateState = Pads->GetAccelerate();
} }
@ -7268,7 +7268,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
velocityChange = params->m_fVelocityChange; velocityChange = params->m_fVelocityChange;
relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity; relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity;
accelerationMultipler = min(min(1.f, relativeVelocityChange), 0.f); accelerationMultipler = Min(Min(1.f, relativeVelocityChange), 0.f);
gasPedalAudio = accelerationMultipler; gasPedalAudio = accelerationMultipler;
currentGear = params->m_pVehicle->m_nCurrentGear; currentGear = params->m_pVehicle->m_nCurrentGear;
@ -7290,9 +7290,9 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
if(0.0f != velocityChange) { if(0.0f != velocityChange) {
time = params->m_pVehicle->m_vecMoveSpeed.z / velocityChange; time = params->m_pVehicle->m_vecMoveSpeed.z / velocityChange;
if(time <= 0.0f) { if(time <= 0.0f) {
freqModifier = max(-0.2f, time) * -15000.f; freqModifier = Max(-0.2f, time) * -15000.f;
} else { } else {
freqModifier = -(min(0.2f, time) * 15000.f); freqModifier = -(Min(0.2f, time) * 15000.f);
} }
if(params->m_fVelocityChange < -0.001f) freqModifier = -freqModifier; if(params->m_fVelocityChange < -0.001f) freqModifier = -freqModifier;
} else { } else {
@ -7311,10 +7311,10 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
gasPedalAudio = automobile->m_fGasPedalAudio; gasPedalAudio = automobile->m_fGasPedalAudio;
} else { } else {
gasPedalAudio = gasPedalAudio =
min(1.0f, params->m_fVelocityChange / Min(1.0f, params->m_fVelocityChange /
params->m_pTransmission->fMaxReverseVelocity); params->m_pTransmission->fMaxReverseVelocity);
} }
gasPedalAudio = max(0.0f, gasPedalAudio); gasPedalAudio = Max(0.0f, gasPedalAudio);
automobile->m_fGasPedalAudio = gasPedalAudio; automobile->m_fGasPedalAudio = gasPedalAudio;
} else if(LastAccel > 0) { } else if(LastAccel > 0) {
if(channelUsed) { if(channelUsed) {
@ -7343,7 +7343,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq, AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq,
(engineSoundType + SFX_CAR_REV_10), 0, 52, 1); (engineSoundType + SFX_CAR_REV_10), 0, 52, 1);
CurrentPretendGear = max(1, currentGear); CurrentPretendGear = Max(1, currentGear);
LastAccel = accelerateState; LastAccel = accelerateState;
bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn;
@ -8005,7 +8005,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
if(params->m_fVelocityChange > 0.0f) { if(params->m_fVelocityChange > 0.0f) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
train = (CTrain *)params->m_pVehicle; train = (CTrain *)params->m_pVehicle;
speedMultipler = min(1.0f, train->m_fSpeed * 250.f / 51.f); speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f);
emittingVol = (75.f * speedMultipler); emittingVol = (75.f * speedMultipler);
if(train->m_fWagonPosition == 0.0f) { if(train->m_fWagonPosition == 0.0f) {
m_sQueueSample.m_bVolume = m_sQueueSample.m_bVolume =
@ -8176,7 +8176,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
if(automobile->Damage.GetDoorStatus(i) == 2) { if(automobile->Damage.GetDoorStatus(i) == 2) {
doorState = automobile->Doors[i].m_nDoorState; doorState = automobile->Doors[i].m_nDoorState;
if(doorState == 1 || doorState == 2) { if(doorState == 1 || doorState == 2) {
velocity = min(0.3f, Abs(automobile->Doors[i].m_fAngVel)); velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel));
if(velocity > 0.0035f) { if(velocity > 0.0035f) {
emittingVol = (100.f * velocity * 10.f / 3.f); emittingVol = (100.f * velocity * 10.f / 3.f);
m_sQueueSample.m_bVolume = ComputeVolume( m_sQueueSample.m_bVolume = ComputeVolume(
@ -8599,7 +8599,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params)
m_sQueueSample.m_fSoundIntensity = 30.0f; m_sQueueSample.m_fSoundIntensity = 30.0f;
break; break;
case SOUND_CAR_JUMP: case SOUND_CAR_JUMP:
emittingVol = max( emittingVol = Max(
80.f, 80.f,
2 * (100.f * 2 * (100.f *
m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
@ -9081,7 +9081,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
params->m_fDistance); params->m_fDistance);
emittingVol = emittingVol =
30.f * 30.f *
min(1.f, Min(1.f,
velocity / (0.5f * params->m_pTransmission->fMaxVelocity)); velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
m_sQueueSample.m_bVolume = m_sQueueSample.m_bVolume =
ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance); ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
@ -9132,6 +9132,9 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
CVehicle *veh = params->m_pVehicle; CVehicle *veh = params->m_pVehicle;
if(veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) return; if(veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) return;
#ifdef FIX_BUGS
if (params->m_pVehicle->m_status == STATUS_WRECKED) return;
#endif
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance); m_sQueueSample.m_bVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) { if(m_sQueueSample.m_bVolume) {
@ -9394,7 +9397,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, CalculateDistance(params->m_bDistanceCalculated,
params->m_fDistance); params->m_fDistance);
relativeVelocity = relativeVelocity =
min(1.0f, Min(1.0f,
velChange / (0.5f * params->m_pTransmission->fMaxVelocity)); velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads; emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads;
m_sQueueSample.m_bVolume = m_sQueueSample.m_bVolume =
@ -9545,6 +9548,9 @@ cAudioManager::ResetTimers(uint32 time)
SampleManager.SetEffectsFadeVolume(0); SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0); SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload(); MusicManager.ResetMusicAfterReload();
#ifdef OPENAL
SampleManager.Service();
#endif
} }
} }
@ -9600,6 +9606,9 @@ cAudioManager::ServiceSoundEffects()
ProcessMissionAudio(); ProcessMissionAudio();
AdjustSamplesVolume(); AdjustSamplesVolume();
ProcessActiveQueues(); ProcessActiveQueues();
#ifdef OPENAL
SampleManager.Service();
#endif
for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
cAudioScriptObject *object = cAudioScriptObject *object =
(cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]] (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]]
@ -9980,7 +9989,7 @@ cAudioManager::Terminate()
m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
PreTerminateGameSpecificShutdown(); PreTerminateGameSpecificShutdown();
for(uint32 i = 0; i < DIGITALCHANNELS; i++) { for(uint32 i = 0; i < MAX_SAMPLEBANKS; i++) {
if(SampleManager.IsSampleBankLoaded(i)) SampleManager.UnloadSampleBank(i); if(SampleManager.IsSampleBankLoaded(i)) SampleManager.UnloadSampleBank(i);
} }
@ -10032,7 +10041,7 @@ cAudioManager::UpdateReflections()
if(CWorld::ProcessVerticalLine( if(CWorld::ProcessVerticalLine(
camPos, m_avecReflectionsPos[4].z, colpoint, camPos, m_avecReflectionsPos[4].z, colpoint,
ent, true, false, false, false, true, false, ent, true, false, false, false, true, false,
false)) { nil)) {
m_afReflectionsDistances[4] = m_afReflectionsDistances[4] =
colpoint.point.z - camPos.z; colpoint.point.z - camPos.z;
} else { } else {
@ -10144,217 +10153,3 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa
quatIntensity; quatIntensity;
return emittingVolume; return emittingVolume;
} }
// STARTPATCHES
// InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
// InjectHook(0x56AD30, &cAudioManager::AddPlayerCarSample, PATCH_JUMP);
// InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
// InjectHook(0x57B8D0, &cAudioManager::AddReleasingSounds, PATCH_JUMP);
// InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
// InjectHook(0x5697A0, &cAudioManager::CalculateDistance, PATCH_JUMP);
// InjectHook(0x57AA10, &cAudioManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
// InjectHook(0x57C160, &cAudioManager::ClearActiveSamples, PATCH_JUMP);
// InjectHook(0x5796A0, &cAudioManager::ClearMissionAudio, PATCH_JUMP);
// InjectHook(0x57C120, &cAudioManager::ClearRequestedQueue, PATCH_JUMP);
// InjectHook(0x57AE00, &cAudioManager::ComputeDopplerEffectedFrequency, PATCH_JUMP);
// InjectHook(0x57AD20, &cAudioManager::ComputePan, PATCH_JUMP);
// InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
// InjectHook(0x57A310, &cAudioManager::CreateEntity, PATCH_JUMP);
// InjectHook(0x57A830, &cAudioManager::DestroyAllGameCreatedEntities, PATCH_JUMP);
// InjectHook(0x57A400, &cAudioManager::DestroyEntity, PATCH_JUMP);
// InjectHook(0x57C290, &cAudioManager::GenerateIntegerRandomNumberTable, PATCH_JUMP);
// InjectHook(0x57A8C0, &cAudioManager::Get3DProviderName, PATCH_JUMP);
// InjectHook(0x571110, &cAudioManager::GetArmyTalkSfx, PATCH_JUMP);
// InjectHook(0x573AB0, &cAudioManager::GetBlackBusinessFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x572050, &cAudioManager::GetBlackCasualFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574380, &cAudioManager::GetBlackConstructionWorkerTalkSfx, PATCH_JUMP);
// InjectHook(0x571D80, &cAudioManager::GetBlackCriminalTalkSfx, PATCH_JUMP);
// InjectHook(0x5735E0, &cAudioManager::GetBlackDockerMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5724D0, &cAudioManager::GetBlackFatFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5726C0, &cAudioManager::GetBlackFatMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5728B0, &cAudioManager::GetBlackFemaleProstituteTalkSfx, PATCH_JUMP);
// InjectHook(0x572C20, &cAudioManager::GetBlackProjectFemaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x572D20, &cAudioManager::GetBlackProjectFemaleYoungTalkSfx, PATCH_JUMP);
// InjectHook(0x572AF0, &cAudioManager::GetBlackProjectMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5739C0, &cAudioManager::GetBlackWorkerMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574FF0, &cAudioManager::GetBomberTalkSfx, PATCH_JUMP);
// InjectHook(0x5712C0, &cAudioManager::GetBusinessMaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x5713E0, &cAudioManager::GetBusinessMaleYoungTalkSfx, PATCH_JUMP);
// InjectHook(0x572040, &cAudioManager::GetCasualMaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x574FE0, &cAudioManager::GetCatatalinaTalkSfx, PATCH_JUMP);
// InjectHook(0x57AA30, &cAudioManager::GetCDAudioDriveLetter, PATCH_JUMP);
// InjectHook(0x573010, &cAudioManager::GetChinatownFemaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x5730F0, &cAudioManager::GetChinatownFemaleYoungTalkSfx, PATCH_JUMP);
// InjectHook(0x572E10, &cAudioManager::GetChinatownMaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x572F10, &cAudioManager::GetChinatownMaleYoungTalkSfx, PATCH_JUMP);
// InjectHook(0x575120, &cAudioManager::GetChunkyTalkSfx, PATCH_JUMP);
// InjectHook(0x571B00, &cAudioManager::GetColumbianTalkSfx, PATCH_JUMP);
// InjectHook(0x570EA0, &cAudioManager::GetCopTalkSfx, PATCH_JUMP);
// InjectHook(0x57A8F0, &cAudioManager::GetCurrent3DProviderIndex, PATCH_JUMP);
// InjectHook(0x571770, &cAudioManager::GetDiabloTalkSfx, PATCH_JUMP);
// InjectHook(0x569750, &cAudioManager::GetDistanceSquared, PATCH_JUMP);
// InjectHook(0x574DA0, &cAudioManager::GetEightTalkSfx, PATCH_JUMP);
// InjectHook(0x574040, &cAudioManager::GetFanFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x573F60, &cAudioManager::GetFanMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x571040, &cAudioManager::GetFBITalkSfx, PATCH_JUMP);
// InjectHook(0x572280, &cAudioManager::GetFemaleNo3TalkSfx, PATCH_JUMP);
// InjectHook(0x5712B0, &cAudioManager::GetFiremanTalkSfx, PATCH_JUMP);
// InjectHook(0x574E50, &cAudioManager::GetFrankieTalkSfx, PATCH_JUMP);
// InjectHook(0x575510, &cAudioManager::GetGenericFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x575460, &cAudioManager::GetGenericMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x571C30, &cAudioManager::GetHoodTalkSfx, PATCH_JUMP);
// InjectHook(0x5741F0, &cAudioManager::GetHospitalFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574120, &cAudioManager::GetHospitalMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x56F410, &cAudioManager::GetJumboTaxiFreq, PATCH_JUMP);
// InjectHook(0x573310, &cAudioManager::GetLittleItalyFemaleOldTalkSfx, PATCH_JUMP);
// InjectHook(0x573400, &cAudioManager::GetLittleItalyFemaleYoungTalkSfx, PATCH_JUMP);
// InjectHook(0x5731E0, &cAudioManager::GetLittleItalyMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x571510, &cAudioManager::GetMafiaTalkSfx, PATCH_JUMP);
// InjectHook(0x571F40, &cAudioManager::GetMaleNo2TalkSfx, PATCH_JUMP);
// InjectHook(0x5711C0, &cAudioManager::GetMedicTalkSfx, PATCH_JUMP);
// InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP);
// InjectHook(0x574F00, &cAudioManager::GetMistyTalkSfx, PATCH_JUMP);
// InjectHook(0x575340, &cAudioManager::GetNormalMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x57A8A0, &cAudioManager::GetNum3DProvidersAvailable, PATCH_JUMP);
// InjectHook(0x574FD0, &cAudioManager::GetOJGTalkSfx, PATCH_JUMP);
// InjectHook(0x570960, &cAudioManager::GetPedCommentSfx, PATCH_JUMP);
// InjectHook(0x570DB0, &cAudioManager::GetPhrase, PATCH_JUMP);
// InjectHook(0x56BF80, &cAudioManager::GetVehicleDriveWheelSkidValue, PATCH_JUMP);
// InjectHook(0x56C120, &cAudioManager::GetVehicleNonDriveWheelSkidValue, PATCH_JUMP);
// InjectHook(0x575240, &cAudioManager::GetPimpTalkSfx, PATCH_JUMP);
// InjectHook(0x570E00, &cAudioManager::GetPlayerTalkSfx, PATCH_JUMP);
// InjectHook(0x5737E0, &cAudioManager::GetScumFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5736D0, &cAudioManager::GetScumMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x575060, &cAudioManager::GetSecurityGuardTalkSfx, PATCH_JUMP);
// InjectHook(0x574480, &cAudioManager::GetShopperFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574790, &cAudioManager::GetSpecialCharacterTalkSfx, PATCH_JUMP);
// InjectHook(0x573E90, &cAudioManager::GetStewardFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x573DC0, &cAudioManager::GetStewardMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574690, &cAudioManager::GetStudentFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574590, &cAudioManager::GetStudentMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x573CD0, &cAudioManager::GetSupermodelFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x573BD0, &cAudioManager::GetSupermodelMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x570F80, &cAudioManager::GetSwatTalkSfx, PATCH_JUMP);
// InjectHook(0x575190, &cAudioManager::GetTaxiDriverTalkSfx, PATCH_JUMP);
// InjectHook(0x571650, &cAudioManager::GetTriadTalkSfx, PATCH_JUMP);
// InjectHook(0x5723A0, &cAudioManager::GetWhiteBusinessFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x572170, &cAudioManager::GetWhiteCasualFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x574290, &cAudioManager::GetWhiteConstructionWorkerTalkSfx, PATCH_JUMP);
// InjectHook(0x571E60, &cAudioManager::GetWhiteCriminalTalkSfx, PATCH_JUMP);
// InjectHook(0x5734F0, &cAudioManager::GetWhiteDockerMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5727B0, &cAudioManager::GetWhiteFatFemaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5725D0, &cAudioManager::GetWhiteFatMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5729D0, &cAudioManager::GetWhiteFemaleProstituteTalkSfx, PATCH_JUMP);
// InjectHook(0x5738D0, &cAudioManager::GetWhiteWorkerMaleTalkSfx, PATCH_JUMP);
// InjectHook(0x5718D0, &cAudioManager::GetYakuzaTalkSfx, PATCH_JUMP);
// InjectHook(0x5719E0, &cAudioManager::GetYardieTalkSfx, PATCH_JUMP);
// InjectHook(0x56CAB0, &cAudioManager::HasAirBrakes, PATCH_JUMP);
// InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
// InjectHook(0x57B030, &cAudioManager::InterrogateAudioEntities, PATCH_JUMP);
// InjectHook(0x57AA50, &cAudioManager::IsAudioInitialised, PATCH_JUMP);
// InjectHook(0x579650, &cAudioManager::IsMissionAudioSampleFinished, PATCH_JUMP);
// InjectHook(0x57A9C0, &cAudioManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
// InjectHook(0x579520, &cAudioManager::MissionScriptAudioUsesPoliceChannel, PATCH_JUMP);
// InjectHook(0x56AD10, &cAudioManager::PlayerJustGotInCar, PATCH_JUMP);
// InjectHook(0x56AD20, &cAudioManager::PlayerJustLeftCar, PATCH_JUMP);
// InjectHook(0x579620, &cAudioManager::PlayLoadedMissionAudio, PATCH_JUMP);
// InjectHook(0x57A500, &cAudioManager::PlayOneShot, PATCH_JUMP);
// InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
// InjectHook(0x569640, &cAudioManager::PostTerminateGameSpecificShutdown, PATCH_JUMP);
// InjectHook(0x569400, &cAudioManager::PreInitialiseGameSpecificSetup, PATCH_JUMP);
// InjectHook(0x579550, &cAudioManager::PreloadMissionAudio, PATCH_JUMP);
// InjectHook(0x569570, &cAudioManager::PreTerminateGameSpecificShutdown, PATCH_JUMP);
// InjectHook(0x57BA60, &cAudioManager::ProcessActiveQueues, PATCH_JUMP);
// InjectHook(0x56C940, &cAudioManager::ProcessAirBrakes, PATCH_JUMP);
// InjectHook(0x577B30, &cAudioManager::ProcessAirportScriptObject, PATCH_JUMP);
// InjectHook(0x56DE80, &cAudioManager::ProcessBoatEngine, PATCH_JUMP);
// InjectHook(0x56E500, &cAudioManager::ProcessBoatMovingOverWater, PATCH_JUMP);
// InjectHook(0x5790D0, &cAudioManager::ProcessBridge, PATCH_JUMP);
// InjectHook(0x579250, &cAudioManager::ProcessBridgeMotor, PATCH_JUMP);
// InjectHook(0x579310, &cAudioManager::ProcessBridgeOneShots, PATCH_JUMP);
// InjectHook(0x579170, &cAudioManager::ProcessBridgeWarning, PATCH_JUMP);
// InjectHook(0x56CC20, &cAudioManager::ProcessCarBombTick, PATCH_JUMP);
// InjectHook(0x577CA0, &cAudioManager::ProcessCinemaScriptObject, PATCH_JUMP);
// InjectHook(0x577E50, &cAudioManager::ProcessDocksScriptObject, PATCH_JUMP);
// InjectHook(0x56CAF0, &cAudioManager::ProcessEngineDamage, PATCH_JUMP);
// InjectHook(0x569870, &cAudioManager::ProcessEntity, PATCH_JUMP);
// InjectHook(0x575AC0, &cAudioManager::ProcessExplosions, PATCH_JUMP);
// InjectHook(0x578FD0, &cAudioManager::ProcessFireHydrant, PATCH_JUMP);
// InjectHook(0x5785E0, &cAudioManager::ProcessFrontEnd, PATCH_JUMP);
// InjectHook(0x56E6A0, &cAudioManager::ProcessHelicopter, PATCH_JUMP);
// InjectHook(0x577FE0, &cAudioManager::ProcessHomeScriptObject, PATCH_JUMP);
// InjectHook(0x56E8F0, &cAudioManager::ProcessJumbo, PATCH_JUMP);
// InjectHook(0x56EA40, &cAudioManager::ProcessJumboAccel, PATCH_JUMP);
// InjectHook(0x56EE40, &cAudioManager::ProcessJumboDecel, PATCH_JUMP);
// InjectHook(0x56ECF0, &cAudioManager::ProcessJumboFlying, PATCH_JUMP);
// InjectHook(0x56ED10, &cAudioManager::ProcessJumboLanding, PATCH_JUMP);
// InjectHook(0x56EC00, &cAudioManager::ProcessJumboTakeOff, PATCH_JUMP);
// InjectHook(0x56EA10, &cAudioManager::ProcessJumboTaxi, PATCH_JUMP);
// InjectHook(0x5777E0, &cAudioManager::ProcessLaunderetteScriptObject, PATCH_JUMP);
// InjectHook(0x576770, &cAudioManager::ProcessLoopingScriptObject, PATCH_JUMP);
// InjectHook(0x5796E0, &cAudioManager::ProcessMissionAudio, PATCH_JUMP);
// InjectHook(0x56A050, &cAudioManager::ProcessModelCarEngine, PATCH_JUMP);
// InjectHook(0x5760C0, &cAudioManager::ProcessOneShotScriptObject, PATCH_JUMP);
// InjectHook(0x56F450, &cAudioManager::ProcessPed, PATCH_JUMP);
// InjectHook(0x56F4D0, &cAudioManager::ProcessPedHeadphones, PATCH_JUMP);
// InjectHook(0x56F650, &cAudioManager::ProcessPedOneShots, PATCH_JUMP);
// InjectHook(0x5699C0, &cAudioManager::ProcessPhysical, PATCH_JUMP);
// InjectHook(0x56E860, &cAudioManager::ProcessPlane, PATCH_JUMP);
// InjectHook(0x56B0D0, &cAudioManager::ProcessPlayersVehicleEngine, PATCH_JUMP);
// InjectHook(0x578190, &cAudioManager::ProcessPoliceCellBeatingScriptObject, PATCH_JUMP);
// InjectHook(0x577280, &cAudioManager::ProcessPornCinema, PATCH_JUMP);
// InjectHook(0x578A80, &cAudioManager::ProcessProjectiles, PATCH_JUMP);
// InjectHook(0x569CC0, &cAudioManager::ProcessRainOnVehicle, PATCH_JUMP);
// InjectHook(0x569700, &cAudioManager::ProcessReverb, PATCH_JUMP);
// InjectHook(0x569E50, &cAudioManager::ProcessReverseGear, PATCH_JUMP);
// InjectHook(0x577630, &cAudioManager::ProcessSawMillScriptObject, PATCH_JUMP);
// InjectHook(0x576070, &cAudioManager::ProcessScriptObject, PATCH_JUMP);
// InjectHook(0x577970, &cAudioManager::ProcessShopScriptObject, PATCH_JUMP);
// InjectHook(0x5697D0, &cAudioManager::ProcessSpecial, PATCH_JUMP);
// InjectHook(0x56DBF0, &cAudioManager::ProcessTrainNoise, PATCH_JUMP);
// InjectHook(0x569A00, &cAudioManager::ProcessVehicle, PATCH_JUMP);
// InjectHook(0x56C770, &cAudioManager::ProcessVehicleDoors, PATCH_JUMP);
// InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
// InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
// InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
// InjectHook(0x56C420, &cAudioManager::ProcessVehicleSirenOrAlarm, PATCH_JUMP);
// InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
// InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
// InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
// InjectHook(0x56A440, &cAudioManager::ProcessWetRoadNoise, PATCH_JUMP);
// InjectHook(0x577530, &cAudioManager::ProcessWorkShopScriptObject, PATCH_JUMP);
// InjectHook(0x57AF90, &cAudioManager::RandomDisplacement, PATCH_JUMP);
// InjectHook(0x57A9F0, &cAudioManager::ReacquireDigitalHandle, PATCH_JUMP);
// InjectHook(0x57A9E0, &cAudioManager::ReleaseDigitalHandle, PATCH_JUMP);
// InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP);
// InjectHook(0x57A7B0, &cAudioManager::ResetTimers, PATCH_JUMP);
// InjectHook(0x57A2A0, &cAudioManager::Service, PATCH_JUMP);
// InjectHook(0x57AA60, &cAudioManager::ServiceSoundEffects, PATCH_JUMP);
// InjectHook(0x57A910, &cAudioManager::SetCurrent3DProvider, PATCH_JUMP);
// InjectHook(0x57AA00, &cAudioManager::SetDynamicAcousticModelingStatus, PATCH_JUMP);
// InjectHook(0x57A770, &cAudioManager::SetEffectsFadeVolume, PATCH_JUMP);
// InjectHook(0x57A730, &cAudioManager::SetEffectsMasterVolume, PATCH_JUMP);
// InjectHook(0x57A4C0, &cAudioManager::SetEntityStatus, PATCH_JUMP);
// InjectHook(0x5795F0, &cAudioManager::SetMissionAudioLocation, PATCH_JUMP);
// InjectHook(0x57A790, &cAudioManager::SetMusicFadeVolume, PATCH_JUMP);
// InjectHook(0x57A750, &cAudioManager::SetMusicMasterVolume, PATCH_JUMP);
// InjectHook(0x57A9A0, &cAudioManager::SetSpeakerConfig, PATCH_JUMP);
// InjectHook(0x56F230, &cAudioManager::SetupJumboFlySound, PATCH_JUMP);
// InjectHook(0x56F310, &cAudioManager::SetupJumboRumbleSound, PATCH_JUMP);
// InjectHook(0x56EF20, &cAudioManager::SetupJumboTaxiSound, PATCH_JUMP);
// InjectHook(0x56F070, &cAudioManager::SetupJumboWhineSound, PATCH_JUMP);
// InjectHook(0x570690, &cAudioManager::SetupPedComments, PATCH_JUMP);
// InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
// InjectHook(0x57AC60, &cAudioManager::TranslateEntity, PATCH_JUMP);
// InjectHook(0x56AC80, &cAudioManager::UpdateGasPedalAudio, PATCH_JUMP);
// InjectHook(0x57B470, &cAudioManager::UpdateReflections, PATCH_JUMP);
// InjectHook(0x56C600, &cAudioManager::UsesReverseWarning, PATCH_JUMP);
// InjectHook(0x56C3C0, &cAudioManager::UsesSiren, PATCH_JUMP);
// InjectHook(0x56C3F0, &cAudioManager::UsesSirenSwitching, PATCH_JUMP);
// InjectHook(0x57C2B0, &cAudioManager::AdjustSamplesVolume, PATCH_JUMP);
// InjectHook(0x57C320, &cAudioManager::ComputeEmittingVolume, PATCH_JUMP);
// InjectHook(0x5755C0, &cPedComments::Add, PATCH_JUMP);
// InjectHook(0x575730, &cPedComments::Process, PATCH_JUMP);
// ENDPATCHES

View file

@ -118,7 +118,7 @@ enum eScriptSounds : int16 {
SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106, SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106,
SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107, SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107,
SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108, SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108,
SCRIPT_SOUND_109 = 109, SCRIPT_SOUND_BULLET_HIT_WATER = 109, //no sound
SCRIPT_SOUND_110 = 110, SCRIPT_SOUND_110 = 110,
SCRIPT_SOUND_111 = 111, SCRIPT_SOUND_111 = 111,
SCRIPT_SOUND_PAYPHONE_RINGING = 112, SCRIPT_SOUND_PAYPHONE_RINGING = 112,
@ -143,28 +143,17 @@ public:
int32 m_nSampleIndex; int32 m_nSampleIndex;
uint8 m_bBankIndex; uint8 m_bBankIndex;
bool m_bIs2D; bool m_bIs2D;
uint8 field_14; // unused
uint8 field_15; // unused
int32 m_nReleasingVolumeModificator; int32 m_nReleasingVolumeModificator;
int32 m_nFrequency; int32 m_nFrequency;
uint8 m_bVolume; uint8 m_bVolume;
uint8 field_25; // unused
uint8 field_26; // unused
uint8 field_27; // unused
float m_fDistance; float m_fDistance;
int32 m_nLoopCount; int32 m_nLoopCount;
int32 m_nLoopStart; int32 m_nLoopStart;
int32 m_nLoopEnd; int32 m_nLoopEnd;
uint8 m_bEmittingVolume; uint8 m_bEmittingVolume;
uint8 field_45; // unused
uint8 field_46; // unused
uint8 field_47; // unused
float m_fSpeedMultiplier; float m_fSpeedMultiplier;
float m_fSoundIntensity; float m_fSoundIntensity;
bool m_bReleasingSoundFlag; bool m_bReleasingSoundFlag;
uint8 field_57; // unused
uint8 field_58; // unused
uint8 field_59; // unused
CVector m_vecPos; CVector m_vecPos;
bool m_bReverbFlag; bool m_bReverbFlag;
uint8 m_bLoopsRemaining; uint8 m_bLoopsRemaining;
@ -173,15 +162,8 @@ public:
int32 m_nReleasingVolumeDivider; int32 m_nReleasingVolumeDivider;
bool m_bIsProcessed; bool m_bIsProcessed;
bool m_bLoopEnded; bool m_bLoopEnded;
uint8 field_82; // unused
uint8 field_83; // unused
int32 m_nCalculatedVolume; int32 m_nCalculatedVolume;
int8 m_nVolumeChange; int8 m_nVolumeChange;
uint8 field_89; // unused
uint8 field_90; // unused
uint8 field_91; // unused
// no methods
}; };
static_assert(sizeof(tSound) == 92, "tSound: error"); static_assert(sizeof(tSound) == 92, "tSound: error");
@ -197,12 +179,8 @@ public:
bool m_bIsUsed; bool m_bIsUsed;
uint8 m_bStatus; uint8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS]; int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
//uint8 gap_18[2];
float m_afVolume[NUM_AUDIOENTITY_EVENTS]; float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents; uint8 m_AudioEvents;
uint8 field_25[3];
// no methods
}; };
static_assert(sizeof(tAudioEntity) == 40, "tAudioEntity: error"); static_assert(sizeof(tAudioEntity) == 40, "tAudioEntity: error");
@ -216,8 +194,6 @@ public:
float m_fDistance; float m_fDistance;
uint8 m_bVolume; uint8 m_bVolume;
int8 m_nProcess; int8 m_nProcess;
// no methods
}; };
static_assert(sizeof(tPedComment) == 28, "tPedComment: error"); static_assert(sizeof(tPedComment) == 28, "tPedComment: error");
@ -244,18 +220,12 @@ class cMissionAudio
public: public:
CVector m_vecPos; CVector m_vecPos;
bool m_bPredefinedProperties; bool m_bPredefinedProperties;
//uint8 gap_13[3];
int m_nSampleIndex; int m_nSampleIndex;
uint8 m_bLoadingStatus; uint8 m_bLoadingStatus;
uint8 m_bPlayStatus; uint8 m_bPlayStatus;
uint8 field_22; // todo find a name uint8 field_22; // todo find a name
uint8 field_23; // unused
int32 m_nMissionAudioCounter; int32 m_nMissionAudioCounter;
bool m_bIsPlayed; bool m_bIsPlayed;
uint8 field_29; // unused
uint8 field_30; // unused
uint8 field_31; // unused
// no methods
}; };
static_assert(sizeof(cMissionAudio) == 32, "cMissionAudio: error"); static_assert(sizeof(cMissionAudio) == 32, "cMissionAudio: error");
@ -305,17 +275,11 @@ public:
uint8 m_bActiveSamples; uint8 m_bActiveSamples;
uint8 field_4; // unused uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus; bool m_bDynamicAcousticModelingStatus;
uint8 field_6; // unused
uint8 field_7; // unused
float m_fSpeedOfSound; float m_fSpeedOfSound;
bool m_bTimerJustReset; bool m_bTimerJustReset;
uint8 field_13; // unused
uint8 field_14; // unused
uint8 field_15; // unused
int32 m_nTimer; int32 m_nTimer;
tSound m_sQueueSample; tSound m_sQueueSample;
bool m_bActiveSampleQueue; bool m_bActiveSampleQueue;
uint8 gap_109[3]; // unused
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS]; tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS]; uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_bSampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS]; uint8 m_bSampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS];
@ -341,7 +305,6 @@ public:
uint8 m_bTimeSpent; uint8 m_bTimeSpent;
uint8 m_bUserPause; uint8 m_bUserPause;
uint8 m_bPreviousUserPause; uint8 m_bPreviousUserPause;
uint8 field_19195; // unused
uint32 m_FrameCounter; uint32 m_FrameCounter;
cAudioManager(); cAudioManager();
@ -618,6 +581,6 @@ public:
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
}; };
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error"); //dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
extern cAudioManager AudioManager; extern cAudioManager AudioManager;

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AudioScriptObject.h" #include "AudioScriptObject.h"
#include "Pools.h" #include "Pools.h"
#include "DMAudio.h" #include "DMAudio.h"
@ -86,10 +86,3 @@ PlayOneShotScriptObject(uint8 id, CVector const &pos)
audioScriptObject->AudioEntity = AEHANDLE_NONE; audioScriptObject->AudioEntity = AEHANDLE_NONE;
DMAudio.CreateOneShotScriptObject(audioScriptObject); DMAudio.CreateOneShotScriptObject(audioScriptObject);
} }
STARTPATCHES
InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP);
InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP);
InjectHook(0x57C560, &cAudioScriptObject::LoadAllAudioScriptObjects, PATCH_JUMP);
InjectHook(0x57c460, &cAudioScriptObject::SaveAllAudioScriptObjects, PATCH_JUMP);
ENDPATCHES

View file

@ -1,12 +1,12 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "MusicManager.h" #include "MusicManager.h"
#include "AudioManager.h" #include "AudioManager.h"
#include "AudioScriptObject.h" #include "AudioScriptObject.h"
#include "sampman.h" #include "sampman.h"
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE; cDMAudio DMAudio;
void void
cDMAudio::Initialise(void) cDMAudio::Initialise(void)
@ -318,57 +318,3 @@ cDMAudio::SetRadioChannel(int8 radio, int32 pos)
{ {
MusicManager.SetRadioChannelByScript(radio, pos); MusicManager.SetRadioChannelByScript(radio, pos);
} }
STARTPATCHES
InjectHook(0x57C760, &cDMAudio::Initialise, PATCH_JUMP);
InjectHook(0x57C780, &cDMAudio::Terminate, PATCH_JUMP);
InjectHook(0x57C7A0, &cDMAudio::Service, PATCH_JUMP);
InjectHook(0x57C7C0, &cDMAudio::CreateEntity, PATCH_JUMP);
InjectHook(0x57C7F0, &cDMAudio::DestroyEntity, PATCH_JUMP);
InjectHook(0x57C810, &cDMAudio::SetEntityStatus, PATCH_JUMP);
InjectHook(0x57C840, &cDMAudio::PlayOneShot, PATCH_JUMP);
InjectHook(0x57C870, &cDMAudio::DestroyAllGameCreatedEntities, PATCH_JUMP);
InjectHook(0x57C890, &cDMAudio::SetEffectsMasterVolume, PATCH_JUMP);
InjectHook(0x57C8C0, &cDMAudio::SetMusicMasterVolume, PATCH_JUMP);
InjectHook(0x57C8F0, &cDMAudio::SetEffectsFadeVol, PATCH_JUMP);
InjectHook(0x57C920, &cDMAudio::SetMusicFadeVol, PATCH_JUMP);
InjectHook(0x57C950, &cDMAudio::GetNum3DProvidersAvailable, PATCH_JUMP);
InjectHook(0x57C970, &cDMAudio::Get3DProviderName, PATCH_JUMP);
InjectHook(0x57C990, &cDMAudio::GetCurrent3DProviderIndex, PATCH_JUMP);
InjectHook(0x57C9B0, &cDMAudio::SetCurrent3DProvider, PATCH_JUMP);
InjectHook(0x57C9D0, &cDMAudio::SetSpeakerConfig, PATCH_JUMP);
InjectHook(0x57C9F0, &cDMAudio::IsMP3RadioChannelAvailable, PATCH_JUMP);
InjectHook(0x57CA10, &cDMAudio::ReleaseDigitalHandle, PATCH_JUMP);
InjectHook(0x57CA30, &cDMAudio::ReacquireDigitalHandle, PATCH_JUMP);
InjectHook(0x57CA50, &cDMAudio::SetDynamicAcousticModelingStatus, PATCH_JUMP);
InjectHook(0x57CA70, &cDMAudio::CheckForAnAudioFileOnCD, PATCH_JUMP);
InjectHook(0x57CA90, &cDMAudio::GetCDAudioDriveLetter, PATCH_JUMP);
InjectHook(0x57CAB0, &cDMAudio::IsAudioInitialised, PATCH_JUMP);
InjectHook(0x57CAD0, &cDMAudio::ReportCrime, PATCH_JUMP);
InjectHook(0x57CB00, &cDMAudio::CreateLoopingScriptObject, PATCH_JUMP);
InjectHook(0x57CB40, &cDMAudio::DestroyLoopingScriptObject, PATCH_JUMP);
InjectHook(0x57CB60, &cDMAudio::CreateOneShotScriptObject, PATCH_JUMP);
InjectHook(0x57CBB0, &cDMAudio::PlaySuspectLastSeen, PATCH_JUMP);
InjectHook(0x57CBE0, &cDMAudio::ReportCollision, PATCH_JUMP);
InjectHook(0x57CC20, &cDMAudio::PlayFrontEndSound, PATCH_JUMP);
InjectHook(0x57CC60, &cDMAudio::PlayRadioAnnouncement, PATCH_JUMP);
InjectHook(0x57CC80, &cDMAudio::PlayFrontEndTrack, PATCH_JUMP);
InjectHook(0x57CCB0, &cDMAudio::StopFrontEndTrack, PATCH_JUMP);
InjectHook(0x57CCD0, &cDMAudio::ResetTimers, PATCH_JUMP);
InjectHook(0x57CCF0, &cDMAudio::ChangeMusicMode, PATCH_JUMP);
InjectHook(0x57CD10, &cDMAudio::PreloadCutSceneMusic, PATCH_JUMP);
InjectHook(0x57CD30, &cDMAudio::PlayPreloadedCutSceneMusic, PATCH_JUMP);
InjectHook(0x57CD50, &cDMAudio::StopCutSceneMusic, PATCH_JUMP);
InjectHook(0x57CD70, &cDMAudio::PreloadMissionAudio, PATCH_JUMP);
InjectHook(0x57CD90, &cDMAudio::GetMissionAudioLoadingStatus, PATCH_JUMP);
InjectHook(0x57CDB0, &cDMAudio::SetMissionAudioLocation, PATCH_JUMP);
InjectHook(0x57CDE0, &cDMAudio::PlayLoadedMissionAudio, PATCH_JUMP);
InjectHook(0x57CE00, &cDMAudio::IsMissionAudioSampleFinished, PATCH_JUMP);
InjectHook(0x57CE20, &cDMAudio::ClearMissionAudio, PATCH_JUMP);
InjectHook(0x57CE40, &cDMAudio::GetRadioInCar, PATCH_JUMP);
InjectHook(0x57CE60, &cDMAudio::SetRadioInCar, PATCH_JUMP);
InjectHook(0x57CE80, &cDMAudio::SetRadioChannel, PATCH_JUMP);
//InjectHook(0x57CEB0, `global constructor keyed to'dmaudio.cpp, PATCH_JUMP);
//InjectHook(0x57CED0, cDMAudio::~cDMAudio, PATCH_JUMP);
ENDPATCHES

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "audio_enums.h" #include "audio_enums.h"
#include "Crime.h"
enum eSound : int16 enum eSound : int16
{ {
@ -179,7 +180,6 @@ enum eSound : int16
class cAudioScriptObject; class cAudioScriptObject;
class CEntity; class CEntity;
enum eCrimeType;
class cDMAudio class cDMAudio
{ {
@ -256,4 +256,4 @@ public:
void SetRadioInCar(uint32 radio); void SetRadioInCar(uint32 radio);
void SetRadioChannel(int8 radio, int32 pos); void SetRadioChannel(int8 radio, int32 pos);
}; };
extern cDMAudio &DMAudio; extern cDMAudio DMAudio;

View file

@ -13,12 +13,12 @@
#include "Timer.h" #include "Timer.h"
#include "World.h" #include "World.h"
#include "sampman.h" #include "sampman.h"
#include "patcher.h"
cMusicManager &MusicManager = *(cMusicManager *)0x8F3964;
int32 &gNumRetunePresses = *(int32 *)0x650B80; cMusicManager MusicManager;
int32 &gRetuneCounter = *(int32*)0x650B84; int32 gNumRetunePresses;
bool& bHasStarted = *(bool*)0x650B7C; int32 gRetuneCounter;
bool bHasStarted;
const int maxVolume = 127; const int maxVolume = 127;
@ -51,6 +51,12 @@ cMusicManager::PlayerInCar()
if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED) if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
return false; return false;
if (!FindPlayerVehicle())
return true;
if (FindPlayerVehicle()->m_status == STATUS_WRECKED)
return false;
switch(FindPlayerVehicle()->m_modelIndex) { switch(FindPlayerVehicle()->m_modelIndex) {
case MI_FIRETRUCK: case MI_FIRETRUCK:
case MI_AMBULAN: case MI_AMBULAN:
@ -699,7 +705,7 @@ cMusicManager::GetTrackStartPos(uint8 track)
result = m_aTracks[track].m_nPosition; result = m_aTracks[track].m_nPosition;
m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
} else } else
result = min(CTimer::GetTimeInMillisecondsPauseMode() - timer, 90000) + m_aTracks[track].m_nPosition; result = Min(CTimer::GetTimeInMillisecondsPauseMode() - timer, 90000) + m_aTracks[track].m_nPosition;
if (result > m_aTracks[track].m_nLength) result %= m_aTracks[track].m_nLength; if (result > m_aTracks[track].m_nLength) result %= m_aTracks[track].m_nLength;
return result; return result;
@ -904,34 +910,3 @@ cMusicManager::ChangeRadioChannel()
} }
return true; return true;
} }
STARTPATCHES
InjectHook(0x57E4B0, &cMusicManager::PlayerInCar, PATCH_JUMP);
InjectHook(0x57E6D0, &cMusicManager::DisplayRadioStationName, PATCH_JUMP);
InjectHook(0x57CF70, &cMusicManager::Initialise, PATCH_JUMP);
InjectHook(0x57D140, &cMusicManager::Terminate, PATCH_JUMP);
InjectHook(0x57D1D0, &cMusicManager::GetRadioInCar, PATCH_JUMP);
InjectHook(0x57D2C0, &cMusicManager::SetRadioInCar, PATCH_JUMP);
InjectHook(0x57D180, &cMusicManager::SetRadioChannelByScript, PATCH_JUMP);
InjectHook(0x57CF30, &cMusicManager::ResetMusicAfterReload, PATCH_JUMP);
InjectHook(0x57E6A0, &cMusicManager::UsesPoliceRadio, PATCH_JUMP);
InjectHook(0x57D310, &cMusicManager::ChangeMusicMode, PATCH_JUMP);
InjectHook(0x57D420, &cMusicManager::ResetTimers, PATCH_JUMP);
InjectHook(0x57D440, &cMusicManager::Service, PATCH_JUMP);
InjectHook(0x57D530, &cMusicManager::ServiceFrontEndMode, PATCH_JUMP);
InjectHook(0x57E3D0, &cMusicManager::StopFrontEndTrack, PATCH_JUMP);
InjectHook(0x57E430, &cMusicManager::PlayAnnouncement, PATCH_JUMP);
InjectHook(0x57E2E0, &cMusicManager::PlayFrontEndTrack, PATCH_JUMP);
InjectHook(0x57E210, &cMusicManager::PreloadCutSceneMusic, PATCH_JUMP);
InjectHook(0x57E290, &cMusicManager::PlayPreloadedCutSceneMusic, PATCH_JUMP);
InjectHook(0x57E2B0, &cMusicManager::StopCutSceneMusic, PATCH_JUMP);
InjectHook(0x57E450, &cMusicManager::GetTrackStartPos, PATCH_JUMP);
InjectHook(0x57D690, &cMusicManager::ServiceGameMode, PATCH_JUMP);
InjectHook(0x57DCB0, &cMusicManager::ServiceAmbience, PATCH_JUMP);
InjectHook(0x57DEA0, &cMusicManager::ComputeAmbienceVol, PATCH_JUMP);
InjectHook(0x57E100, &cMusicManager::ServiceTrack, PATCH_JUMP);
InjectHook(0x57DFC0, &cMusicManager::ServiceAnnouncement, PATCH_JUMP);
InjectHook(0x57E530, &cMusicManager::GetCarTuning, PATCH_JUMP);
InjectHook(0x57E5A0, &cMusicManager::GetNextCarTuning, PATCH_JUMP);
InjectHook(0x57E130, &cMusicManager::ChangeRadioChannel, PATCH_JUMP);
ENDPATCHES

View file

@ -86,4 +86,4 @@ public:
static_assert(sizeof(cMusicManager) == 0x95C, "cMusicManager: error"); static_assert(sizeof(cMusicManager) == 0x95C, "cMusicManager: error");
extern cMusicManager &MusicManager; extern cMusicManager MusicManager;

View file

@ -1,15 +1,18 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "AudioManager.h" #include "AudioManager.h"
#include "AudioSamples.h" #include "AudioSamples.h"
#include "MusicManager.h" #include "MusicManager.h"
#include "PoliceRadio.h"
#include "PlayerPed.h" #include "PlayerPed.h"
#include "sampman.h" #include "PoliceRadio.h"
#include "Zones.h" #include "Replay.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "World.h" #include "World.h"
#include "Zones.h"
#include "sampman.h"
const int maxVolume = 127; const int maxVolume = 127;
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
@ -21,14 +24,14 @@ struct tPoliceRadioZone {
int32 field_12; int32 field_12;
}; };
tPoliceRadioZone (&ZoneSfx)[NUMAUDIOZONES] = *(tPoliceRadioZone(*)[NUMAUDIOZONES])*(uintptr*)0x880240; tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
char *SubZo2Label = (char*)0x6E9918; char SubZo2Label[8];
char *SubZo3Label = (char*)0x6E9870; char SubZo3Label[8];
int32 &g_nMissionAudioSfx = *(int32*)0x60ED84; int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 &g_nMissionAudioPlayingStatus = *(int8*)0x60ED88; int8 g_nMissionAudioPlayingStatus = 2;
uint8 &gSpecialSuspectLastSeenReport = *(uint8*)0x95CD4D; uint8 gSpecialSuspectLastSeenReport;
uint32 (&gMinTimeToNextReport)[NUM_CRIME_TYPES] = *(uint32(*)[NUM_CRIME_TYPES])*(uintptr*)0x8E2828; uint32 gMinTimeToNextReport[NUM_CRIME_TYPES];
void void
cAudioManager::InitialisePoliceRadioZones() cAudioManager::InitialisePoliceRadioZones()
@ -155,7 +158,8 @@ cAudioManager::ServicePoliceRadio()
if(!m_bUserPause) { if(!m_bUserPause) {
bool crimeReport = SetupCrimeReport(); bool crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef #ifdef FIX_BUGS // Crash at 0x5fe6ef
if(!FindPlayerPed() || !FindPlayerPed()->m_pWanted) return; if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
return;
#endif #endif
wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel; wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
if(!crimeReport) { if(!crimeReport) {
@ -774,19 +778,3 @@ cAudioManager::AgeCrimes()
} }
} }
} }
STARTPATCHES
InjectHook(0x580AF0, &cAudioManager::AgeCrimes, PATCH_JUMP);
InjectHook(0x57F060, &cAudioManager::DoPoliceRadioCrackle, PATCH_JUMP);
InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP);
InjectHook(0x57EEC0, &cAudioManager::InitialisePoliceRadio, PATCH_JUMP);
InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);
InjectHook(0x580500, &cAudioManager::PlaySuspectLastSeen, PATCH_JUMP);
InjectHook(0x5803D0, &cAudioManager::ReportCrime, PATCH_JUMP);
InjectHook(0x57EFF0, &cAudioManager::ResetPoliceRadio, PATCH_JUMP);
InjectHook(0x57F110, &cAudioManager::ServicePoliceRadio, PATCH_JUMP);
InjectHook(0x57F1B0, &cAudioManager::ServicePoliceRadioChannel, PATCH_JUMP);
InjectHook(0x57F020, &cAudioManager::SetMissionScriptPoliceAudio, PATCH_JUMP);
InjectHook(0x57F5B0, &cAudioManager::SetupCrimeReport, PATCH_JUMP);
InjectHook(0x57FCC0, &cAudioManager::SetupSuspectLastSeenReport, PATCH_JUMP);
ENDPATCHES

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,339 @@
#pragma once
#include "common.h"
#include "AudioSamples.h"
#define MAX_VOLUME 127
struct tSample {
int32 nOffset;
uint32 nSize;
int32 nFrequency;
int32 nLoopStart;
int32 nLoopEnd;
};
enum
{
SAMPLEBANK_MAIN,
SAMPLEBANK_PED,
MAX_SAMPLEBANKS,
SAMPLEBANK_INVALID
};
#define MAX_PEDSFX 7
#define PED_BLOCKSIZE 79000
#define MAXPROVIDERS 64
#define MAXCHANNELS 28
#define MAXCHANNELS_SURROUND 24
#define MAX2DCHANNELS 1
#define CHANNEL2D MAXCHANNELS
#define MAX_MP3STREAMS 2
#define DIGITALRATE 32000
#define DIGITALBITS 16
#define DIGITALCHANNELS 2
#define MAX_DIGITAL_MIXER_CHANNELS 32
class cSampleManager
{
uint8 m_nEffectsVolume;
uint8 m_nMusicVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
uint8 m_nMonoMode;
char unk;
char m_szCDRomRootPath[80];
bool m_bInitialised;
uint8 m_nNumberOfProviders;
char *m_aAudioProviders[MAXPROVIDERS];
tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
public:
cSampleManager(void) :
m_nNumberOfProviders(0)
{ }
~cSampleManager(void)
{ }
void SetSpeakerConfig(int32 nConfig);
uint32 GetMaximumSupportedChannels(void);
uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
bool IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle (void);
void ReacquireDigitalHandle(void);
bool Initialise(void);
void Terminate (void);
bool CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
void UpdateEffectsVolume(void);
void SetEffectsMasterVolume(uint8 nVolume);
void SetMusicMasterVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
bool LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank);
bool IsSampleBankLoaded(uint8 nBank);
bool IsPedCommentLoaded(uint32 nComment);
bool LoadPedComment (uint32 nComment);
int32 _GetPedCommentSlot(uint32 nComment);
int32 GetSampleBaseFrequency (uint32 nSample);
int32 GetSampleLoopStartOffset(uint32 nSample);
int32 GetSampleLoopEndOffset (uint32 nSample);
uint32 GetSampleLength (uint32 nSample);
bool UpdateReverb(void);
void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
void SetChannelVolume (uint32 nChannel, uint32 nVolume);
void SetChannelPan (uint32 nChannel, uint32 nPan);
void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
bool GetChannelUsedFlag (uint32 nChannel);
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
void PreloadStreamedFile (uint8 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
int32 GetStreamedFileLength (uint8 nStream);
bool IsStreamPlaying (uint8 nStream);
bool InitialiseSampleBanks(void);
};
extern cSampleManager SampleManager;
extern int32 BankStartOffset[MAX_SAMPLEBANKS];
static char StreamedNameTable[][25]=
{
"AUDIO\\HEAD.WAV",
"AUDIO\\CLASS.WAV",
"AUDIO\\KJAH.WAV",
"AUDIO\\RISE.WAV",
"AUDIO\\LIPS.WAV",
"AUDIO\\GAME.WAV",
"AUDIO\\MSX.WAV",
"AUDIO\\FLASH.WAV",
"AUDIO\\CHAT.WAV",
"AUDIO\\HEAD.WAV",
"AUDIO\\POLICE.WAV",
"AUDIO\\CITY.WAV",
"AUDIO\\WATER.WAV",
"AUDIO\\COMOPEN.WAV",
"AUDIO\\SUBOPEN.WAV",
"AUDIO\\JB.MP3",
"AUDIO\\BET.MP3",
"AUDIO\\L1_LG.MP3",
"AUDIO\\L2_DSB.MP3",
"AUDIO\\L3_DM.MP3",
"AUDIO\\L4_PAP.MP3",
"AUDIO\\L5_TFB.MP3",
"AUDIO\\J0_DM2.MP3",
"AUDIO\\J1_LFL.MP3",
"AUDIO\\J2_KCL.MP3",
"AUDIO\\J3_VH.MP3",
"AUDIO\\J4_ETH.MP3",
"AUDIO\\J5_DST.MP3",
"AUDIO\\J6_TBJ.MP3",
"AUDIO\\T1_TOL.MP3",
"AUDIO\\T2_TPU.MP3",
"AUDIO\\T3_MAS.MP3",
"AUDIO\\T4_TAT.MP3",
"AUDIO\\T5_BF.MP3",
"AUDIO\\S0_MAS.MP3",
"AUDIO\\S1_PF.MP3",
"AUDIO\\S2_CTG.MP3",
"AUDIO\\S3_RTC.MP3",
"AUDIO\\S5_LRQ.MP3",
"AUDIO\\S4_BDBA.MP3",
"AUDIO\\S4_BDBB.MP3",
"AUDIO\\S2_CTG2.MP3",
"AUDIO\\S4_BDBD.MP3",
"AUDIO\\S5_LRQB.MP3",
"AUDIO\\S5_LRQC.MP3",
"AUDIO\\A1_SSO.WAV",
"AUDIO\\A2_PP.WAV",
"AUDIO\\A3_SS.WAV",
"AUDIO\\A4_PDR.WAV",
"AUDIO\\A5_K2FT.WAV",
"AUDIO\\K1_KBO.MP3",
"AUDIO\\K2_GIS.MP3",
"AUDIO\\K3_DS.MP3",
"AUDIO\\K4_SHI.MP3",
"AUDIO\\K5_SD.MP3",
"AUDIO\\R0_PDR2.MP3",
"AUDIO\\R1_SW.MP3",
"AUDIO\\R2_AP.MP3",
"AUDIO\\R3_ED.MP3",
"AUDIO\\R4_GF.MP3",
"AUDIO\\R5_PB.MP3",
"AUDIO\\R6_MM.MP3",
"AUDIO\\D1_STOG.MP3",
"AUDIO\\D2_KK.MP3",
"AUDIO\\D3_ADO.MP3",
"AUDIO\\D5_ES.MP3",
"AUDIO\\D7_MLD.MP3",
"AUDIO\\D4_GTA.MP3",
"AUDIO\\D4_GTA2.MP3",
"AUDIO\\D6_STS.MP3",
"AUDIO\\A6_BAIT.WAV",
"AUDIO\\A7_ETG.WAV",
"AUDIO\\A8_PS.WAV",
"AUDIO\\A9_ASD.WAV",
"AUDIO\\K4_SHI2.MP3",
"AUDIO\\C1_TEX.MP3",
"AUDIO\\EL_PH1.MP3",
"AUDIO\\EL_PH2.MP3",
"AUDIO\\EL_PH3.MP3",
"AUDIO\\EL_PH4.MP3",
"AUDIO\\YD_PH1.MP3",
"AUDIO\\YD_PH2.MP3",
"AUDIO\\YD_PH3.MP3",
"AUDIO\\YD_PH4.MP3",
"AUDIO\\HD_PH1.MP3",
"AUDIO\\HD_PH2.MP3",
"AUDIO\\HD_PH3.MP3",
"AUDIO\\HD_PH4.MP3",
"AUDIO\\HD_PH5.MP3",
"AUDIO\\MT_PH1.MP3",
"AUDIO\\MT_PH2.MP3",
"AUDIO\\MT_PH3.MP3",
"AUDIO\\MT_PH4.MP3",
"AUDIO\\MISCOM.WAV",
"AUDIO\\END.MP3",
"AUDIO\\lib_a1.WAV",
"AUDIO\\lib_a2.WAV",
"AUDIO\\lib_a.WAV",
"AUDIO\\lib_b.WAV",
"AUDIO\\lib_c.WAV",
"AUDIO\\lib_d.WAV",
"AUDIO\\l2_a.WAV",
"AUDIO\\j4t_1.WAV",
"AUDIO\\j4t_2.WAV",
"AUDIO\\j4t_3.WAV",
"AUDIO\\j4t_4.WAV",
"AUDIO\\j4_a.WAV",
"AUDIO\\j4_b.WAV",
"AUDIO\\j4_c.WAV",
"AUDIO\\j4_d.WAV",
"AUDIO\\j4_e.WAV",
"AUDIO\\j4_f.WAV",
"AUDIO\\j6_1.WAV",
"AUDIO\\j6_a.WAV",
"AUDIO\\j6_b.WAV",
"AUDIO\\j6_c.WAV",
"AUDIO\\j6_d.WAV",
"AUDIO\\t4_a.WAV",
"AUDIO\\s1_a.WAV",
"AUDIO\\s1_a1.WAV",
"AUDIO\\s1_b.WAV",
"AUDIO\\s1_c.WAV",
"AUDIO\\s1_c1.WAV",
"AUDIO\\s1_d.WAV",
"AUDIO\\s1_e.WAV",
"AUDIO\\s1_f.WAV",
"AUDIO\\s1_g.WAV",
"AUDIO\\s1_h.WAV",
"AUDIO\\s1_i.WAV",
"AUDIO\\s1_j.WAV",
"AUDIO\\s1_k.WAV",
"AUDIO\\s1_l.WAV",
"AUDIO\\s3_a.WAV",
"AUDIO\\s3_b.WAV",
"AUDIO\\el3_a.WAV",
"AUDIO\\mf1_a.WAV",
"AUDIO\\mf2_a.WAV",
"AUDIO\\mf3_a.WAV",
"AUDIO\\mf3_b.WAV",
"AUDIO\\mf3_b1.WAV",
"AUDIO\\mf3_c.WAV",
"AUDIO\\mf4_a.WAV",
"AUDIO\\mf4_b.WAV",
"AUDIO\\mf4_c.WAV",
"AUDIO\\a1_a.WAV",
"AUDIO\\a3_a.WAV",
"AUDIO\\a5_a.WAV",
"AUDIO\\a4_a.WAV",
"AUDIO\\a4_b.WAV",
"AUDIO\\a4_c.WAV",
"AUDIO\\a4_d.WAV",
"AUDIO\\k1_a.WAV",
"AUDIO\\k3_a.WAV",
"AUDIO\\r1_a.WAV",
"AUDIO\\r2_a.WAV",
"AUDIO\\r2_b.WAV",
"AUDIO\\r2_c.WAV",
"AUDIO\\r2_d.WAV",
"AUDIO\\r2_e.WAV",
"AUDIO\\r2_f.WAV",
"AUDIO\\r2_g.WAV",
"AUDIO\\r2_h.WAV",
"AUDIO\\r5_a.WAV",
"AUDIO\\r6_a.WAV",
"AUDIO\\r6_a1.WAV",
"AUDIO\\r6_b.WAV",
"AUDIO\\lo2_a.WAV",
"AUDIO\\lo6_a.WAV",
"AUDIO\\yd2_a.WAV",
"AUDIO\\yd2_b.WAV",
"AUDIO\\yd2_c.WAV",
"AUDIO\\yd2_c1.WAV",
"AUDIO\\yd2_d.WAV",
"AUDIO\\yd2_e.WAV",
"AUDIO\\yd2_f.WAV",
"AUDIO\\yd2_g.WAV",
"AUDIO\\yd2_h.WAV",
"AUDIO\\yd2_ass.WAV",
"AUDIO\\yd2_ok.WAV",
"AUDIO\\h5_a.WAV",
"AUDIO\\h5_b.WAV",
"AUDIO\\h5_c.WAV",
"AUDIO\\ammu_a.WAV",
"AUDIO\\ammu_b.WAV",
"AUDIO\\ammu_c.WAV",
"AUDIO\\door_1.WAV",
"AUDIO\\door_2.WAV",
"AUDIO\\door_3.WAV",
"AUDIO\\door_4.WAV",
"AUDIO\\door_5.WAV",
"AUDIO\\door_6.WAV",
"AUDIO\\t3_a.WAV",
"AUDIO\\t3_b.WAV",
"AUDIO\\t3_c.WAV",
"AUDIO\\k1_b.WAV",
"AUDIO\\cat1.WAV"
};

File diff suppressed because it is too large Load diff

340
src/audio/openal/samp_oal.h Normal file
View file

@ -0,0 +1,340 @@
#pragma once
#include "common.h"
#include "AudioSamples.h"
#define MAX_VOLUME 127
//#define MAX_FREQ 22050
#define MAX_FREQ 32000
struct tSample {
int32 nOffset;
uint32 nSize;
int32 nFrequency;
int32 nLoopStart;
int32 nLoopEnd;
};
enum
{
SAMPLEBANK_MAIN,
SAMPLEBANK_PED,
MAX_SAMPLEBANKS,
SAMPLEBANK_INVALID
};
#define MAX_PEDSFX 7
#define PED_BLOCKSIZE 79000
//#define MAXCHANNELS 21 android
#define MAXCHANNELS 28
#define MAX2DCHANNELS 1
#define CHANNEL2D MAXCHANNELS
#define MAX_STREAMS 2
struct ALCdevice_struct;
struct ALCcontext_struct;
typedef struct ALCdevice_struct ALCdevice;
typedef struct ALCcontext_struct ALCcontext;
class cSampleManager
{
int field_0;
ALCdevice *m_pDevice;
ALCcontext *m_pContext;
uint8 m_nEffectsVolume;
uint8 m_nMusicVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
uint8 m_nMonoMode;
char _pad0[3];
tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
public:
cSampleManager(void);
~cSampleManager(void);
void SetSpeakerConfig(int32 nConfig);
uint32 GetMaximumSupportedChannels(void);
uint32 GetNum3DProvidersAvailable();
void SetNum3DProvidersAvailable(uint32 num);
char *Get3DProviderName(uint8 id);
void Set3DProviderName(uint8 id, char *name);
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
bool IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle (void);
void ReacquireDigitalHandle(void);
bool Initialise(void);
void Terminate (void);
void UpdateSoundBuffers(void);
bool CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
void UpdateEffectsVolume(void);
void SetEffectsMasterVolume(uint8 nVolume);
void SetMusicMasterVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
void SetMonoMode (uint8 nMode);
bool LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank);
bool IsSampleBankLoaded(uint8 nBank);
bool IsPedCommentLoaded(uint32 nComment);
bool LoadPedComment (uint32 nComment);
int32 GetBankContainingSound(uint32 offset);
int32 _GetPedCommentSlot(uint32 nComment);
int32 GetSampleBaseFrequency (uint32 nSample);
int32 GetSampleLoopStartOffset(uint32 nSample);
int32 GetSampleLoopEndOffset (uint32 nSample);
uint32 GetSampleLength (uint32 nSample);
bool UpdateReverb(void);
void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
void SetChannelVolume (uint32 nChannel, uint32 nVolume);
void SetChannelPan (uint32 nChannel, uint32 nPan);
void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
bool GetChannelUsedFlag (uint32 nChannel);
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
void PreloadStreamedFile (uint8 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
int32 GetStreamedFileLength (uint8 nStream);
bool IsStreamPlaying (uint8 nStream);
void Service(void);
bool InitialiseSampleBanks(void);
};
extern cSampleManager SampleManager;
extern int32 BankStartOffset[MAX_SAMPLEBANKS];
static char StreamedNameTable[][25]=
{
"AUDIO\\HEAD.MP3",
"AUDIO\\CLASS.MP3",
"AUDIO\\KJAH.MP3",
"AUDIO\\RISE.MP3",
"AUDIO\\LIPS.MP3",
"AUDIO\\GAME.MP3",
"AUDIO\\MSX.MP3",
"AUDIO\\FLASH.MP3",
"AUDIO\\CHAT.MP3",
"AUDIO\\HEAD.MP3",
"AUDIO\\POLICE.MP3",
"AUDIO\\CITY.MP3",
"AUDIO\\WATER.MP3",
"AUDIO\\COMOPEN.MP3",
"AUDIO\\SUBOPEN.MP3",
"AUDIO\\JB.MP3",
"AUDIO\\BET.MP3",
"AUDIO\\L1_LG.MP3",
"AUDIO\\L2_DSB.MP3",
"AUDIO\\L3_DM.MP3",
"AUDIO\\L4_PAP.MP3",
"AUDIO\\L5_TFB.MP3",
"AUDIO\\J0_DM2.MP3",
"AUDIO\\J1_LFL.MP3",
"AUDIO\\J2_KCL.MP3",
"AUDIO\\J3_VH.MP3",
"AUDIO\\J4_ETH.MP3",
"AUDIO\\J5_DST.MP3",
"AUDIO\\J6_TBJ.MP3",
"AUDIO\\T1_TOL.MP3",
"AUDIO\\T2_TPU.MP3",
"AUDIO\\T3_MAS.MP3",
"AUDIO\\T4_TAT.MP3",
"AUDIO\\T5_BF.MP3",
"AUDIO\\S0_MAS.MP3",
"AUDIO\\S1_PF.MP3",
"AUDIO\\S2_CTG.MP3",
"AUDIO\\S3_RTC.MP3",
"AUDIO\\S5_LRQ.MP3",
"AUDIO\\S4_BDBA.MP3",
"AUDIO\\S4_BDBB.MP3",
"AUDIO\\S2_CTG2.MP3",
"AUDIO\\S4_BDBD.MP3",
"AUDIO\\S5_LRQB.MP3",
"AUDIO\\S5_LRQC.MP3",
"AUDIO\\A1_SSO.MP3",
"AUDIO\\A2_PP.MP3",
"AUDIO\\A3_SS.MP3",
"AUDIO\\A4_PDR.MP3",
"AUDIO\\A5_K2FT.MP3",
"AUDIO\\K1_KBO.MP3",
"AUDIO\\K2_GIS.MP3",
"AUDIO\\K3_DS.MP3",
"AUDIO\\K4_SHI.MP3",
"AUDIO\\K5_SD.MP3",
"AUDIO\\R0_PDR2.MP3",
"AUDIO\\R1_SW.MP3",
"AUDIO\\R2_AP.MP3",
"AUDIO\\R3_ED.MP3",
"AUDIO\\R4_GF.MP3",
"AUDIO\\R5_PB.MP3",
"AUDIO\\R6_MM.MP3",
"AUDIO\\D1_STOG.MP3",
"AUDIO\\D2_KK.MP3",
"AUDIO\\D3_ADO.MP3",
"AUDIO\\D5_ES.MP3",
"AUDIO\\D7_MLD.MP3",
"AUDIO\\D4_GTA.MP3",
"AUDIO\\D4_GTA2.MP3",
"AUDIO\\D6_STS.MP3",
"AUDIO\\A6_BAIT.MP3",
"AUDIO\\A7_ETG.MP3",
"AUDIO\\A8_PS.MP3",
"AUDIO\\A9_ASD.MP3",
"AUDIO\\K4_SHI2.MP3",
"AUDIO\\C1_TEX.MP3",
"AUDIO\\EL_PH1.MP3",
"AUDIO\\EL_PH2.MP3",
"AUDIO\\EL_PH3.MP3",
"AUDIO\\EL_PH4.MP3",
"AUDIO\\YD_PH1.MP3",
"AUDIO\\YD_PH2.MP3",
"AUDIO\\YD_PH3.MP3",
"AUDIO\\YD_PH4.MP3",
"AUDIO\\HD_PH1.MP3",
"AUDIO\\HD_PH2.MP3",
"AUDIO\\HD_PH3.MP3",
"AUDIO\\HD_PH4.MP3",
"AUDIO\\HD_PH5.MP3",
"AUDIO\\MT_PH1.MP3",
"AUDIO\\MT_PH2.MP3",
"AUDIO\\MT_PH3.MP3",
"AUDIO\\MT_PH4.MP3",
"AUDIO\\MISCOM.MP3",
"AUDIO\\END.MP3",
"AUDIO\\lib_a1.MP3",
"AUDIO\\lib_a2.MP3",
"AUDIO\\lib_a.MP3",
"AUDIO\\lib_b.MP3",
"AUDIO\\lib_c.MP3",
"AUDIO\\lib_d.MP3",
"AUDIO\\l2_a.MP3",
"AUDIO\\j4t_1.MP3",
"AUDIO\\j4t_2.MP3",
"AUDIO\\j4t_3.MP3",
"AUDIO\\j4t_4.MP3",
"AUDIO\\j4_a.MP3",
"AUDIO\\j4_b.MP3",
"AUDIO\\j4_c.MP3",
"AUDIO\\j4_d.MP3",
"AUDIO\\j4_e.MP3",
"AUDIO\\j4_f.MP3",
"AUDIO\\j6_1.MP3",
"AUDIO\\j6_a.MP3",
"AUDIO\\j6_b.MP3",
"AUDIO\\j6_c.MP3",
"AUDIO\\j6_d.MP3",
"AUDIO\\t4_a.MP3",
"AUDIO\\s1_a.MP3",
"AUDIO\\s1_a1.MP3",
"AUDIO\\s1_b.MP3",
"AUDIO\\s1_c.MP3",
"AUDIO\\s1_c1.MP3",
"AUDIO\\s1_d.MP3",
"AUDIO\\s1_e.MP3",
"AUDIO\\s1_f.MP3",
"AUDIO\\s1_g.MP3",
"AUDIO\\s1_h.MP3",
"AUDIO\\s1_i.MP3",
"AUDIO\\s1_j.MP3",
"AUDIO\\s1_k.MP3",
"AUDIO\\s1_l.MP3",
"AUDIO\\s3_a.MP3",
"AUDIO\\s3_b.MP3",
"AUDIO\\el3_a.MP3",
"AUDIO\\mf1_a.MP3",
"AUDIO\\mf2_a.MP3",
"AUDIO\\mf3_a.MP3",
"AUDIO\\mf3_b.MP3",
"AUDIO\\mf3_b1.MP3",
"AUDIO\\mf3_c.MP3",
"AUDIO\\mf4_a.MP3",
"AUDIO\\mf4_b.MP3",
"AUDIO\\mf4_c.MP3",
"AUDIO\\a1_a.MP3",
"AUDIO\\a3_a.MP3",
"AUDIO\\a5_a.MP3",
"AUDIO\\a4_a.MP3",
"AUDIO\\a4_b.MP3",
"AUDIO\\a4_c.MP3",
"AUDIO\\a4_d.MP3",
"AUDIO\\k1_a.MP3",
"AUDIO\\k3_a.MP3",
"AUDIO\\r1_a.MP3",
"AUDIO\\r2_a.MP3",
"AUDIO\\r2_b.MP3",
"AUDIO\\r2_c.MP3",
"AUDIO\\r2_d.MP3",
"AUDIO\\r2_e.MP3",
"AUDIO\\r2_f.MP3",
"AUDIO\\r2_g.MP3",
"AUDIO\\r2_h.MP3",
"AUDIO\\r5_a.MP3",
"AUDIO\\r6_a.MP3",
"AUDIO\\r6_a1.MP3",
"AUDIO\\r6_b.MP3",
"AUDIO\\lo2_a.MP3",
"AUDIO\\lo6_a.MP3",
"AUDIO\\yd2_a.MP3",
"AUDIO\\yd2_b.MP3",
"AUDIO\\yd2_c.MP3",
"AUDIO\\yd2_c1.MP3",
"AUDIO\\yd2_d.MP3",
"AUDIO\\yd2_e.MP3",
"AUDIO\\yd2_f.MP3",
"AUDIO\\yd2_g.MP3",
"AUDIO\\yd2_h.MP3",
"AUDIO\\yd2_ass.MP3",
"AUDIO\\yd2_ok.MP3",
"AUDIO\\h5_a.MP3",
"AUDIO\\h5_b.MP3",
"AUDIO\\h5_c.MP3",
"AUDIO\\ammu_a.MP3",
"AUDIO\\ammu_b.MP3",
"AUDIO\\ammu_c.MP3",
"AUDIO\\door_1.MP3",
"AUDIO\\door_2.MP3",
"AUDIO\\door_3.MP3",
"AUDIO\\door_4.MP3",
"AUDIO\\door_5.MP3",
"AUDIO\\door_6.MP3",
"AUDIO\\t3_a.MP3",
"AUDIO\\t3_b.MP3",
"AUDIO\\t3_c.MP3",
"AUDIO\\k1_b.MP3",
"AUDIO\\cat1.MP3"
};

File diff suppressed because it is too large Load diff

View file

@ -1,339 +1,7 @@
#pragma once #pragma once
#include "common.h" #include "common.h"
#include "AudioSamples.h" #ifndef OPENAL
#include "miles\sampman_mss.h"
#define MAX_VOLUME 127 #else
#include "openal\samp_oal.h"
struct tSample { #endif
int32 nOffset;
uint32 nSize;
int32 nFrequency;
int32 nLoopStart;
int32 nLoopEnd;
};
enum
{
SAMPLEBANK_MAIN,
SAMPLEBANK_PED,
MAX_SAMPLEBANKS,
SAMPLEBANK_INVALID
};
#define MAX_PEDSFX 7
#define PED_BLOCKSIZE 79000
#define MAXPROVIDERS 64
#define MAXCHANNELS 28
#define MAXCHANNELS_SURROUND 24
#define MAX2DCHANNELS 1
#define CHANNEL2D MAXCHANNELS
#define MAX_MP3STREAMS 2
#define DIGITALRATE 32000
#define DIGITALBITS 16
#define DIGITALCHANNELS 2
#define MAX_DIGITAL_MIXER_CHANNELS 32
class cSampleManager
{
uint8 m_nEffectsVolume;
uint8 m_nMusicVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
uint8 m_nMonoMode;
char _pad0[1];
char m_szCDRomRootPath[80];
bool m_bInitialised;
uint8 m_nNumberOfProviders;
char *m_aAudioProviders[MAXPROVIDERS];
tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
public:
cSampleManager(void) :
m_nNumberOfProviders(0)
{ }
~cSampleManager(void)
{ }
void SetSpeakerConfig(int32 nConfig);
uint32 GetMaximumSupportedChannels(void);
uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
bool IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle (void);
void ReacquireDigitalHandle(void);
bool Initialise(void);
void Terminate (void);
bool CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
void UpdateEffectsVolume(void);
void SetEffectsMasterVolume(uint8 nVolume);
void SetMusicMasterVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
bool LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank);
bool IsSampleBankLoaded(uint8 nBank);
bool IsPedCommentLoaded(uint32 nComment);
bool LoadPedComment (uint32 nComment);
int32 _GetPedCommentSlot(uint32 nComment);
int32 GetSampleBaseFrequency (uint32 nSample);
int32 GetSampleLoopStartOffset(uint32 nSample);
int32 GetSampleLoopEndOffset (uint32 nSample);
uint32 GetSampleLength (uint32 nSample);
bool UpdateReverb(void);
void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
void SetChannelVolume (uint32 nChannel, uint32 nVolume);
void SetChannelPan (uint32 nChannel, uint32 nPan);
void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
bool GetChannelUsedFlag (uint32 nChannel);
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
void PreloadStreamedFile (uint8 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
int32 GetStreamedFileLength (uint8 nStream);
bool IsStreamPlaying (uint8 nStream);
bool InitialiseSampleBanks(void);
};
extern cSampleManager &SampleManager;
extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS];
static char StreamedNameTable[][25]=
{
"AUDIO\\HEAD.WAV",
"AUDIO\\CLASS.WAV",
"AUDIO\\KJAH.WAV",
"AUDIO\\RISE.WAV",
"AUDIO\\LIPS.WAV",
"AUDIO\\GAME.WAV",
"AUDIO\\MSX.WAV",
"AUDIO\\FLASH.WAV",
"AUDIO\\CHAT.WAV",
"AUDIO\\HEAD.WAV",
"AUDIO\\POLICE.WAV",
"AUDIO\\CITY.WAV",
"AUDIO\\WATER.WAV",
"AUDIO\\COMOPEN.WAV",
"AUDIO\\SUBOPEN.WAV",
"AUDIO\\JB.MP3",
"AUDIO\\BET.MP3",
"AUDIO\\L1_LG.MP3",
"AUDIO\\L2_DSB.MP3",
"AUDIO\\L3_DM.MP3",
"AUDIO\\L4_PAP.MP3",
"AUDIO\\L5_TFB.MP3",
"AUDIO\\J0_DM2.MP3",
"AUDIO\\J1_LFL.MP3",
"AUDIO\\J2_KCL.MP3",
"AUDIO\\J3_VH.MP3",
"AUDIO\\J4_ETH.MP3",
"AUDIO\\J5_DST.MP3",
"AUDIO\\J6_TBJ.MP3",
"AUDIO\\T1_TOL.MP3",
"AUDIO\\T2_TPU.MP3",
"AUDIO\\T3_MAS.MP3",
"AUDIO\\T4_TAT.MP3",
"AUDIO\\T5_BF.MP3",
"AUDIO\\S0_MAS.MP3",
"AUDIO\\S1_PF.MP3",
"AUDIO\\S2_CTG.MP3",
"AUDIO\\S3_RTC.MP3",
"AUDIO\\S5_LRQ.MP3",
"AUDIO\\S4_BDBA.MP3",
"AUDIO\\S4_BDBB.MP3",
"AUDIO\\S2_CTG2.MP3",
"AUDIO\\S4_BDBD.MP3",
"AUDIO\\S5_LRQB.MP3",
"AUDIO\\S5_LRQC.MP3",
"AUDIO\\A1_SSO.WAV",
"AUDIO\\A2_PP.WAV",
"AUDIO\\A3_SS.WAV",
"AUDIO\\A4_PDR.WAV",
"AUDIO\\A5_K2FT.WAV",
"AUDIO\\K1_KBO.MP3",
"AUDIO\\K2_GIS.MP3",
"AUDIO\\K3_DS.MP3",
"AUDIO\\K4_SHI.MP3",
"AUDIO\\K5_SD.MP3",
"AUDIO\\R0_PDR2.MP3",
"AUDIO\\R1_SW.MP3",
"AUDIO\\R2_AP.MP3",
"AUDIO\\R3_ED.MP3",
"AUDIO\\R4_GF.MP3",
"AUDIO\\R5_PB.MP3",
"AUDIO\\R6_MM.MP3",
"AUDIO\\D1_STOG.MP3",
"AUDIO\\D2_KK.MP3",
"AUDIO\\D3_ADO.MP3",
"AUDIO\\D5_ES.MP3",
"AUDIO\\D7_MLD.MP3",
"AUDIO\\D4_GTA.MP3",
"AUDIO\\D4_GTA2.MP3",
"AUDIO\\D6_STS.MP3",
"AUDIO\\A6_BAIT.WAV",
"AUDIO\\A7_ETG.WAV",
"AUDIO\\A8_PS.WAV",
"AUDIO\\A9_ASD.WAV",
"AUDIO\\K4_SHI2.MP3",
"AUDIO\\C1_TEX.MP3",
"AUDIO\\EL_PH1.MP3",
"AUDIO\\EL_PH2.MP3",
"AUDIO\\EL_PH3.MP3",
"AUDIO\\EL_PH4.MP3",
"AUDIO\\YD_PH1.MP3",
"AUDIO\\YD_PH2.MP3",
"AUDIO\\YD_PH3.MP3",
"AUDIO\\YD_PH4.MP3",
"AUDIO\\HD_PH1.MP3",
"AUDIO\\HD_PH2.MP3",
"AUDIO\\HD_PH3.MP3",
"AUDIO\\HD_PH4.MP3",
"AUDIO\\HD_PH5.MP3",
"AUDIO\\MT_PH1.MP3",
"AUDIO\\MT_PH2.MP3",
"AUDIO\\MT_PH3.MP3",
"AUDIO\\MT_PH4.MP3",
"AUDIO\\MISCOM.WAV",
"AUDIO\\END.MP3",
"AUDIO\\lib_a1.WAV",
"AUDIO\\lib_a2.WAV",
"AUDIO\\lib_a.WAV",
"AUDIO\\lib_b.WAV",
"AUDIO\\lib_c.WAV",
"AUDIO\\lib_d.WAV",
"AUDIO\\l2_a.WAV",
"AUDIO\\j4t_1.WAV",
"AUDIO\\j4t_2.WAV",
"AUDIO\\j4t_3.WAV",
"AUDIO\\j4t_4.WAV",
"AUDIO\\j4_a.WAV",
"AUDIO\\j4_b.WAV",
"AUDIO\\j4_c.WAV",
"AUDIO\\j4_d.WAV",
"AUDIO\\j4_e.WAV",
"AUDIO\\j4_f.WAV",
"AUDIO\\j6_1.WAV",
"AUDIO\\j6_a.WAV",
"AUDIO\\j6_b.WAV",
"AUDIO\\j6_c.WAV",
"AUDIO\\j6_d.WAV",
"AUDIO\\t4_a.WAV",
"AUDIO\\s1_a.WAV",
"AUDIO\\s1_a1.WAV",
"AUDIO\\s1_b.WAV",
"AUDIO\\s1_c.WAV",
"AUDIO\\s1_c1.WAV",
"AUDIO\\s1_d.WAV",
"AUDIO\\s1_e.WAV",
"AUDIO\\s1_f.WAV",
"AUDIO\\s1_g.WAV",
"AUDIO\\s1_h.WAV",
"AUDIO\\s1_i.WAV",
"AUDIO\\s1_j.WAV",
"AUDIO\\s1_k.WAV",
"AUDIO\\s1_l.WAV",
"AUDIO\\s3_a.WAV",
"AUDIO\\s3_b.WAV",
"AUDIO\\el3_a.WAV",
"AUDIO\\mf1_a.WAV",
"AUDIO\\mf2_a.WAV",
"AUDIO\\mf3_a.WAV",
"AUDIO\\mf3_b.WAV",
"AUDIO\\mf3_b1.WAV",
"AUDIO\\mf3_c.WAV",
"AUDIO\\mf4_a.WAV",
"AUDIO\\mf4_b.WAV",
"AUDIO\\mf4_c.WAV",
"AUDIO\\a1_a.WAV",
"AUDIO\\a3_a.WAV",
"AUDIO\\a5_a.WAV",
"AUDIO\\a4_a.WAV",
"AUDIO\\a4_b.WAV",
"AUDIO\\a4_c.WAV",
"AUDIO\\a4_d.WAV",
"AUDIO\\k1_a.WAV",
"AUDIO\\k3_a.WAV",
"AUDIO\\r1_a.WAV",
"AUDIO\\r2_a.WAV",
"AUDIO\\r2_b.WAV",
"AUDIO\\r2_c.WAV",
"AUDIO\\r2_d.WAV",
"AUDIO\\r2_e.WAV",
"AUDIO\\r2_f.WAV",
"AUDIO\\r2_g.WAV",
"AUDIO\\r2_h.WAV",
"AUDIO\\r5_a.WAV",
"AUDIO\\r6_a.WAV",
"AUDIO\\r6_a1.WAV",
"AUDIO\\r6_b.WAV",
"AUDIO\\lo2_a.WAV",
"AUDIO\\lo6_a.WAV",
"AUDIO\\yd2_a.WAV",
"AUDIO\\yd2_b.WAV",
"AUDIO\\yd2_c.WAV",
"AUDIO\\yd2_c1.WAV",
"AUDIO\\yd2_d.WAV",
"AUDIO\\yd2_e.WAV",
"AUDIO\\yd2_f.WAV",
"AUDIO\\yd2_g.WAV",
"AUDIO\\yd2_h.WAV",
"AUDIO\\yd2_ass.WAV",
"AUDIO\\yd2_ok.WAV",
"AUDIO\\h5_a.WAV",
"AUDIO\\h5_b.WAV",
"AUDIO\\h5_c.WAV",
"AUDIO\\ammu_a.WAV",
"AUDIO\\ammu_b.WAV",
"AUDIO\\ammu_c.WAV",
"AUDIO\\door_1.WAV",
"AUDIO\\door_2.WAV",
"AUDIO\\door_3.WAV",
"AUDIO\\door_4.WAV",
"AUDIO\\door_5.WAV",
"AUDIO\\door_6.WAV",
"AUDIO\\t3_a.WAV",
"AUDIO\\t3_b.WAV",
"AUDIO\\t3_c.WAV",
"AUDIO\\k1_b.WAV",
"AUDIO\\cat1.WAV"
};

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AutoPilot.h" #include "AutoPilot.h"
#include "CarCtrl.h" #include "CarCtrl.h"
@ -8,7 +8,7 @@
void CAutoPilot::ModifySpeed(float speed) void CAutoPilot::ModifySpeed(float speed)
{ {
m_fMaxTrafficSpeed = max(0.01f, speed); m_fMaxTrafficSpeed = Max(0.01f, speed);
float positionBetweenNodes = (float)(CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve) / m_nTimeToSpendOnCurrentCurve; float positionBetweenNodes = (float)(CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve) / m_nTimeToSpendOnCurrentCurve;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo]; CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[m_nNextPathNodeInfo]; CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[m_nNextPathNodeInfo];
@ -35,7 +35,7 @@ void CAutoPilot::ModifySpeed(float speed)
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
(uint32)(positionBetweenNodes * m_nTimeToSpendOnCurrentCurve); (uint32)(positionBetweenNodes * m_nTimeToSpendOnCurrentCurve);
#else #else
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nSpeedScaleFactor; m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nTimeToSpendOnCurrentCurve;
#endif #endif
} }

View file

@ -1,25 +1,25 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Bridge.h" #include "Bridge.h"
#include "Pools.h" #include "Pools.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "PathFind.h" #include "PathFind.h"
#include "Stats.h" #include "Stats.h"
CEntity*& CBridge::pLiftRoad = *(CEntity**)0x8E2C8C; CEntity *CBridge::pLiftRoad;
CEntity*& CBridge::pLiftPart = *(CEntity**)0x8E2C94; CEntity *CBridge::pLiftPart;
CEntity*& CBridge::pWeight = *(CEntity**)0x8E28BC; CEntity *CBridge::pWeight;
int& CBridge::State = *(int*)0x8F2A1C; int CBridge::State;
int& CBridge::OldState = *(int*)0x8F2A20; int CBridge::OldState;
float& CBridge::DefaultZLiftPart = *(float*)0x941430; float CBridge::DefaultZLiftPart;
float& CBridge::DefaultZLiftRoad = *(float*)0x941438; float CBridge::DefaultZLiftRoad;
float& CBridge::DefaultZLiftWeight = *(float*)0x8F1A44; float CBridge::DefaultZLiftWeight;
float& CBridge::OldLift = *(float*)0x8F6254; float CBridge::OldLift;
uint32& CBridge::TimeOfBridgeBecomingOperational = *(uint32*)0x8F2BC0; uint32 CBridge::TimeOfBridgeBecomingOperational;
void CBridge::Init() void CBridge::Init()
{ {
@ -144,11 +144,3 @@ bool CBridge::ThisIsABridgeObjectMovingUp(int index)
return State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP || State == STATE_LIFT_PART_MOVING_UP; return State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP || State == STATE_LIFT_PART_MOVING_UP;
} }
STARTPATCHES
InjectHook(0x413A30, &CBridge::Init, PATCH_JUMP);
InjectHook(0x413AC0, &CBridge::Update, PATCH_JUMP);
InjectHook(0x413D10, &CBridge::ShouldLightsBeFlashing, PATCH_JUMP);
InjectHook(0x413D20, &CBridge::FindBridgeEntities, PATCH_JUMP);
InjectHook(0x413DE0, &CBridge::ThisIsABridgeObjectMovingUp, PATCH_JUMP);
ENDPATCHES

View file

@ -14,11 +14,11 @@ enum bridgeStates {
class CBridge class CBridge
{ {
public: public:
static CEntity *&pLiftRoad, *&pLiftPart, *&pWeight; static CEntity *pLiftRoad, *pLiftPart, *pWeight;
static int &State, &OldState; static int State, OldState;
static float &DefaultZLiftPart, &DefaultZLiftRoad, &DefaultZLiftWeight; static float DefaultZLiftPart, DefaultZLiftRoad, DefaultZLiftWeight;
static float &OldLift; static float OldLift;
static uint32 &TimeOfBridgeBecomingOperational; static uint32 TimeOfBridgeBecomingOperational;
static void Init(); static void Init();
static void Update(); static void Update();

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "CarAI.h" #include "CarAI.h"
#include "Accident.h" #include "Accident.h"
@ -33,7 +33,6 @@ float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle)
void CCarAI::UpdateCarAI(CVehicle* pVehicle) void CCarAI::UpdateCarAI(CVehicle* pVehicle)
{ {
//((void(*)(CVehicle*))(0x413E50))(pVehicle);
//return; //return;
if (pVehicle->bIsLawEnforcer){ if (pVehicle->bIsLawEnforcer){
if (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_FARAWAY || if (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_FARAWAY ||
@ -375,7 +374,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 750; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 750;
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
if (pVehicle->VehicleCreatedBy == RANDOM_VEHICLE) if (pVehicle->VehicleCreatedBy == RANDOM_VEHICLE)
pVehicle->AutoPilot.m_nDrivingStyle = max(DRIVINGSTYLE_AVOID_CARS, pVehicle->AutoPilot.m_nDrivingStyle); pVehicle->AutoPilot.m_nDrivingStyle = Max(DRIVINGSTYLE_AVOID_CARS, pVehicle->AutoPilot.m_nDrivingStyle);
pVehicle->PlayCarHorn(); pVehicle->PlayCarHorn();
} }
} }
@ -511,7 +510,7 @@ void CCarAI::TellCarToRamOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar); pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_FARAWAY; pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_FARAWAY;
pVehicle->bEngineOn = true; pVehicle->bEngineOn = true;
pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed); pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
} }
void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget) void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
@ -520,7 +519,7 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar); pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_FARAWAY; pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_FARAWAY;
pVehicle->bEngineOn = true; pVehicle->bEngineOn = true;
pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed); pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
} }
eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() eCarMission CCarAI::FindPoliceCarMissionForWantedLevel()
{ {
@ -637,6 +636,3 @@ void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
} }
} }
} }
STARTPATCHES
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "CarCtrl.h" #include "CarCtrl.h"
#include "Accident.h" #include "Accident.h"
@ -67,25 +67,25 @@
#define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f #define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f
#define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f #define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f
int &CCarCtrl::NumLawEnforcerCars = *(int*)0x8F1B38; int CCarCtrl::NumLawEnforcerCars;
int &CCarCtrl::NumAmbulancesOnDuty = *(int*)0x885BB0; int CCarCtrl::NumAmbulancesOnDuty;
int &CCarCtrl::NumFiretrucksOnDuty = *(int*)0x9411F0; int CCarCtrl::NumFiretrucksOnDuty;
bool &CCarCtrl::bCarsGeneratedAroundCamera = *(bool*)0x95CD8A; bool CCarCtrl::bCarsGeneratedAroundCamera;
float& CCarCtrl::CarDensityMultiplier = *(float*)0x5EC8B4; float CCarCtrl::CarDensityMultiplier = 1.0f;
int32 &CCarCtrl::NumMissionCars = *(int32*)0x8F1B54; int32 CCarCtrl::NumMissionCars;
int32 &CCarCtrl::NumRandomCars = *(int32*)0x943118; int32 CCarCtrl::NumRandomCars;
int32 &CCarCtrl::NumParkedCars = *(int32*)0x8F29E0; int32 CCarCtrl::NumParkedCars;
int32 &CCarCtrl::NumPermanentCars = *(int32*)0x8F29F0; int32 CCarCtrl::NumPermanentCars;
int8 &CCarCtrl::CountDownToCarsAtStart = *(int8*)0x95CD63; int8 CCarCtrl::CountDownToCarsAtStart;
int32 &CCarCtrl::MaxNumberOfCarsInUse = *(int32*)0x5EC8B8; int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
uint32 &CCarCtrl::LastTimeLawEnforcerCreated = *(uint32*)0x8F5FF0; uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 &CCarCtrl::LastTimeFireTruckCreated = *(uint32*)0x880F5C; uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 &CCarCtrl::LastTimeAmbulanceCreated = *(uint32*)0x941450; uint32 CCarCtrl::LastTimeAmbulanceCreated;
int32 (&CCarCtrl::TotalNumOfCarsOfRating)[TOTAL_CUSTOM_CLASSES] = *(int32(*)[TOTAL_CUSTOM_CLASSES])*(uintptr*)0x8F1A60; int32 CCarCtrl::TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
int32 (&CCarCtrl::NextCarOfRating)[TOTAL_CUSTOM_CLASSES] = *(int32(*)[TOTAL_CUSTOM_CLASSES])*(uintptr*)0x9412AC; int32 CCarCtrl::NextCarOfRating[TOTAL_CUSTOM_CLASSES];
int32 (&CCarCtrl::CarArrays)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY] = *(int32(*)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY])*(uintptr*)0x6EB860; int32 CCarCtrl::CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP] = *(CVehicle*(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x70D830; CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP];
uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x87F9A8; uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP];
void void
CCarCtrl::GenerateRandomCars() CCarCtrl::GenerateRandomCars()
@ -362,7 +362,7 @@ CCarCtrl::GenerateOneRandomCar()
if (distanceBetweenNodes / 2 < carLength) if (distanceBetweenNodes / 2 < carLength)
positionBetweenNodes = 0.5f; positionBetweenNodes = 0.5f;
else else
positionBetweenNodes = min(1.0f - carLength / distanceBetweenNodes, max(carLength / distanceBetweenNodes, positionBetweenNodes)); positionBetweenNodes = Min(1.0f - carLength / distanceBetweenNodes, Max(carLength / distanceBetweenNodes, positionBetweenNodes));
pCar->AutoPilot.m_nNextDirection = (curNodeId >= nextNodeId) ? 1 : -1; pCar->AutoPilot.m_nNextDirection = (curNodeId >= nextNodeId) ? 1 : -1;
if (pCurNode->numLinks == 1){ if (pCurNode->numLinks == 1){
/* Do not create vehicle if there is nowhere to go. */ /* Do not create vehicle if there is nowhere to go. */
@ -426,7 +426,7 @@ CCarCtrl::GenerateOneRandomCar()
(uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve); (uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve);
#else #else
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
(0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nSpeedScaleFactor; (0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve;
#endif #endif
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f); CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
CVector directionNextLink(directionNextLinkX, directionNextLinkY, 0.0f); CVector directionNextLink(directionNextLinkX, directionNextLinkY, 0.0f);
@ -804,10 +804,10 @@ CCarCtrl::FindMaximumSpeedForThisCarInTraffic(CVehicle* pVehicle)
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER; float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER; float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER; float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
int xstart = max(0, CWorld::GetSectorIndexX(left)); int xstart = Max(0, CWorld::GetSectorIndexX(left));
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right)); int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
int ystart = max(0, CWorld::GetSectorIndexY(top)); int ystart = Max(0, CWorld::GetSectorIndexY(top));
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom)); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend); assert(xstart <= xend);
assert(ystart <= yend); assert(ystart <= yend);
@ -838,10 +838,10 @@ CCarCtrl::ScanForPedDanger(CVehicle* pVehicle)
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER; float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER; float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER; float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
int xstart = max(0, CWorld::GetSectorIndexX(left)); int xstart = Max(0, CWorld::GetSectorIndexX(left));
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right)); int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
int ystart = max(0, CWorld::GetSectorIndexY(top)); int ystart = Max(0, CWorld::GetSectorIndexY(top));
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom)); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend); assert(xstart <= xend);
assert(ystart <= yend); assert(ystart <= yend);
@ -873,12 +873,12 @@ CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
float curSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed; float curSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed;
if (maxSpeed >= curSpeed){ if (maxSpeed >= curSpeed){
if (maxSpeed > curSpeed) if (maxSpeed > curSpeed)
pVehicle->AutoPilot.ModifySpeed(min(maxSpeed, curSpeed + 0.05f * CTimer::GetTimeStep())); pVehicle->AutoPilot.ModifySpeed(Min(maxSpeed, curSpeed + 0.05f * CTimer::GetTimeStep()));
}else if (curSpeed != 0.0f) { }else if (curSpeed != 0.0f) {
if (curSpeed < 0.1f) if (curSpeed < 0.1f)
pVehicle->AutoPilot.ModifySpeed(0.0f); pVehicle->AutoPilot.ModifySpeed(0.0f);
else else
pVehicle->AutoPilot.ModifySpeed(max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep())); pVehicle->AutoPilot.ModifySpeed(Max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
} }
} }
@ -979,7 +979,7 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
if (distanceUntilHit < 10.0f){ if (distanceUntilHit < 10.0f){
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS || if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS ||
pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_SLOW_DOWN_FOR_CARS){ pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_SLOW_DOWN_FOR_CARS){
*pSpeed = min(*pSpeed, ABS(distanceUntilHit - 1.0f) * 0.1f * curSpeed); *pSpeed = Min(*pSpeed, ABS(distanceUntilHit - 1.0f) * 0.1f * curSpeed);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds = true; pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds = true;
if (distanceUntilHit < 2.0f){ if (distanceUntilHit < 2.0f){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT; pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
@ -1028,11 +1028,11 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
float projectionY = speedOtherY - forwardA.y * curSpeed; float projectionY = speedOtherY - forwardA.y * curSpeed;
float proximityA = TestCollisionBetween2MovingRects(pOtherVehicle, pVehicle, projectionX, projectionY, &forwardA, &forwardB, 0); float proximityA = TestCollisionBetween2MovingRects(pOtherVehicle, pVehicle, projectionX, projectionY, &forwardA, &forwardB, 0);
float proximityB = TestCollisionBetween2MovingRects(pVehicle, pOtherVehicle, -projectionX, -projectionY, &forwardB, &forwardA, 1); float proximityB = TestCollisionBetween2MovingRects(pVehicle, pOtherVehicle, -projectionX, -projectionY, &forwardB, &forwardA, 1);
float minProximity = min(proximityA, proximityB); float minProximity = Min(proximityA, proximityB);
if (minProximity >= 0.0f && minProximity < 1.0f){ if (minProximity >= 0.0f && minProximity < 1.0f){
minProximity = max(0.0f, (minProximity - 0.2f) * 1.25f); minProximity = Max(0.0f, (minProximity - 0.2f) * 1.25f);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfCars = true; pVehicle->AutoPilot.m_bSlowedDownBecauseOfCars = true;
*pSpeed = min(*pSpeed, minProximity * curSpeed); *pSpeed = Min(*pSpeed, minProximity * curSpeed);
} }
if (minProximity >= 0.0f && minProximity < 0.5f && pOtherEntity->IsVehicle() && if (minProximity >= 0.0f && minProximity < 0.5f && pOtherEntity->IsVehicle() &&
CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 15000 && CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 15000 &&
@ -1041,7 +1041,7 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
if (pOtherEntity != FindPlayerVehicle() && if (pOtherEntity != FindPlayerVehicle() &&
DotProduct2D(pVehicle->GetForward(), pOtherVehicle->GetForward()) < 0.5f && DotProduct2D(pVehicle->GetForward(), pOtherVehicle->GetForward()) < 0.5f &&
pVehicle < pOtherVehicle){ /* that comparasion though... */ pVehicle < pOtherVehicle){ /* that comparasion though... */
*pSpeed = max(curSpeed / 5, *pSpeed); *pSpeed = Max(curSpeed / 5, *pSpeed);
if (pVehicle->m_status == STATUS_SIMPLE){ if (pVehicle->m_status == STATUS_SIMPLE){
pVehicle->m_status = STATUS_PHYSICS; pVehicle->m_status = STATUS_PHYSICS;
SwitchVehicleToRealPhysics(pVehicle); SwitchVehicleToRealPhysics(pVehicle);
@ -1097,7 +1097,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityWidth = -(widthDistance - widthB) / widthProjection; float proximityWidth = -(widthDistance - widthB) / widthProjection;
if (proximityWidth < 1.0f){ if (proximityWidth < 1.0f){
baseWidthProximity = proximityWidth; baseWidthProximity = proximityWidth;
fullWidthProximity = min(1.0f, proximityWidth - fullWidthB / widthProjection); fullWidthProximity = Min(1.0f, proximityWidth - fullWidthB / widthProjection);
}else{ }else{
baseWidthProximity = 1.0f; baseWidthProximity = 1.0f;
} }
@ -1110,7 +1110,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityWidth = -(widthDistance + widthB) / widthProjection; float proximityWidth = -(widthDistance + widthB) / widthProjection;
if (proximityWidth < 1.0f) { if (proximityWidth < 1.0f) {
baseWidthProximity = proximityWidth; baseWidthProximity = proximityWidth;
fullWidthProximity = min(1.0f, proximityWidth + fullWidthB / widthProjection); fullWidthProximity = Min(1.0f, proximityWidth + fullWidthB / widthProjection);
} }
else { else {
baseWidthProximity = 1.0f; baseWidthProximity = 1.0f;
@ -1135,7 +1135,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityLength = -(lenDistance - lenB) / lenProjection; float proximityLength = -(lenDistance - lenB) / lenProjection;
if (proximityLength < 1.0f) { if (proximityLength < 1.0f) {
baseLengthProximity = proximityLength; baseLengthProximity = proximityLength;
fullLengthProximity = min(1.0f, proximityLength - fullLenB / lenProjection); fullLengthProximity = Min(1.0f, proximityLength - fullLenB / lenProjection);
} }
else { else {
baseLengthProximity = 1.0f; baseLengthProximity = 1.0f;
@ -1151,7 +1151,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityLength = -(lenDistance + backLenB) / lenProjection; float proximityLength = -(lenDistance + backLenB) / lenProjection;
if (proximityLength < 1.0f) { if (proximityLength < 1.0f) {
baseLengthProximity = proximityLength; baseLengthProximity = proximityLength;
fullLengthProximity = min(1.0f, proximityLength + fullLenB / lenProjection); fullLengthProximity = Min(1.0f, proximityLength + fullLenB / lenProjection);
} }
else { else {
baseLengthProximity = 1.0f; baseLengthProximity = 1.0f;
@ -1168,24 +1168,24 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
else if (lenProjection < 0.0f) { else if (lenProjection < 0.0f) {
fullLengthProximity = -(backLenB + lenDistance) / lenProjection; fullLengthProximity = -(backLenB + lenDistance) / lenProjection;
} }
float baseProximity = max(baseWidthProximity, baseLengthProximity); float baseProximity = Max(baseWidthProximity, baseLengthProximity);
if (baseProximity < fullWidthProximity && baseProximity < fullLengthProximity) if (baseProximity < fullWidthProximity && baseProximity < fullLengthProximity)
proximity = min(proximity, baseProximity); proximity = Min(proximity, baseProximity);
} }
return proximity; return proximity;
} }
float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward) float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward)
{ {
float distanceToTest = min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() * 2.5f + 1.0f) * 12.0f; float distanceToTest = Min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() * 2.5f + 1.0f) * 12.0f;
float left = pVehicle->GetPosition().x - distanceToTest; float left = pVehicle->GetPosition().x - distanceToTest;
float right = pVehicle->GetPosition().x + distanceToTest; float right = pVehicle->GetPosition().x + distanceToTest;
float top = pVehicle->GetPosition().y - distanceToTest; float top = pVehicle->GetPosition().y - distanceToTest;
float bottom = pVehicle->GetPosition().y + distanceToTest; float bottom = pVehicle->GetPosition().y + distanceToTest;
int xstart = max(0, CWorld::GetSectorIndexX(left)); int xstart = Max(0, CWorld::GetSectorIndexX(left));
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right)); int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
int ystart = max(0, CWorld::GetSectorIndexY(top)); int ystart = Max(0, CWorld::GetSectorIndexY(top));
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom)); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend); assert(xstart <= xend);
assert(ystart <= yend); assert(ystart <= yend);
@ -1566,8 +1566,8 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nNextLane -= 1; pVehicle->AutoPilot.m_nNextLane -= 1;
} }
} }
pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
}else{ }else{
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane; pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
} }
@ -1595,7 +1595,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve < 10) if (pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve < 10)
/* Oh hey there Obbe */ /* Oh hey there Obbe */
printf("fout\n"); printf("fout\n");
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
} }
uint8 CCarCtrl::FindPathDirection(int32 prevNode, int32 curNode, int32 nextNode) uint8 CCarCtrl::FindPathDirection(int32 prevNode, int32 curNode, int32 nextNode)
@ -1746,8 +1746,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
pVehicle->AutoPilot.m_nNextLane -= 1; pVehicle->AutoPilot.m_nNextLane -= 1;
} }
} }
pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
} }
else { else {
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane; pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
@ -1773,7 +1773,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
directionCurrentLinkX, directionCurrentLinkY, directionCurrentLinkX, directionCurrentLinkY,
directionNextLinkX, directionNextLinkY directionNextLinkX, directionNextLinkY
) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed); ) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed);
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
} }
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle) bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
@ -1826,8 +1826,8 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
else else
pVehicle->AutoPilot.m_nNextLane -= 1; pVehicle->AutoPilot.m_nNextLane -= 1;
} }
pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane); pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
} }
else { else {
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane; pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
@ -1853,7 +1853,7 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
directionCurrentLinkX, directionCurrentLinkY, directionCurrentLinkX, directionCurrentLinkY,
directionNextLinkX, directionNextLinkY directionNextLinkX, directionNextLinkY
) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed); ) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed);
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
return false; return false;
} }
@ -1965,7 +1965,7 @@ float CCarCtrl::FindSpeedMultiplier(float angleChange, float minAngle, float max
{ {
float angle = Abs(LimitRadianAngle(angleChange)); float angle = Abs(LimitRadianAngle(angleChange));
float n = angle - minAngle; float n = angle - minAngle;
n = max(0.0f, n); n = Max(0.0f, n);
float d = maxAngle - minAngle; float d = maxAngle - minAngle;
float mult = 1.0f - n / d * (1.0f - coef); float mult = 1.0f - n / d * (1.0f - coef);
if (n > d) if (n > d)
@ -2252,9 +2252,9 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
angleCurrentLink = FindAngleToWeaveThroughTraffic(pVehicle, nil, angleCurrentLink, angleForward); angleCurrentLink = FindAngleToWeaveThroughTraffic(pVehicle, nil, angleCurrentLink, angleForward);
float steerAngle = LimitRadianAngle(angleCurrentLink - angleForward); float steerAngle = LimitRadianAngle(angleCurrentLink - angleForward);
float maxAngle = FindMaxSteerAngle(pVehicle); float maxAngle = FindMaxSteerAngle(pVehicle);
steerAngle = min(maxAngle, max(-maxAngle, steerAngle)); steerAngle = Min(maxAngle, Max(-maxAngle, steerAngle));
if (pVehicle->GetMoveSpeed().Magnitude() > MIN_SPEED_TO_START_LIMITING_STEER) if (pVehicle->GetMoveSpeed().Magnitude() > MIN_SPEED_TO_START_LIMITING_STEER)
steerAngle = min(MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, max(-MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, steerAngle)); steerAngle = Min(MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, Max(-MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, steerAngle));
float currentForwardSpeed = DotProduct(pVehicle->GetMoveSpeed(), pVehicle->GetForward()) * GAME_SPEED_TO_CARAI_SPEED; float currentForwardSpeed = DotProduct(pVehicle->GetMoveSpeed(), pVehicle->GetForward()) * GAME_SPEED_TO_CARAI_SPEED;
float speedStyleMultiplier; float speedStyleMultiplier;
switch (pVehicle->AutoPilot.m_nDrivingStyle) { switch (pVehicle->AutoPilot.m_nDrivingStyle) {
@ -2298,21 +2298,21 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
speedNodesMultiplier = 1.0f - speedNodesMultiplier = 1.0f -
(1.0f - scalarDistanceToNextNode / DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN) * (1.0f - scalarDistanceToNextNode / DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN) *
(1.0f - tmpWideMultiplier); (1.0f - tmpWideMultiplier);
float speedMultiplier = min(speedStyleMultiplier, min(speedAngleMultiplier, speedNodesMultiplier)); float speedMultiplier = Min(speedStyleMultiplier, Min(speedAngleMultiplier, speedNodesMultiplier));
float speed = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier; float speed = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier;
float speedDifference = speed - currentForwardSpeed; float speedDifference = speed - currentForwardSpeed;
if (speed < 0.05f && speedDifference < 0.03f){ if (speed < 0.05f && speedDifference < 0.03f){
*pBrake = 1.0f; *pBrake = 1.0f;
*pAccel = 0.0f; *pAccel = 0.0f;
}else if (speedDifference <= 0.0f){ }else if (speedDifference <= 0.0f){
*pBrake = min(0.5f, -speedDifference * 0.05f); *pBrake = Min(0.5f, -speedDifference * 0.05f);
*pAccel = 0.0f; *pAccel = 0.0f;
}else if (currentForwardSpeed < 2.0f){ }else if (currentForwardSpeed < 2.0f){
*pBrake = 0.0f; *pBrake = 0.0f;
*pAccel = min(1.0f, speedDifference * 0.25f); *pAccel = Min(1.0f, speedDifference * 0.25f);
}else{ }else{
*pBrake = 0.0f; *pBrake = 0.0f;
*pAccel = min(1.0f, speedDifference * 0.125f); *pAccel = Min(1.0f, speedDifference * 0.125f);
} }
*pSwerve = steerAngle; *pSwerve = steerAngle;
*pHandbrake = false; *pHandbrake = false;
@ -2332,7 +2332,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
if (ABS(steerAngle) > MIN_ANGLE_TO_APPLY_HANDBRAKE) if (ABS(steerAngle) > MIN_ANGLE_TO_APPLY_HANDBRAKE)
*pHandbrake = true; *pHandbrake = true;
float maxAngle = FindMaxSteerAngle(pVehicle); float maxAngle = FindMaxSteerAngle(pVehicle);
steerAngle = min(maxAngle, max(-maxAngle, steerAngle)); steerAngle = Min(maxAngle, Max(-maxAngle, steerAngle));
float speedMultiplier = FindSpeedMultiplier(angleToTarget - angleForward, float speedMultiplier = FindSpeedMultiplier(angleToTarget - angleForward,
MIN_ANGLE_FOR_SPEED_LIMITING, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT); MIN_ANGLE_FOR_SPEED_LIMITING, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT);
float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier; float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier;
@ -2340,9 +2340,9 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
float speedDiff = speedTarget - currentSpeed; float speedDiff = speedTarget - currentSpeed;
if (speedDiff <= 0.0f){ if (speedDiff <= 0.0f){
*pAccel = 0.0f; *pAccel = 0.0f;
*pBrake = min(0.5f, -speedDiff * 0.05f); *pBrake = Min(0.5f, -speedDiff * 0.05f);
}else if (currentSpeed < 25.0f){ }else if (currentSpeed < 25.0f){
*pAccel = min(1.0f, speedDiff * 0.1f); *pAccel = Min(1.0f, speedDiff * 0.1f);
*pBrake = 0.0f; *pBrake = 0.0f;
}else{ }else{
*pAccel = 1.0f; *pAccel = 1.0f;
@ -2414,7 +2414,7 @@ void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CBoat* pBoat, float target
float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y); float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y);
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y); float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
float angleDiff = LimitRadianAngle(angleToTarget - angleForward); float angleDiff = LimitRadianAngle(angleToTarget - angleForward);
angleDiff = min(DEFAULT_MAX_STEER_ANGLE, max(-DEFAULT_MAX_STEER_ANGLE, angleDiff)); angleDiff = Min(DEFAULT_MAX_STEER_ANGLE, Max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason
float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f; float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f;
if (speedDiff > 0.0f){ if (speedDiff > 0.0f){
@ -2736,20 +2736,3 @@ bool CCarCtrl::MapCouldMoveInThisArea(float x, float y)
return x > -342.0f && x < -219.0f && return x > -342.0f && x < -219.0f &&
y > -677.0f && y < -580.0f; y > -677.0f && y < -580.0f;
} }
STARTPATCHES
InjectHook(0x416580, &CCarCtrl::GenerateRandomCars, PATCH_JUMP);
InjectHook(0x417EC0, &CCarCtrl::ChooseModel, PATCH_JUMP);
InjectHook(0x418320, &CCarCtrl::RemoveDistantCars, PATCH_JUMP);
InjectHook(0x418430, &CCarCtrl::PossiblyRemoveVehicle, PATCH_JUMP);
InjectHook(0x41D280, &CCarCtrl::Init, PATCH_JUMP);
InjectHook(0x41D3B0, &CCarCtrl::ReInit, PATCH_JUMP);
InjectHook(0x41E250, &CCarCtrl::SteerAIBoatWithPhysics, PATCH_JUMP);
InjectHook(0x41F6E0, &CCarCtrl::RegisterVehicleOfInterest, PATCH_JUMP);
InjectHook(0x41F780, &CCarCtrl::IsThisVehicleInteresting, PATCH_JUMP);
InjectHook(0x41F7A0, &CCarCtrl::RemoveFromInterestingVehicleList, PATCH_JUMP);
InjectHook(0x41F7D0, &CCarCtrl::ClearInterestingVehicleList, PATCH_JUMP);
InjectHook(0x41F7F0, &CCarCtrl::SwitchVehicleToRealPhysics, PATCH_JUMP);
InjectHook(0x41F820, &CCarCtrl::JoinCarWithRoadSystem, PATCH_JUMP);
InjectHook(0x41FA00, &CCarCtrl::JoinCarWithRoadSystemGotoCoors, PATCH_JUMP);
ENDPATCHES

View file

@ -120,23 +120,23 @@ public:
return angle; return angle;
} }
static int32 &NumLawEnforcerCars; static int32 NumLawEnforcerCars;
static int32 &NumAmbulancesOnDuty; static int32 NumAmbulancesOnDuty;
static int32 &NumFiretrucksOnDuty; static int32 NumFiretrucksOnDuty;
static int32 &NumRandomCars; static int32 NumRandomCars;
static int32 &NumMissionCars; static int32 NumMissionCars;
static int32 &NumParkedCars; static int32 NumParkedCars;
static int32 &NumPermanentCars; static int32 NumPermanentCars;
static bool &bCarsGeneratedAroundCamera; static bool bCarsGeneratedAroundCamera;
static float &CarDensityMultiplier; static float CarDensityMultiplier;
static int8 &CountDownToCarsAtStart; static int8 CountDownToCarsAtStart;
static int32 &MaxNumberOfCarsInUse; static int32 MaxNumberOfCarsInUse;
static uint32 &LastTimeLawEnforcerCreated; static uint32 LastTimeLawEnforcerCreated;
static uint32 &LastTimeFireTruckCreated; static uint32 LastTimeFireTruckCreated;
static uint32 &LastTimeAmbulanceCreated; static uint32 LastTimeAmbulanceCreated;
static int32 (&TotalNumOfCarsOfRating)[TOTAL_CUSTOM_CLASSES]; static int32 TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
static int32 (&NextCarOfRating)[TOTAL_CUSTOM_CLASSES]; static int32 NextCarOfRating[TOTAL_CUSTOM_CLASSES];
static int32 (&CarArrays)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY]; static int32 CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
}; };
extern CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP]; extern CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP];

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Curves.h" #include "Curves.h"
float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y) float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "main.h" #include "main.h"
#include "Darkel.h" #include "Darkel.h"
#include "PlayerPed.h" #include "PlayerPed.h"
@ -17,29 +17,29 @@
#define FRENZY_ANY_PED -1 #define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2 #define FRENZY_ANY_CAR -2
int32 &CDarkel::TimeLimit = *(int32*)0x885BAC; int32 CDarkel::TimeLimit;
int32 &CDarkel::PreviousTime = *(int32*)0x885B00; int32 CDarkel::PreviousTime;
int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8; int32 CDarkel::TimeOfFrenzyStart;
int32 &CDarkel::WeaponType = *(int32*)0x9430F0; int32 CDarkel::WeaponType;
int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8; int32 CDarkel::AmmoInterruptedWeapon;
int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8; int32 CDarkel::KillsNeeded;
int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60; int8 CDarkel::InterruptedWeapon;
/* /*
* bStandardSoundAndMessages is a completely beta thing, * bStandardSoundAndMessages is a completely beta thing,
* makes game handle sounds & messages instead of SCM (just like in GTA2) * makes game handle sounds & messages instead of SCM (just like in GTA2)
* but it's never been used in the game. Has unused sliding text when frenzy completed etc. * but it's never been used in the game. Has unused sliding text when frenzy completed etc.
*/ */
int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6; int8 CDarkel::bStandardSoundAndMessages;
int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA; int8 CDarkel::bNeedHeadShot;
int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98; int8 CDarkel::bProperKillFrenzy;
uint16 &CDarkel::Status = *(uint16*)0x95CCB4; uint16 CDarkel::Status;
uint16 (&CDarkel::RegisteredKills)[NUM_DEFAULT_MODELS] = *(uint16(*)[NUM_DEFAULT_MODELS]) * (uintptr*)0x6EDBE0; uint16 CDarkel::RegisteredKills[NUM_DEFAULT_MODELS];
int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78; int32 CDarkel::ModelToKill;
int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40; int32 CDarkel::ModelToKill2;
int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C; int32 CDarkel::ModelToKill3;
int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34; int32 CDarkel::ModelToKill4;
wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08; wchar *CDarkel::pStartMessage;
uint8 uint8
CDarkel::CalcFade(uint32 time, uint32 start, uint32 end) CDarkel::CalcFade(uint32 time, uint32 start, uint32 end)
@ -262,10 +262,10 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
pStartMessage = text; pStartMessage = text;
if (text == TheText.Get("PAGE_00")) { if (text == TheText.Get("PAGE_00")) {
CDarkel::bProperKillFrenzy = 1; CDarkel::bProperKillFrenzy = true;
CDarkel::pStartMessage = 0; CDarkel::pStartMessage = nil;
} else } else
bProperKillFrenzy = 0; bProperKillFrenzy = false;
bStandardSoundAndMessages = standardSound; bStandardSoundAndMessages = standardSound;
bNeedHeadShot = needHeadShot; bNeedHeadShot = needHeadShot;
@ -284,7 +284,7 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
if (FindPlayerVehicle()) { if (FindPlayerVehicle()) {
player->m_currentWeapon = player->m_nSelectedWepSlot; player->m_currentWeapon = player->m_nSelectedWepSlot;
player->GetWeapon()->m_nAmmoInClip = min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); player->GetWeapon()->m_nAmmoInClip = Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
player->ClearWeaponTarget(); player->ClearWeaponTarget();
} }
} }
@ -371,19 +371,3 @@ CDarkel::Update()
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0);
} }
} }
STARTPATCHES
InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP);
InjectHook(0x420650, CDarkel::Init, PATCH_JUMP);
InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);
InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP);
InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP);
InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP);
InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP);
InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP);
InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP);
InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP);
InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP);
InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP);
InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP);
ENDPATCHES

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "ModelIndices.h" #include "ModelIndices.h"
#include "WeaponType.h"
class CVehicle; class CVehicle;
class CPed; class CPed;
enum eWeaponType;
enum enum
{ {
@ -16,22 +17,22 @@ enum
class CDarkel class CDarkel
{ {
private: private:
static int32 &TimeLimit; static int32 TimeLimit;
static int32 &PreviousTime; static int32 PreviousTime;
static int32 &TimeOfFrenzyStart; static int32 TimeOfFrenzyStart;
static int32 &WeaponType; static int32 WeaponType;
static int32 &AmmoInterruptedWeapon; static int32 AmmoInterruptedWeapon;
static int32 &KillsNeeded; static int32 KillsNeeded;
static int8 &InterruptedWeapon; static int8 InterruptedWeapon;
static int8 &bStandardSoundAndMessages; static int8 bStandardSoundAndMessages;
static int8 &bNeedHeadShot; static int8 bNeedHeadShot;
static int8 &bProperKillFrenzy; static int8 bProperKillFrenzy;
static uint16 &Status; static uint16 Status;
static uint16 (&RegisteredKills)[NUM_DEFAULT_MODELS]; static uint16 RegisteredKills[NUM_DEFAULT_MODELS];
static int32 &ModelToKill; static int32 ModelToKill;
static int32 &ModelToKill2; static int32 ModelToKill2;
static int32 &ModelToKill3; static int32 ModelToKill3;
static int32 &ModelToKill4; static int32 ModelToKill4;
static wchar *pStartMessage; static wchar *pStartMessage;
public: public:

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "GameLogic.h" #include "GameLogic.h"
#include "Clock.h" #include "Clock.h"
#include "Stats.h" #include "Stats.h"
@ -20,7 +20,7 @@
#include "Script.h" #include "Script.h"
#include "Garages.h" #include "Garages.h"
uint8 CGameLogic::ActivePlayers; // 0x95CD5E uint8 CGameLogic::ActivePlayers;
void void
CGameLogic::InitAtStartOfGame() CGameLogic::InitAtStartOfGame()
@ -93,7 +93,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfHospitalFree) { if (pPlayerInfo.m_bGetOutOfHospitalFree) {
pPlayerInfo.m_bGetOutOfHospitalFree = false; pPlayerInfo.m_bGetOutOfHospitalFree = false;
} else { } else {
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000); pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 1000);
pPlayerInfo.m_pPed->ClearWeapons(); pPlayerInfo.m_pPed->ClearWeapons();
} }
@ -163,7 +163,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfJailFree) { if (pPlayerInfo.m_bGetOutOfJailFree) {
pPlayerInfo.m_bGetOutOfJailFree = false; pPlayerInfo.m_bGetOutOfJailFree = false;
} else { } else {
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney); pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - takeMoney);
pPlayerInfo.m_pPed->ClearWeapons(); pPlayerInfo.m_pPed->ClearWeapons();
} }
@ -284,11 +284,3 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
CWorld::Remove(pPlayerPed); CWorld::Remove(pPlayerPed);
CWorld::Add(pPlayerPed); CWorld::Add(pPlayerPed);
} }
STARTPATCHES
InjectHook(0x4213F0, &CGameLogic::InitAtStartOfGame, PATCH_JUMP);
InjectHook(0x421C00, &CGameLogic::PassTime, PATCH_JUMP);
InjectHook(0x421A20, &CGameLogic::SortOutStreamingAndMemory, PATCH_JUMP);
InjectHook(0x421400, &CGameLogic::Update, PATCH_JUMP);
InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Garages.h" #include "Garages.h"
#include "main.h" #include "main.h"
@ -111,27 +111,27 @@ const int32 gaCarsToCollectInCraigsGarages[TOTAL_COLLECTCARS_GARAGES][TOTAL_COLL
{ MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO } { MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO }
}; };
int32& CGarages::BankVansCollected = *(int32*)0x8F1B34; int32 CGarages::BankVansCollected;
bool& CGarages::BombsAreFree = *(bool*)0x95CD7A; bool CGarages::BombsAreFree;
bool& CGarages::RespraysAreFree = *(bool*)0x95CD1D; bool CGarages::RespraysAreFree;
int32& CGarages::CarsCollected = *(int32*)0x880E18; int32 CGarages::CarsCollected;
int32(&CGarages::CarTypesCollected)[TOTAL_COLLECTCARS_GARAGES] = *(int32(*)[TOTAL_COLLECTCARS_GARAGES]) * (uintptr*)0x8E286C; int32 CGarages::CarTypesCollected[TOTAL_COLLECTCARS_GARAGES];
int32& CGarages::CrushedCarId = *(int32*)0x943060; int32 CGarages::CrushedCarId;
uint32& CGarages::LastTimeHelpMessage = *(uint32*)0x8F1B58; uint32 CGarages::LastTimeHelpMessage;
int32& CGarages::MessageNumberInString = *(int32*)0x885BA8; int32 CGarages::MessageNumberInString;
char(&CGarages::MessageIDString)[MESSAGE_LENGTH] = *(char(*)[MESSAGE_LENGTH]) * (uintptr*)0x878358; char CGarages::MessageIDString[MESSAGE_LENGTH];
int32& CGarages::MessageNumberInString2 = *(int32*)0x8E2C14; int32 CGarages::MessageNumberInString2;
uint32& CGarages::MessageStartTime = *(uint32*)0x8F2530; uint32 CGarages::MessageStartTime;
uint32& CGarages::MessageEndTime = *(uint32*)0x8F597C; uint32 CGarages::MessageEndTime;
uint32& CGarages::NumGarages = *(uint32*)0x8F29F4; uint32 CGarages::NumGarages;
bool& CGarages::PlayerInGarage = *(bool*)0x95CD83; bool CGarages::PlayerInGarage;
int32& CGarages::PoliceCarsCollected = *(int32*)0x941444; int32 CGarages::PoliceCarsCollected;
CStoredCar(&CGarages::aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA210; CStoredCar CGarages::aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
CStoredCar(&CGarages::aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA300; CStoredCar CGarages::aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
CStoredCar(&CGarages::aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA3F0; CStoredCar CGarages::aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
int32& CGarages::AudioEntity = *(int32*)0x5ECEA8; int32 CGarages::AudioEntity = AEHANDLE_NONE;
CGarage(&CGarages::aGarages)[NUM_GARAGES] = *(CGarage(*)[NUM_GARAGES]) * (uintptr*)0x72BCD0; CGarage CGarages::aGarages[NUM_GARAGES];
bool& CGarages::bCamShouldBeOutisde = *(bool*)0x95CDB2; bool CGarages::bCamShouldBeOutisde;
void CGarages::Init(void) void CGarages::Init(void)
{ {
@ -206,12 +206,12 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z
return NumGarages++; return NumGarages++;
} }
CGarage* pGarage = &aGarages[NumGarages]; CGarage* pGarage = &aGarages[NumGarages];
pGarage->m_fX1 = min(X1, X2); pGarage->m_fX1 = Min(X1, X2);
pGarage->m_fX2 = max(X1, X2); pGarage->m_fX2 = Max(X1, X2);
pGarage->m_fY1 = min(Y1, Y2); pGarage->m_fY1 = Min(Y1, Y2);
pGarage->m_fY2 = max(Y1, Y2); pGarage->m_fY2 = Max(Y1, Y2);
pGarage->m_fZ1 = min(Z1, Z2); pGarage->m_fZ1 = Min(Z1, Z2);
pGarage->m_fZ2 = max(Z1, Z2); pGarage->m_fZ2 = Max(Z1, Z2);
pGarage->m_pDoor1 = nil; pGarage->m_pDoor1 = nil;
pGarage->m_pDoor2 = nil; pGarage->m_pDoor2 = nil;
pGarage->m_fDoor1Z = Z1; pGarage->m_fDoor1Z = Z1;
@ -307,13 +307,13 @@ void CGarage::Update()
CGarages::bCamShouldBeOutisde = true; CGarages::bCamShouldBeOutisde = true;
} }
if (pVehicle) { if (pVehicle) {
if (IsEntityEntirelyOutside(pVehicle, 0.0f)) if (!IsEntityEntirelyOutside(pVehicle, 0.0f))
TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = this; TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = this;
if (pVehicle->GetModelIndex() == MI_MRWHOOP) { if (pVehicle->GetModelIndex() == MI_MRWHOOP) {
if (pVehicle->IsWithinArea( if (pVehicle->IsWithinArea(
m_fX1 - DISTANCE_FOR_MRWHOOP_HACK, m_fX1 - DISTANCE_FOR_MRWHOOP_HACK,
m_fX2 + DISTANCE_FOR_MRWHOOP_HACK, m_fY1 + DISTANCE_FOR_MRWHOOP_HACK,
m_fY1 - DISTANCE_FOR_MRWHOOP_HACK, m_fX2 - DISTANCE_FOR_MRWHOOP_HACK,
m_fY2 + DISTANCE_FOR_MRWHOOP_HACK)) { m_fY2 + DISTANCE_FOR_MRWHOOP_HACK)) {
TheCamera.pToGarageWeAreIn = this; TheCamera.pToGarageWeAreIn = this;
CGarages::bCamShouldBeOutisde = true; CGarages::bCamShouldBeOutisde = true;
@ -361,7 +361,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY;
@ -440,7 +440,7 @@ void CGarage::Update()
} }
if (bTakeMoney) { if (bTakeMoney) {
if (!CGarages::RespraysAreFree) if (!CGarages::RespraysAreFree)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - RESPRAY_PRICE); CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - RESPRAY_PRICE);
CGarages::TriggerMessage("GA_2", -1, 4000, -1); // New engine and paint job. The cops won't recognize you! CGarages::TriggerMessage("GA_2", -1, 4000, -1); // New engine and paint job. The cops won't recognize you!
} }
else if (bChangedColour) { else if (bChangedColour) {
@ -458,7 +458,7 @@ void CGarage::Update()
m_fY2 + DISTANCE_TO_CALL_OFF_CHASE); m_fY2 + DISTANCE_TO_CALL_OFF_CHASE);
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR; m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -503,7 +503,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB;
@ -520,7 +520,7 @@ void CGarage::Update()
} }
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
if (!CGarages::BombsAreFree) if (!CGarages::BombsAreFree)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE); CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) { if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) {
((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType); ((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed(); ((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
@ -562,7 +562,7 @@ void CGarage::Update()
} }
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR; m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -597,7 +597,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar) if (m_bClosingWithoutTargetCar)
@ -626,7 +626,7 @@ void CGarage::Update()
} }
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -663,7 +663,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@ -710,7 +710,7 @@ void CGarage::Update()
m_pTarget = FindPlayerVehicle(); m_pTarget = FindPlayerVehicle();
m_pTarget->RegisterReference((CEntity**)&m_pTarget); m_pTarget->RegisterReference((CEntity**)&m_pTarget);
} }
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -759,7 +759,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@ -799,7 +799,7 @@ void CGarage::Update()
m_pTarget = FindPlayerVehicle(); m_pTarget = FindPlayerVehicle();
m_pTarget->RegisterReference((CEntity**)&m_pTarget); m_pTarget->RegisterReference((CEntity**)&m_pTarget);
} }
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -820,7 +820,7 @@ void CGarage::Update()
m_eGarageState = GS_CLOSING; m_eGarageState = GS_CLOSING;
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@ -831,7 +831,7 @@ void CGarage::Update()
case GS_FULLYCLOSED: case GS_FULLYCLOSED:
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -865,7 +865,7 @@ void CGarage::Update()
} }
case GS_CLOSING: case GS_CLOSING:
if (m_pTarget) { if (m_pTarget) {
m_fDoorPos = max(0.0f, m_fDoorPos - CRUSHER_CRANE_SPEED * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - CRUSHER_CRANE_SPEED * CTimer::GetTimeStep());
if (m_fDoorPos < TWOPI / 5) { if (m_fDoorPos < TWOPI / 5) {
m_pTarget->bUsesCollision = false; m_pTarget->bUsesCollision = false;
m_pTarget->bAffectedByGravity = false; m_pTarget->bAffectedByGravity = false;
@ -876,7 +876,7 @@ void CGarage::Update()
} }
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
CGarages::CrushedCarId = CPools::GetVehiclePool()->GetIndex(m_pTarget); CGarages::CrushedCarId = CPools::GetVehiclePool()->GetIndex(m_pTarget);
float reward = min(CRUSHER_MAX_REWARD, CRUSHER_MIN_REWARD + m_pTarget->pHandling->nMonetaryValue * m_pTarget->m_fHealth * CRUSHER_REWARD_COEFFICIENT); float reward = Min(CRUSHER_MAX_REWARD, CRUSHER_MIN_REWARD + m_pTarget->pHandling->nMonetaryValue * m_pTarget->m_fHealth * CRUSHER_REWARD_COEFFICIENT);
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += reward; CWorld::Players[CWorld::PlayerInFocus].m_nMoney += reward;
DestroyVehicleAndDriverAndPassengers(m_pTarget); DestroyVehicleAndDriverAndPassengers(m_pTarget);
++CStats::CarsCrushed; ++CStats::CarsCrushed;
@ -900,7 +900,7 @@ void CGarage::Update()
} }
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED); m_fDoorPos = Min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED);
if (m_fDoorPos == HALFPI) { if (m_fDoorPos == HALFPI) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -933,7 +933,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar) if (m_bClosingWithoutTargetCar)
@ -961,7 +961,7 @@ void CGarage::Update()
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -981,7 +981,7 @@ void CGarage::Update()
case GARAGE_FOR_SCRIPT_TO_OPEN: case GARAGE_FOR_SCRIPT_TO_OPEN:
switch (m_eGarageState) { switch (m_eGarageState) {
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -1001,7 +1001,7 @@ void CGarage::Update()
case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE: case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE:
switch (m_eGarageState) { switch (m_eGarageState) {
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@ -1009,7 +1009,7 @@ void CGarage::Update()
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -1050,7 +1050,7 @@ void CGarage::Update()
break; break;
} }
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (!IsPlayerOutsideGarage()) if (!IsPlayerOutsideGarage())
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
else if (m_fDoorPos == 0.0f) { else if (m_fDoorPos == 0.0f) {
@ -1082,7 +1082,7 @@ void CGarage::Update()
#ifdef FIX_BUGS #ifdef FIX_BUGS
bool bCreatedAllCars = false; bool bCreatedAllCars = false;
#else #else
bool bCraetedAllCars; bool bCreatedAllCars;
#endif #endif
switch (m_eGarageType) { switch (m_eGarageType) {
case GARAGE_HIDEOUT_ONE: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse1); break; case GARAGE_HIDEOUT_ONE: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse1); break;
@ -1096,7 +1096,7 @@ void CGarage::Update()
break; break;
} }
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -1121,7 +1121,7 @@ void CGarage::Update()
} }
break; break;
case GS_CLOSING: case GS_CLOSING:
m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@ -1137,7 +1137,7 @@ void CGarage::Update()
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
break; break;
case GS_OPENING: case GS_OPENING:
m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@ -1695,17 +1695,17 @@ float CGarage::CalcSmallestDistToGarageDoorSquared(float X, float Y)
dist1 = SQR(m_fDoor1X - X) + SQR(m_fDoor1Y - Y); dist1 = SQR(m_fDoor1X - X) + SQR(m_fDoor1Y - Y);
if (m_pDoor2) if (m_pDoor2)
dist2 = SQR(m_fDoor2X - X) + SQR(m_fDoor2Y - Y); dist2 = SQR(m_fDoor2X - X) + SQR(m_fDoor2Y - Y);
return min(dist1, dist2); return Min(dist1, dist2);
} }
void CGarage::FindDoorsEntities() void CGarage::FindDoorsEntities()
{ {
m_pDoor1 = nil; m_pDoor1 = nil;
m_pDoor2 = nil; m_pDoor2 = nil;
int xstart = max(0, CWorld::GetSectorIndexX(m_fX1)); int xstart = Max(0, CWorld::GetSectorIndexX(m_fX1));
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2)); int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2));
int ystart = max(0, CWorld::GetSectorIndexY(m_fY1)); int ystart = Max(0, CWorld::GetSectorIndexY(m_fY1));
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fY2)); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fY2));
assert(xstart <= xend); assert(xstart <= xend);
assert(ystart <= yend); assert(ystart <= yend);
@ -1891,7 +1891,7 @@ void CGarage::StoreAndRemoveCarsForThisHideout(CStoredCar* aCars, int32 nMax)
pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 && pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) { pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE) { if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE) {
if (index < max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f)) if (index < Max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f))
aCars[index++].StoreCar(pVehicle); aCars[index++].StoreCar(pVehicle);
CWorld::Players[CWorld::PlayerInFocus].CancelPlayerEnteringCars(pVehicle); CWorld::Players[CWorld::PlayerInFocus].CancelPlayerEnteringCars(pVehicle);
CWorld::Remove(pVehicle); CWorld::Remove(pVehicle);
@ -2256,7 +2256,7 @@ void CGarages::Save(uint8 * buf, uint32 * size)
#endif #endif
} }
CStoredCar::CStoredCar(const CStoredCar & other) const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
{ {
m_nModelIndex = other.m_nModelIndex; m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos; m_vecPos = other.m_vecPos;
@ -2272,6 +2272,7 @@ CStoredCar::CStoredCar(const CStoredCar & other)
m_nVariationA = other.m_nVariationA; m_nVariationA = other.m_nVariationA;
m_nVariationB = other.m_nVariationB; m_nVariationB = other.m_nVariationB;
m_nCarBombType = other.m_nCarBombType; m_nCarBombType = other.m_nCarBombType;
return *this;
} }
void CGarages::Load(uint8* buf, uint32 size) void CGarages::Load(uint8* buf, uint32 size)
@ -2313,6 +2314,10 @@ void CGarages::Load(uint8* buf, uint32 size)
#ifdef FIX_GARAGE_SIZE #ifdef FIX_GARAGE_SIZE
VALIDATESAVEBUF(size); VALIDATESAVEBUF(size);
#endif #endif
MessageEndTime = 0;
bCamShouldBeOutisde = false;
MessageStartTime = 0;
} }
bool bool
@ -2352,10 +2357,3 @@ CGarages::IsModelIndexADoor(uint32 id)
id == MI_CRUSHERBODY || id == MI_CRUSHERBODY ||
id == MI_CRUSHERLID; id == MI_CRUSHERLID;
} }
STARTPATCHES
InjectHook(0x427AB0, CGarages::IsPointInAGarageCameraZone, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x427BC0, CGarages::CameraShouldBeOutside, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x428940, CGarages::Load, PATCH_JUMP); // GenericLoad
ENDPATCHES

View file

@ -70,7 +70,7 @@ public:
void Init() { m_nModelIndex = 0; } void Init() { m_nModelIndex = 0; }
void Clear() { m_nModelIndex = 0; } void Clear() { m_nModelIndex = 0; }
bool HasCar() { return m_nModelIndex != 0; } bool HasCar() { return m_nModelIndex != 0; }
CStoredCar(const CStoredCar& other); const CStoredCar &operator=(const CStoredCar& other);
void StoreCar(CVehicle*); void StoreCar(CVehicle*);
CVehicle* RestoreCar(); CVehicle* RestoreCar();
}; };
@ -179,27 +179,27 @@ class CGarages
enum { enum {
MESSAGE_LENGTH = 8 MESSAGE_LENGTH = 8
}; };
static int32 &BankVansCollected; static int32 BankVansCollected;
static bool &BombsAreFree; static bool BombsAreFree;
static bool &RespraysAreFree; static bool RespraysAreFree;
static int32 &CarsCollected; static int32 CarsCollected;
static int32 (&CarTypesCollected)[TOTAL_COLLECTCARS_GARAGES]; static int32 CarTypesCollected[TOTAL_COLLECTCARS_GARAGES];
static int32 &CrushedCarId; static int32 CrushedCarId;
static uint32 &LastTimeHelpMessage; static uint32 LastTimeHelpMessage;
static int32 &MessageNumberInString; static int32 MessageNumberInString;
static char(&MessageIDString)[MESSAGE_LENGTH]; static char MessageIDString[MESSAGE_LENGTH];
static int32 &MessageNumberInString2; static int32 MessageNumberInString2;
static uint32 &MessageStartTime; static uint32 MessageStartTime;
static uint32 &MessageEndTime; static uint32 MessageEndTime;
static uint32 &NumGarages; static uint32 NumGarages;
static bool &PlayerInGarage; static bool PlayerInGarage;
static int32 &PoliceCarsCollected; static int32 PoliceCarsCollected;
static CGarage(&aGarages)[NUM_GARAGES]; static CGarage aGarages[NUM_GARAGES];
static CStoredCar(&aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS]; static CStoredCar aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS]; static CStoredCar aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS]; static CStoredCar aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
static int32 &AudioEntity; static int32 AudioEntity;
static bool &bCamShouldBeOutisde; static bool bCamShouldBeOutisde;
public: public:
static void Init(void); static void Init(void);

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "Hud.h" #include "Hud.h"
@ -153,18 +153,3 @@ void COnscreenTimerEntry::ProcessForDisplayCounter() {
uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset); uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset);
sprintf(m_bCounterBuffer, "%d", counter); sprintf(m_bCounterBuffer, "%d", counter);
} }
STARTPATCHES
InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP);
InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP);
InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayClock, PATCH_JUMP);
InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP);
InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP);
InjectHook(0x429320, &COnscreenTimer::Process, PATCH_JUMP);
InjectHook(0x4292E0, &COnscreenTimer::ProcessForDisplay, PATCH_JUMP);
InjectHook(0x429450, &COnscreenTimer::ClearCounter, PATCH_JUMP);
InjectHook(0x429410, &COnscreenTimer::ClearClock, PATCH_JUMP);
InjectHook(0x4293B0, &COnscreenTimer::AddCounter, PATCH_JUMP);
InjectHook(0x429350, &COnscreenTimer::AddClock, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "General.h" #include "General.h"
#include "FileMgr.h" // only needed for empty function #include "FileMgr.h" // only needed for empty function
#include "Camera.h" #include "Camera.h"
@ -12,21 +12,213 @@ bool gbShowPedPaths;
bool gbShowCarPaths; bool gbShowCarPaths;
bool gbShowCarPathsLinks; bool gbShowCarPathsLinks;
CPathFind &ThePaths = *(CPathFind*)0x8F6754; CPathFind ThePaths;
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
#define MAX_DIST INT16_MAX-1 #define MAX_DIST INT16_MAX-1
#define MIN_PED_ROUTE_DISTANCE 23.8f
// object flags: // object flags:
// 1 UseInRoadBlock // 1 UseInRoadBlock
// 2 east/west road(?) // 2 east/west road(?)
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C; CPathInfoForObject *InfoForTileCars;
CPathInfoForObject *&InfoForTilePeds = *(CPathInfoForObject**)0x8F1AE4; CPathInfoForObject *InfoForTilePeds;
// unused // unused
CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824; CTempDetachedNode *DetachedNodesCars;
CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0; CTempDetachedNode *DetachedNodesPeds;
bool
CPedPath::CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints)
{
*pointsFound = 0;
CVector vecDistance = destination - position;
if (Abs(vecDistance.x) > MIN_PED_ROUTE_DISTANCE || Abs(vecDistance.y) > MIN_PED_ROUTE_DISTANCE || Abs(vecDistance.z) > MIN_PED_ROUTE_DISTANCE)
return false;
CVector vecPos = (position + destination) * 0.5f;
CVector vecSectorStartPos (vecPos.x - 14.0f, vecPos.y - 14.0f, vecPos.z);
CVector2D vecSectorEndPos (vecPos.x + 28.0f, vecPos.x + 28.0f);
const int16 nodeStartX = (position.x - vecSectorStartPos.x) / 0.7f;
const int16 nodeStartY = (position.y - vecSectorStartPos.y) / 0.7f;
const int16 nodeEndX = (destination.x - vecSectorStartPos.x) / 0.7f;
const int16 nodeEndY = (destination.y - vecSectorStartPos.y) / 0.7f;
if (nodeStartX == nodeEndX && nodeStartY == nodeEndY)
return false;
CPedPathNode pathNodes[40][40];
CPedPathNode pathNodesList[416];
for (int32 x = 0; x < 40; x++) {
for (int32 y = 0; y < 40; y++) {
pathNodes[x][y].bBlockade = false;
pathNodes[x][y].id = INT16_MAX;
pathNodes[x][y].nodeIdX = x;
pathNodes[x][y].nodeIdY = y;
}
}
CWorld::AdvanceCurrentScanCode();
if (pathType != ROUTE_NO_BLOCKADE) {
const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
for (int32 y = nStartY; y <= nEndY; y++) {
for (int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = CWorld::GetSector(x, y);
AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], pathNodes, &vecSectorStartPos);
AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], pathNodes, &vecSectorStartPos);
AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], pathNodes, &vecSectorStartPos);
AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], pathNodes, &vecSectorStartPos);
}
}
}
for (int32 i = 0; i < 416; i++) {
pathNodesList[i].prev = nil;
pathNodesList[i].next = nil;
}
CPedPathNode *pStartPathNode = &pathNodes[nodeStartX][nodeStartY];
CPedPathNode *pEndPathNode = &pathNodes[nodeEndX][nodeEndY];
pEndPathNode->bBlockade = false;
pEndPathNode->id = 0;
pEndPathNode->prev = nil;
pEndPathNode->next = pathNodesList;
pathNodesList[0].prev = pEndPathNode;
int32 pathNodeIndex = 0;
CPedPathNode *pPreviousNode = nil;
for (; pathNodeIndex < 414; pathNodeIndex++)
{
pPreviousNode = pathNodesList[pathNodeIndex].prev;
while (pPreviousNode && pPreviousNode != pStartPathNode) {
const uint8 nodeIdX = pPreviousNode->nodeIdX;
const uint8 nodeIdY = pPreviousNode->nodeIdY;
if (nodeIdX > 0) {
AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY], pathNodeIndex + 5, pathNodesList);
if (nodeIdY > 0)
AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY - 1], pathNodeIndex + 7, pathNodesList);
if (nodeIdY < 39)
AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY + 1], pathNodeIndex + 7, pathNodesList);
}
if (nodeIdX < 39) {
AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY], pathNodeIndex + 5, pathNodesList);
if (nodeIdY > 0)
AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY - 1], pathNodeIndex + 7, pathNodesList);
if (nodeIdY < 39)
AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY + 1], pathNodeIndex + 7, pathNodesList);
}
if (nodeIdY > 0)
AddNodeToPathList(&pathNodes[nodeIdX][nodeIdY - 1], pathNodeIndex + 5, pathNodesList);
if (nodeIdY < 39)
AddNodeToPathList(&pathNodes[nodeIdX][nodeIdY + 1], pathNodeIndex + 5, pathNodesList);
pPreviousNode = pPreviousNode->prev;
if (!pPreviousNode)
break;
}
if (pPreviousNode && pPreviousNode == pStartPathNode)
break;
}
if (pathNodeIndex == 414)
return false;
CPedPathNode *pPathNode = pStartPathNode;
for (*pointsFound = 0; pPathNode != pEndPathNode && *pointsFound < maxPoints; ++ *pointsFound) {
const uint8 nodeIdX = pPathNode->nodeIdX;
const uint8 nodeIdY = pPathNode->nodeIdY;
if (nodeIdX > 0 && pathNodes[nodeIdX - 1][nodeIdY].id + 5 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX - 1][nodeIdY];
else if (nodeIdX > 39 && pathNodes[nodeIdX + 1][nodeIdY].id + 5 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX + 1][nodeIdY];
else if (nodeIdY > 0 && pathNodes[nodeIdX][nodeIdY - 1].id + 5 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX][nodeIdY - 1];
else if (nodeIdY > 39 && pathNodes[nodeIdX][nodeIdY + 1].id + 5 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX][nodeIdY + 1];
else if (nodeIdX > 0 && nodeIdY > 0 && pathNodes[nodeIdX - 1][nodeIdY - 1].id + 7 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX - 1][nodeIdY - 1];
else if (nodeIdX > 0 && nodeIdY < 39 && pathNodes[nodeIdX - 1][nodeIdY + 1].id + 7 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX - 1][nodeIdY + 1];
else if (nodeIdX < 39 && nodeIdY > 0 && pathNodes[nodeIdX + 1][nodeIdY - 1].id + 7 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX + 1][nodeIdY - 1];
else if (nodeIdX < 39 && nodeIdY < 39 && pathNodes[nodeIdX + 1][nodeIdY + 1].id + 7 == pPathNode->id)
pPathNode = &pathNodes[nodeIdX + 1][nodeIdY + 1];
pointPoses[*pointsFound] = vecSectorStartPos;
pointPoses[*pointsFound].x += pPathNode->nodeIdX * 0.7f;
pointPoses[*pointsFound].y += pPathNode->nodeIdY * 0.7f;
}
return true;
}
void
CPedPath::AddNodeToPathList(CPedPathNode *pNodeToAdd, int16 id, CPedPathNode *pNodeList)
{
if (!pNodeToAdd->bBlockade && id < pNodeToAdd->id) {
if (pNodeToAdd->id != INT16_MAX)
RemoveNodeFromList(pNodeToAdd);
AddNodeToList(pNodeToAdd, id, pNodeList);
}
}
void
CPedPath::RemoveNodeFromList(CPedPathNode *pNode)
{
pNode->next->prev = pNode->prev;
if (pNode->prev)
pNode->prev->next = pNode->next;
}
void
CPedPath::AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList)
{
pNode->prev = pList[index].prev;
pNode->next = &pList[index];
if (pList[index].prev)
pList[index].prev->next = pNode;
pList[index].prev = pNode;
pNode->id = index;
}
void
CPedPath::AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition)
{
CPtrNode* listNode = list.first;
while (listNode) {
CEntity* pEntity = (CEntity*)listNode->item;
if (pEntity->m_scanCode != CWorld::GetCurrentScanCode() && pEntity->bUsesCollision) {
pEntity->m_scanCode = CWorld::GetCurrentScanCode();
AddBlockade(pEntity, pathNodes, pPosition);
}
listNode = listNode->next;
}
}
void
CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition)
{
const CColBox& boundingBox = pEntity->GetColModel()->boundingBox;
const float fBoundMaxY = boundingBox.max.y + 0.3f;
const float fBoundMinY = boundingBox.min.y - 0.3f;
const float fBoundMaxX = boundingBox.max.x + 0.3f;
const float fDistanceX = pPosition->x - pEntity->m_matrix.GetPosition().x;
const float fDistanceY = pPosition->y - pEntity->m_matrix.GetPosition().y;
const float fBoundRadius = pEntity->GetBoundRadius();
CVector vecBoundCentre;
pEntity->GetBoundCentre(vecBoundCentre);
if (vecBoundCentre.x + fBoundRadius >= pPosition->x &&
vecBoundCentre.y + fBoundRadius >= pPosition->y &&
vecBoundCentre.x - fBoundRadius <= pPosition->x + 28.0f &&
vecBoundCentre.y - fBoundRadius <= pPosition->y + 28.0f) {
for (int16 x = 0; x < 40; x++) {
const float pointX = x * 0.7f + fDistanceX;
for (int16 y = 0; y < 40; y++) {
if (!pathNodes[x][y].bBlockade) {
const float pointY = y * 0.7f + fDistanceY;
CVector2D point(pointX, pointY);
if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->m_matrix.GetRight()))) {
float fDotProduct = DotProduct2D(point, pEntity->m_matrix.GetForward());
if (fBoundMaxY > fDotProduct && fBoundMinY < fDotProduct)
pathNodes[x][y].bBlockade = true;
}
}
}
}
}
}
void void
CPathFind::Init(void) CPathFind::Init(void)
@ -205,8 +397,8 @@ CPathFind::PreparePathData(void)
numExtern++; numExtern++;
if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes) if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes)
numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes; numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes;
maxX = max(maxX, Abs(InfoForTileCars[k].x)); maxX = Max(maxX, Abs(InfoForTileCars[k].x));
maxY = max(maxY, Abs(InfoForTileCars[k].y)); maxY = Max(maxY, Abs(InfoForTileCars[k].y));
}else if(InfoForTileCars[k].type == NodeTypeIntern) }else if(InfoForTileCars[k].type == NodeTypeIntern)
numIntern++; numIntern++;
} }
@ -390,7 +582,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
if(Abs(dx) < nearestDist){ if(Abs(dx) < nearestDist){
dy = tempnodes[k].pos.y - CoorsXFormed.y; dy = tempnodes[k].pos.y - CoorsXFormed.y;
if(Abs(dy) < nearestDist){ if(Abs(dy) < nearestDist){
nearestDist = max(Abs(dx), Abs(dy)); nearestDist = Max(Abs(dx), Abs(dy));
nearestId = k; nearestId = k;
} }
} }
@ -499,13 +691,13 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// Find i inside path segment // Find i inside path segment
iseg = 0; iseg = 0;
for(j = max(oldNumPathNodes, i-12); j < i; j++) for(j = Max(oldNumPathNodes, i-12); j < i; j++)
if(m_pathNodes[j].objectIndex == m_pathNodes[i].objectIndex) if(m_pathNodes[j].objectIndex == m_pathNodes[i].objectIndex)
iseg++; iseg++;
istart = 12*m_mapObjects[m_pathNodes[i].objectIndex]->m_modelIndex; istart = 12*m_mapObjects[m_pathNodes[i].objectIndex]->m_modelIndex;
// Add links to other internal nodes // Add links to other internal nodes
for(j = max(oldNumPathNodes, i-12); j < min(m_numPathNodes, i+12); j++){ for(j = Max(oldNumPathNodes, i-12); j < Min(m_numPathNodes, i+12); j++){
if(m_pathNodes[i].objectIndex != m_pathNodes[j].objectIndex || i == j) if(m_pathNodes[i].objectIndex != m_pathNodes[j].objectIndex || i == j)
continue; continue;
// N.B.: in every path segment, the externals have to be at the end // N.B.: in every path segment, the externals have to be at the end
@ -1274,8 +1466,11 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
targetNode = FindNodeClosestToCoors(target, type, distLimit); targetNode = FindNodeClosestToCoors(target, type, distLimit);
else else
targetNode = forcedTargetNode; targetNode = forcedTargetNode;
if(targetNode < 0) if(targetNode < 0) {
goto fail; *pNumNodes = 0;
if(pDist) *pDist = 100000.0f;
return;
}
// Find start // Find start
int numPathsToTry; int numPathsToTry;
@ -1294,19 +1489,28 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
numPathsToTry = 1; numPathsToTry = 1;
startObj = m_mapObjects[m_pathNodes[startNodeId].objectIndex]; startObj = m_mapObjects[m_pathNodes[startNodeId].objectIndex];
} }
if(numPathsToTry == 0) if(numPathsToTry == 0) {
goto fail; *pNumNodes = 0;
if(pDist) *pDist = 100000.0f;
return;
}
if(startNodeId < 0){ if(startNodeId < 0){
// why only check node 0? // why only check node 0?
if(m_pathNodes[startObj->m_nodeIndices[type][0]].group != m_pathNodes[targetNode].group) if(m_pathNodes[startObj->m_nodeIndices[type][0]].group !=
goto fail; m_pathNodes[targetNode].group) {
*pNumNodes = 0;
if(pDist) *pDist = 100000.0f;
return;
}
}else{ }else{
if(m_pathNodes[startNodeId].group != m_pathNodes[targetNode].group) if(m_pathNodes[startNodeId].group != m_pathNodes[targetNode].group) {
goto fail; *pNumNodes = 0;
if(pDist) *pDist = 100000.0f;
return;
}
} }
for(i = 0; i < 512; i++) for(i = 0; i < 512; i++)
m_searchNodes[i].next = nil; m_searchNodes[i].next = nil;
AddNodeToList(&m_pathNodes[targetNode], 0); AddNodeToList(&m_pathNodes[targetNode], 0);
@ -1384,11 +1588,6 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
for(i = 0; i < numNodesToBeCleared; i++) for(i = 0; i < numNodesToBeCleared; i++)
apNodesToBeCleared[i]->distance = MAX_DIST; apNodesToBeCleared[i]->distance = MAX_DIST;
return; return;
fail:
*pNumNodes = 0;
if(pDist)
*pDist = 100000.0f;
} }
static CPathNode *pNodeList[32]; static CPathNode *pNodeList[32];
@ -1574,41 +1773,3 @@ CPathFind::DisplayPathData(void)
} }
} }
} }
STARTPATCHES
InjectHook(0x4294A0, &CPathFind::Init, PATCH_JUMP);
InjectHook(0x42D580, &CPathFind::AllocatePathFindInfoMem, PATCH_JUMP);
InjectHook(0x429540, &CPathFind::RegisterMapObject, PATCH_JUMP);
InjectHook(0x42D7E0, &CPathFind::StoreNodeInfoPed, PATCH_JUMP);
InjectHook(0x42D690, &CPathFind::StoreNodeInfoCar, PATCH_JUMP);
InjectHook(0x429610, &CPathFind::PreparePathData, PATCH_JUMP);
InjectHook(0x42B810, &CPathFind::CountFloodFillGroups, PATCH_JUMP);
InjectHook(0x429C20, &CPathFind::PreparePathDataForType, PATCH_JUMP);
InjectHook(0x42C990, &CPathFind::CalcRoadDensity, PATCH_JUMP);
InjectHook(0x42E1B0, &CPathFind::TestForPedTrafficLight, PATCH_JUMP);
InjectHook(0x42E340, &CPathFind::TestCrossesRoad, PATCH_JUMP);
InjectHook(0x42CBE0, &CPathFind::AddNodeToList, PATCH_JUMP);
InjectHook(0x42CBB0, &CPathFind::RemoveNodeFromList, PATCH_JUMP);
InjectHook(0x42B790, &CPathFind::RemoveBadStartNode, PATCH_JUMP);
InjectHook(0x42E3B0, &CPathFind::SetLinksBridgeLights, PATCH_JUMP);
InjectHook(0x42DED0, &CPathFind::SwitchOffNodeAndNeighbours, PATCH_JUMP);
InjectHook(0x42D960, &CPathFind::SwitchRoadsOffInArea, PATCH_JUMP);
InjectHook(0x42DA50, &CPathFind::SwitchPedRoadsOffInArea, PATCH_JUMP);
InjectHook(0x42DB50, &CPathFind::SwitchRoadsInAngledArea, PATCH_JUMP);
InjectHook(0x42E140, &CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours, PATCH_JUMP);
InjectHook(0x42DF50, &CPathFind::MarkRoadsBetweenLevelsInArea, PATCH_JUMP);
InjectHook(0x42E040, &CPathFind::PedMarkRoadsBetweenLevelsInArea, PATCH_JUMP);
InjectHook(0x42CC30, &CPathFind::FindNodeClosestToCoors, PATCH_JUMP);
InjectHook(0x42CDC0, &CPathFind::FindNodeClosestToCoorsFavourDirection, PATCH_JUMP);
InjectHook(0x42CFC0, &CPathFind::FindNodeOrientationForCarPlacement, PATCH_JUMP);
InjectHook(0x42D060, &CPathFind::FindNodeOrientationForCarPlacementFacingDestination, PATCH_JUMP);
InjectHook(0x42BF10, &CPathFind::NewGenerateCarCreationCoors, PATCH_JUMP);
InjectHook(0x42C1E0, &CPathFind::GeneratePedCreationCoors, PATCH_JUMP);
InjectHook(0x42D2A0, &CPathFind::FindRoadObjectClosestToCoors, PATCH_JUMP);
InjectHook(0x42B9F0, &CPathFind::FindNextNodeWandering, PATCH_JUMP);
InjectHook(0x42B040, &CPathFind::DoPathSearch, PATCH_JUMP);
InjectHook(0x42C8C0, &CPathFind::TestCoorsCloseness, PATCH_JUMP);
InjectHook(0x42E450, &CPathFind::Save, PATCH_JUMP);
InjectHook(0x42E550, &CPathFind::Load, PATCH_JUMP);
ENDPATCHES

View file

@ -3,11 +3,7 @@
#include "Treadable.h" #include "Treadable.h"
class CVehicle; class CVehicle;
class CPtrList;
class CPedPath {
public:
static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
};
enum enum
{ {
@ -30,6 +26,33 @@ enum
SWITCH_ON = 1, SWITCH_ON = 1,
}; };
enum
{
ROUTE_ADD_BLOCKADE = 0,
ROUTE_NO_BLOCKADE = 1
};
struct CPedPathNode
{
bool bBlockade;
uint8 nodeIdX;
uint8 nodeIdY;
int16 id;
CPedPathNode* prev;
CPedPathNode* next;
};
static_assert(sizeof(CPedPathNode) == 0x10, "CPedPathNode: error");
class CPedPath {
public:
static bool CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints);
static void AddNodeToPathList(CPedPathNode *pNodeToAdd, int16 id, CPedPathNode *pNodeList);
static void RemoveNodeFromList(CPedPathNode *pNode);
static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList);
static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition);
static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition);
};
struct CPathNode struct CPathNode
{ {
CVector pos; CVector pos;
@ -115,8 +138,8 @@ struct CPathInfoForObject
int8 numRightLanes; int8 numRightLanes;
uint8 crossing : 1; uint8 crossing : 1;
}; };
extern CPathInfoForObject *&InfoForTileCars; extern CPathInfoForObject *InfoForTileCars;
extern CPathInfoForObject *&InfoForTilePeds; extern CPathInfoForObject *InfoForTilePeds;
struct CTempNode struct CTempNode
{ {
@ -211,7 +234,7 @@ public:
}; };
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error"); static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");
extern CPathFind &ThePaths; extern CPathFind ThePaths;
extern bool gbShowPedPaths; extern bool gbShowPedPaths;
extern bool gbShowCarPaths; extern bool gbShowCarPaths;

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Phones.h" #include "Phones.h"
#include "Pools.h" #include "Pools.h"
#include "ModelIndices.h" #include "ModelIndices.h"
@ -12,14 +12,17 @@
#include "AudioScriptObject.h" #include "AudioScriptObject.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#ifdef FIX_BUGS
#include "Replay.h"
#endif
CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20; CPhoneInfo gPhoneInfo;
bool &CPhoneInfo::bDisplayingPhoneMessage = *(bool*)0x6283AC; // is phone picked up bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
uint32 &CPhoneInfo::PhoneEnableControlsTimer = *(uint32*)0x6283A8; uint32 CPhoneInfo::PhoneEnableControlsTimer;
CPhone *&CPhoneInfo::pPhoneDisplayingMessages = *(CPhone**)0x6283B0; CPhone *CPhoneInfo::pPhoneDisplayingMessages;
bool &CPhoneInfo::bPickingUpPhone = *(bool*)0x6283B4; bool CPhoneInfo::bPickingUpPhone;
CPed *&CPhoneInfo::pCallBackPed = *(CPed**)0x6283B8; // ped who picking up the phone (reset after pickup cb) CPed *CPhoneInfo::pCallBackPed; // ped who picking up the phone (reset after pickup cb)
/* /*
Entering phonebooth cutscene, showing messages and triggering these things Entering phonebooth cutscene, showing messages and triggering these things
@ -45,6 +48,10 @@ isPhoneAvailable(int m_phoneId)
void void
CPhoneInfo::Update(void) CPhoneInfo::Update(void)
{ {
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return;
#endif
CPlayerPed *player = FindPlayerPed(); CPlayerPed *player = FindPlayerPed();
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus]; CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
if (bDisplayingPhoneMessage && CTimer::GetTimeInMilliseconds() > PhoneEnableControlsTimer) { if (bDisplayingPhoneMessage && CTimer::GetTimeInMilliseconds() > PhoneEnableControlsTimer) {
@ -377,20 +384,3 @@ PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg)
CPhoneInfo::pCallBackPed = nil; CPhoneInfo::pCallBackPed = nil;
} }
STARTPATCHES
InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP);
InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP);
InjectHook(0x42FFF0, &CPhoneInfo::HasMessageBeenDisplayed, PATCH_JUMP);
InjectHook(0x430030, &CPhoneInfo::IsMessageBeingDisplayed, PATCH_JUMP);
InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP);
InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP);
InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP);
InjectHook(0x430060, &CPhoneInfo::Save, PATCH_JUMP);
InjectHook(0x42F710, &CPhoneInfo::Shutdown, PATCH_JUMP);
InjectHook(0x42F640, &CPhoneInfo::Initialise, PATCH_JUMP);
InjectHook(0x42FDB0, &CPhoneInfo::GrabPhone, PATCH_JUMP);
InjectHook(0x42F7A0, &CPhoneInfo::Update, PATCH_JUMP);
InjectHook(0x42F570, &PhonePutDownCB, PATCH_JUMP);
InjectHook(0x42F470, &PhonePickUpCB, PATCH_JUMP);
ENDPATCHES

View file

@ -36,11 +36,11 @@ static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
class CPhoneInfo { class CPhoneInfo {
public: public:
static bool &bDisplayingPhoneMessage; static bool bDisplayingPhoneMessage;
static uint32 &PhoneEnableControlsTimer; static uint32 PhoneEnableControlsTimer;
static CPhone *&pPhoneDisplayingMessages; static CPhone *pPhoneDisplayingMessages;
static bool &bPickingUpPhone; static bool bPickingUpPhone;
static CPed *&pCallBackPed; static CPed *pCallBackPed;
int32 m_nMax; int32 m_nMax;
int32 m_nScriptPhonesMax; int32 m_nScriptPhonesMax;
@ -63,7 +63,7 @@ public:
void Update(void); void Update(void);
}; };
extern CPhoneInfo &gPhoneInfo; extern CPhoneInfo gPhoneInfo;
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg); void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg); void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "main.h" #include "main.h"
#include "Camera.h" #include "Camera.h"
@ -31,16 +31,16 @@
#include "WaterLevel.h" #include "WaterLevel.h"
#include "World.h" #include "World.h"
CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98; CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;// = *(int16*)0x95CC98; int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538; int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A; int16 CPickups::CollectedPickUpIndex;
// unused // unused
bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71; bool CPickups::bPickUpcamActivated;
CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8; CVehicle *CPickups::pPlayerVehicle;
CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8; CVector CPickups::StaticCamCoors;
uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C; uint32 CPickups::StaticCamStartTime;
tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES]; tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
@ -99,7 +99,7 @@ CPickup::GiveUsAPickUpObject(int32 handle)
switch (m_eType) switch (m_eType)
{ {
case PICKUP_IN_SHOP: case PICKUP_IN_SHOP:
object->m_obj_flag2 = true; object->bPickupObjWithMessage = true;
object->bOutOfStock = false; object->bOutOfStock = false;
break; break;
case PICKUP_ON_STREET: case PICKUP_ON_STREET:
@ -113,11 +113,11 @@ CPickup::GiveUsAPickUpObject(int32 handle)
case PICKUP_NAUTICAL_MINE_ARMED: case PICKUP_NAUTICAL_MINE_ARMED:
case PICKUP_FLOATINGPACKAGE: case PICKUP_FLOATINGPACKAGE:
case PICKUP_ON_STREET_SLOW: case PICKUP_ON_STREET_SLOW:
object->m_obj_flag2 = false; object->bPickupObjWithMessage = false;
object->bOutOfStock = false; object->bOutOfStock = false;
break; break;
case PICKUP_IN_SHOP_OUT_OF_STOCK: case PICKUP_IN_SHOP_OUT_OF_STOCK:
object->m_obj_flag2 = false; object->bPickupObjWithMessage = false;
object->bOutOfStock = true; object->bOutOfStock = true;
object->bRenderScorched = true; object->bRenderScorched = true;
break; break;
@ -491,7 +491,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
int32 slot = 0; int32 slot = 0;
if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) { if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) {
for (slot = NUMPICKUPS; slot >= 0; slot--) { for (slot = NUMPICKUPS-1; slot >= 0; slot--) {
if (aPickUps[slot].m_eType == PICKUP_NONE) { if (aPickUps[slot].m_eType == PICKUP_NONE) {
bFreeFound = true; bFreeFound = true;
break; break;
@ -623,6 +623,34 @@ CPickups::Update()
if (CReplay::IsPlayingBack()) if (CReplay::IsPlayingBack())
return; return;
#endif #endif
#ifdef CAMERA_PICKUP
if ( bPickUpcamActivated ) // taken from PS2
{
float dist = (FindPlayerCoors() - StaticCamCoors).Magnitude2D();
float mult;
if ( dist < 10.0f )
mult = 1.0f - (dist / 10.0f );
else
mult = 0.0f;
CVector pos = StaticCamCoors;
pos.z += (pPlayerVehicle->GetColModel()->boundingBox.GetSize().z + 2.0f) * mult;
if ( (CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 750 )
{
TheCamera.SetCamPositionForFixedMode(pos, CVector(0.0f, 0.0f, 0.0f));
TheCamera.TakeControl(FindPlayerVehicle(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_SCRIPT);
}
if ( FindPlayerVehicle() != pPlayerVehicle
|| (FindPlayerCoors() - StaticCamCoors).Magnitude() > 40.0f
|| ((CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 60000) )
{
TheCamera.RestoreWithJumpCut();
bPickUpcamActivated = false;
}
}
#endif
#define PICKUPS_FRAME_SPAN (6) #define PICKUPS_FRAME_SPAN (6)
#ifdef FIX_BUGS #ifdef FIX_BUGS
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) { for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
@ -690,7 +718,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CObject *object = (CObject*)entity; CObject *object = (CObject*)entity;
if (object->m_obj_flag2 || object->bOutOfStock || object->m_nBonusValue) { if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) {
float dist = (TheCamera.GetPosition() - pos).Magnitude(); float dist = (TheCamera.GetPosition() - pos).Magnitude();
const float MAXDIST = 12.0f; const float MAXDIST = 12.0f;
@ -1406,47 +1434,3 @@ CPacManPickups::ResetPowerPillsCarriedByPlayer()
FindPlayerVehicle()->m_fForceMultiplier = 1.0f; FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
} }
} }
STARTPATCHES
InjectHook(0x430220, CPickups::Init, PATCH_JUMP);
InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP);
InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP);
InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP);
InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP);
InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP);
InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP);
InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP);
InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP);
InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP);
InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP);
InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP);
InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP);
InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP);
InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP);
InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/
InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP);
InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP);
InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP);
InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP);
InjectHook(0x433F60, CPickups::Load, PATCH_JUMP);
InjectHook(0x433E40, CPickups::Save, PATCH_JUMP);
InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP);
InjectHook(0x430860, &CPickup::Update, PATCH_JUMP);
InjectHook(0x4331B0, &CPacManPickup::Update, PATCH_JUMP);
InjectHook(0x432760, CPacManPickups::Init, PATCH_JUMP);
InjectHook(0x432800, CPacManPickups::Update, PATCH_JUMP);
InjectHook(0x432AE0, CPacManPickups::GeneratePMPickUps, PATCH_JUMP);
InjectHook(0x432D50, CPacManPickups::GeneratePMPickUpsForRace, PATCH_JUMP);
InjectHook(0x432F20, CPacManPickups::GenerateOnePMPickUp, PATCH_JUMP);
InjectHook(0x432F60, CPacManPickups::Render, PATCH_JUMP);
InjectHook(0x433150, CPacManPickups::ClearPMPickUps, PATCH_JUMP);
InjectHook(0x433340, CPacManPickups::StartPacManRace, PATCH_JUMP);
InjectHook(0x433360, CPacManPickups::StartPacManRecord, PATCH_JUMP);
InjectHook(0x4333A0, CPacManPickups::QueryPowerPillsEatenInRace, PATCH_JUMP);
InjectHook(0x4333B0, CPacManPickups::ResetPowerPillsEatenInRace, PATCH_JUMP);
InjectHook(0x4333C0, CPacManPickups::CleanUpPacManStuff, PATCH_JUMP);
InjectHook(0x4333D0, CPacManPickups::StartPacManScramble, PATCH_JUMP);
InjectHook(0x4333F0, CPacManPickups::QueryPowerPillsCarriedByPlayer, PATCH_JUMP);
InjectHook(0x433410, CPacManPickups::ResetPowerPillsCarriedByPlayer, PATCH_JUMP);
ENDPATCHES

View file

@ -89,13 +89,13 @@ public:
static void Load(uint8 *buf, uint32 size); static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size); static void Save(uint8 *buf, uint32 *size);
static CPickup(&aPickUps)[NUMPICKUPS]; static CPickup aPickUps[NUMPICKUPS];
// unused // unused
static bool &bPickUpcamActivated; static bool bPickUpcamActivated;
static CVehicle *&pPlayerVehicle; static CVehicle *pPlayerVehicle;
static CVector &StaticCamCoors; static CVector StaticCamCoors;
static uint32 &StaticCamStartTime; static uint32 StaticCamStartTime;
}; };
extern uint16 AmmoForWeapon[20]; extern uint16 AmmoForWeapon[20];

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Record.h" #include "Record.h"
#include "FileMgr.h" #include "FileMgr.h"
@ -10,11 +10,11 @@
#include "VehicleModelInfo.h" #include "VehicleModelInfo.h"
#include "World.h" #include "World.h"
uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24; uint16 CRecordDataForGame::RecordingState;
uint8*& CRecordDataForGame::pDataBuffer = *(uint8**)0x8F1B70; uint8* CRecordDataForGame::pDataBuffer;
uint8*& CRecordDataForGame::pDataBufferPointer = *(uint8**)0x8F1AB0; uint8* CRecordDataForGame::pDataBufferPointer;
int& CRecordDataForGame::FId = *(int*)0x885BA4; int CRecordDataForGame::FId;
tGameBuffer& CRecordDataForGame::pDataBufferForFrame = *(tGameBuffer*)0x72CED0; tGameBuffer CRecordDataForGame::pDataBufferForFrame;
#define MEMORY_FOR_GAME_RECORD (150000) #define MEMORY_FOR_GAME_RECORD (150000)
@ -176,15 +176,15 @@ uint16 CRecordDataForGame::CalcGameChecksum(void)
return checksum ^ checksum >> 16; return checksum ^ checksum >> 16;
} }
uint8& CRecordDataForChase::Status = *(uint8*)0x95CDCE; uint8 CRecordDataForChase::Status;
int& CRecordDataForChase::PositionChanges = *(int*)0x8F59C8; int CRecordDataForChase::PositionChanges;
uint8& CRecordDataForChase::CurrentCar = *(uint8*)0x95CDC9; uint8 CRecordDataForChase::CurrentCar;
CAutomobile* (&CRecordDataForChase::pChaseCars)[NUM_CHASE_CARS] = *(CAutomobile * (*)[NUM_CHASE_CARS])*(uintptr*)0x6F46A8; CAutomobile* CRecordDataForChase::pChaseCars[NUM_CHASE_CARS];
uint32& CRecordDataForChase::AnimStartTime = *(uint32*)0x8F1AEC; uint32 CRecordDataForChase::AnimStartTime;
float& CRecordDataForChase::AnimTime = *(float*)0x880F88; float CRecordDataForChase::AnimTime;
CCarStateEachFrame* (&CRecordDataForChase::pBaseMemForCar)[NUM_CHASE_CARS] = *(CCarStateEachFrame * (*)[NUM_CHASE_CARS])*(uintptr*)0x70EA18; CCarStateEachFrame* CRecordDataForChase::pBaseMemForCar[NUM_CHASE_CARS];
float& CRecordDataForChase::TimeMultiplier = *(float*)0x8E2A94; float CRecordDataForChase::TimeMultiplier;
int& CRecordDataForChase::FId2 = *(int*)0x8E2C18; int CRecordDataForChase::FId2;
#define CHASE_SCENE_LENGTH_IN_SECONDS (80) #define CHASE_SCENE_LENGTH_IN_SECONDS (80)
#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame #define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
@ -296,7 +296,7 @@ void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
case STATE_PLAYBACK: case STATE_PLAYBACK:
{ {
TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds(); TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier); float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * Min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
for (int i = 0; i < NUM_CHASE_CARS; i++) { for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (!pBaseMemForCar[i]) if (!pBaseMemForCar[i])
continue; continue;
@ -371,7 +371,7 @@ void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFram
else else
pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2); pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
} }
pCar->m_fHealth = min(pCar->m_fHealth, 500.0f); pCar->m_fHealth = Min(pCar->m_fHealth, 500.0f);
if (stop) { if (stop) {
pCar->m_fGasPedal = 0.0f; pCar->m_fGasPedal = 0.0f;
pCar->m_fBrakePedal = 0.0f; pCar->m_fBrakePedal = 0.0f;

View file

@ -23,7 +23,7 @@ public:
CVector pos; CVector pos;
}; };
extern char* gString; extern char gString[256];;
class CRecordDataForChase class CRecordDataForChase
{ {
@ -37,15 +37,15 @@ class CRecordDataForChase
STATE_PLAYBACK = 3, STATE_PLAYBACK = 3,
STATE_PLAYBACK_BEFORE_RECORDING = 4 STATE_PLAYBACK_BEFORE_RECORDING = 4
}; };
static uint8 &Status; static uint8 Status;
static int &PositionChanges; static int PositionChanges;
static uint8 &CurrentCar; static uint8 CurrentCar;
static CAutomobile*(&pChaseCars)[NUM_CHASE_CARS]; static CAutomobile*pChaseCars[NUM_CHASE_CARS];
static float &AnimTime; static float AnimTime;
static uint32 &AnimStartTime; static uint32 AnimStartTime;
static CCarStateEachFrame* (&pBaseMemForCar)[NUM_CHASE_CARS]; static CCarStateEachFrame* pBaseMemForCar[NUM_CHASE_CARS];
static float &TimeMultiplier; static float TimeMultiplier;
static int &FId2; static int FId2;
public: public:
static bool IsRecording(void) { return Status == STATE_RECORD; } static bool IsRecording(void) { return Status == STATE_RECORD; }
@ -86,11 +86,11 @@ class CRecordDataForGame
STATE_RECORD = 1, STATE_RECORD = 1,
STATE_PLAYBACK = 2, STATE_PLAYBACK = 2,
}; };
static uint16& RecordingState; static uint16 RecordingState;
static uint8* &pDataBuffer; static uint8* pDataBuffer;
static uint8* &pDataBufferPointer; static uint8* pDataBufferPointer;
static int &FId; static int FId;
static tGameBuffer &pDataBufferForFrame; static tGameBuffer pDataBufferForFrame;
public: public:
static bool IsRecording() { return RecordingState == STATE_RECORD; } static bool IsRecording() { return RecordingState == STATE_RECORD; }

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Automobile.h" #include "Automobile.h"
#include "CarCtrl.h" #include "CarCtrl.h"
#include "Camera.h" #include "Camera.h"
@ -49,8 +49,3 @@ CRemote::TakeRemoteControlledCarFromPlayer(void)
CWorld::Players[CWorld::PlayerInFocus].m_bInRemoteMode = true; CWorld::Players[CWorld::PlayerInFocus].m_bInRemoteMode = true;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true; CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
} }
STARTPATCHES
InjectHook(0x435C30, &CRemote::GivePlayerRemoteControlledCar, PATCH_JUMP);
InjectHook(0x435DA0, &CRemote::TakeRemoteControlledCarFromPlayer, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#include "Boat.h" #include "Boat.h"
#include "SpecialFX.h" #include "SpecialFX.h"
@ -39,71 +39,73 @@
#include "Camera.h" #include "Camera.h"
#include "Radar.h" #include "Radar.h"
uint8 &CReplay::Mode = *(uint8*)0x95CD5B; uint8 CReplay::Mode;
CAddressInReplayBuffer &CReplay::Record = *(CAddressInReplayBuffer*)0x942F7C; CAddressInReplayBuffer CReplay::Record;
CAddressInReplayBuffer &CReplay::Playback = *(CAddressInReplayBuffer*)0x8F5F48; CAddressInReplayBuffer CReplay::Playback;
uint8 *&CReplay::pBuf0 = *(uint8**)0x8E2C64; uint8 *CReplay::pBuf0;
CAutomobile *&CReplay::pBuf1 = *(CAutomobile**)0x8E2C68; CAutomobile *CReplay::pBuf1;
uint8 *&CReplay::pBuf2 = *(uint8**)0x8E2C6C; uint8 *CReplay::pBuf2;
CPlayerPed *&CReplay::pBuf3 = *(CPlayerPed**)0x8E2C70; CPlayerPed *CReplay::pBuf3;
uint8 *&CReplay::pBuf4 = *(uint8**)0x8E2C74; uint8 *CReplay::pBuf4;
CCutsceneHead *&CReplay::pBuf5 = *(CCutsceneHead**)0x8E2C78; CCutsceneHead *CReplay::pBuf5;
uint8 *&CReplay::pBuf6 = *(uint8**)0x8E2C80; uint8 *CReplay::pBuf6;
CPtrNode *&CReplay::pBuf7 = *(CPtrNode**)0x8E2C84; CPtrNode *CReplay::pBuf7;
uint8 *&CReplay::pBuf8 = *(uint8**)0x8E2C54; uint8 *CReplay::pBuf8;
CEntryInfoNode *&CReplay::pBuf9 = *(CEntryInfoNode**)0x8E2C58; CEntryInfoNode *CReplay::pBuf9;
uint8 *&CReplay::pBuf10 = *(uint8**)0x8F2C28; uint8 *CReplay::pBuf10;
CDummyPed *&CReplay::pBuf11 = *(CDummyPed**)0x8F2C2C; CDummyPed *CReplay::pBuf11;
uint8 *&CReplay::pRadarBlips = *(uint8**)0x8F29F8; uint8 *CReplay::pRadarBlips;
uint8 *&CReplay::pStoredCam = *(uint8**)0x8F2C34; uint8 *CReplay::pStoredCam;
uint8 *&CReplay::pWorld1 = *(uint8**)0x8E29C4; uint8 *CReplay::pWorld1;
CReference *&CReplay::pEmptyReferences = *(CReference**)0x8F256C; CReference *CReplay::pEmptyReferences;
CStoredDetailedAnimationState *&CReplay::pPedAnims = *(CStoredDetailedAnimationState**)0x8F6260; CStoredDetailedAnimationState *CReplay::pPedAnims;
uint8 *&CReplay::pPickups = *(uint8**)0x8F1A48; uint8 *CReplay::pPickups;
uint8 *&CReplay::pReferences = *(uint8**)0x880FAC; uint8 *CReplay::pReferences;
uint8(&CReplay::BufferStatus)[NUM_REPLAYBUFFERS] = *(uint8(*)[NUM_REPLAYBUFFERS])*(uintptr*)0x8804D8; uint8 CReplay::BufferStatus[NUM_REPLAYBUFFERS];
uint8(&CReplay::Buffers)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE] = *(uint8(*)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE])*(uintptr*)0x779958; uint8 CReplay::Buffers[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
bool &CReplay::bPlayingBackFromFile = *(bool*)0x95CD58; bool CReplay::bPlayingBackFromFile;
bool &CReplay::bReplayEnabled = *(bool*)0x617CAC; bool CReplay::bReplayEnabled = true;
uint32 &CReplay::SlowMotion = *(uint32*)0x9414D4; uint32 CReplay::SlowMotion;
uint32 &CReplay::FramesActiveLookAroundCam = *(uint32*)0x880F84; uint32 CReplay::FramesActiveLookAroundCam;
bool &CReplay::bDoLoadSceneWhenDone = *(bool*)0x95CD76; bool CReplay::bDoLoadSceneWhenDone;
CPtrList &CReplay::WorldPtrList = *(CPtrList*)0x880F90; CPtrNode* CReplay::WorldPtrList;
CPtrList &CReplay::BigBuildingPtrList = *(CPtrList*)0x941284; CPtrNode* CReplay::BigBuildingPtrList;
CWanted &CReplay::PlayerWanted = *(CWanted*)0x8F6278; CWanted CReplay::PlayerWanted;
CPlayerInfo &CReplay::PlayerInfo = *(CPlayerInfo*)0x8F5840; CPlayerInfo CReplay::PlayerInfo;
uint32 &CReplay::Time1 = *(uint32*)0x8F29DC; uint32 CReplay::Time1;
uint32 &CReplay::Time2 = *(uint32*)0x8F29D0; uint32 CReplay::Time2;
uint32 &CReplay::Time3 = *(uint32*)0x8F29D4; uint32 CReplay::Time3;
uint32 &CReplay::Time4 = *(uint32*)0x8F29C8; uint32 CReplay::Time4;
uint32 &CReplay::Frame = *(uint32*)0x8F2554; uint32 CReplay::Frame;
uint8 &CReplay::ClockHours = *(uint8*)0x95CDC5; uint8 CReplay::ClockHours;
uint8 &CReplay::ClockMinutes = *(uint8*)0x95CDA2; uint8 CReplay::ClockMinutes;
uint16 &CReplay::OldWeatherType = *(uint16*)0x95CCEA; uint16 CReplay::OldWeatherType;
uint16 &CReplay::NewWeatherType = *(uint16*)0x95CC6E; uint16 CReplay::NewWeatherType;
float &CReplay::WeatherInterpolationValue = *(float*)0x8F1A28; float CReplay::WeatherInterpolationValue;
float &CReplay::TimeStepNonClipped = *(float*)0x8F5FF4; float CReplay::TimeStepNonClipped;
float &CReplay::TimeStep = *(float*)0x8F2C24; float CReplay::TimeStep;
float &CReplay::TimeScale = *(float*)0x880E20; float CReplay::TimeScale;
float &CReplay::CameraFixedX = *(float*)0x943054; float CReplay::CameraFixedX;
float &CReplay::CameraFixedY = *(float*)0x943058; float CReplay::CameraFixedY;
float &CReplay::CameraFixedZ = *(float*)0x94305C; float CReplay::CameraFixedZ;
int32 &CReplay::OldRadioStation = *(int32*)0x94151C; int32 CReplay::OldRadioStation;
int8 &CReplay::CameraMode = *(int8*)0x95CD5F; int8 CReplay::CameraMode;
bool &CReplay::bAllowLookAroundCam = *(bool*)0x95CDCD; bool CReplay::bAllowLookAroundCam;
float &CReplay::LoadSceneX = *(float*)0x880F9C; float CReplay::LoadSceneX;
float &CReplay::LoadSceneY = *(float*)0x880F98; float CReplay::LoadSceneY;
float &CReplay::LoadSceneZ = *(float*)0x880F94; float CReplay::LoadSceneZ;
float &CReplay::CameraFocusX = *(float*)0x942F5C; float CReplay::CameraFocusX;
float &CReplay::CameraFocusY = *(float*)0x942F74; float CReplay::CameraFocusY;
float &CReplay::CameraFocusZ = *(float*)0x942F58; float CReplay::CameraFocusZ;
bool &CReplay::bPlayerInRCBuggy = *(bool*)0x95CDC3; bool CReplay::bPlayerInRCBuggy;
float &CReplay::fDistanceLookAroundCam = *(float*)0x885B44; float CReplay::fDistanceLookAroundCam;
float &CReplay::fBetaAngleLookAroundCam = *(float*)0x94072C; float CReplay::fBetaAngleLookAroundCam;
float &CReplay::fAlphaAngleLookAroundCam = *(float*)0x8F2A0C; float CReplay::fAlphaAngleLookAroundCam;
#ifdef FIX_BUGS
int CReplay::nHandleOfPlayerPed[NUMPLAYERS];
#endif
static void(*(&CBArray)[30])(CAnimBlendAssociation*, void*) = *(void(*(*)[30])(CAnimBlendAssociation*, void*))*(uintptr*)0x61052C; static void(*CBArray[])(CAnimBlendAssociation*, void*) =
static void(*CBArray_RE3[])(CAnimBlendAssociation*, void*) =
{ {
nil, &CPed::PedGetupCB, &CPed::PedStaggerCB, &CPed::PedEvadeCB, &CPed::FinishDieAnimCB, nil, &CPed::PedGetupCB, &CPed::PedStaggerCB, &CPed::PedEvadeCB, &CPed::FinishDieAnimCB,
&CPed::FinishedWaitCB, &CPed::FinishLaunchCB, &CPed::FinishHitHeadCB, &CPed::PedAnimGetInCB, &CPed::PedAnimDoorOpenCB, &CPed::FinishedWaitCB, &CPed::FinishLaunchCB, &CPed::FinishHitHeadCB, &CPed::PedAnimGetInCB, &CPed::PedAnimDoorOpenCB,
@ -119,16 +121,13 @@ static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*))
if (CBArray[i] == f) if (CBArray[i] == f)
return i; return i;
} }
for (int i = 0; i < sizeof(CBArray_RE3) / sizeof(*CBArray_RE3); i++) {
if (CBArray_RE3[i] == f)
return i;
}
return 0; return 0;
} }
static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*) static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*)
{ {
return CBArray_RE3[id]; return CBArray[id];
} }
static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying) static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying)
@ -279,7 +278,7 @@ void CReplay::RecordThisFrame(void)
continue; continue;
memory_required += sizeof(tBulletTracePacket); memory_required += sizeof(tBulletTracePacket);
} }
memory_required += sizeof(tEndOfFramePacket); memory_required += sizeof(tEndOfFramePacket) + 1; // 1 for Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
if (Record.m_nOffset + memory_required > REPLAYBUFFERSIZE) { if (Record.m_nOffset + memory_required > REPLAYBUFFERSIZE) {
Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
BufferStatus[Record.m_bSlot] = REPLAYBUFFER_PLAYBACK; BufferStatus[Record.m_bSlot] = REPLAYBUFFER_PLAYBACK;
@ -682,9 +681,9 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id)
vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */ vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */
vp->acceleration = vehicle->m_fGasPedal * 100.0f; vp->acceleration = vehicle->m_fGasPedal * 100.0f;
vp->panels = vehicle->IsCar() ? ((CAutomobile*)vehicle)->Damage.m_panelStatus : 0; vp->panels = vehicle->IsCar() ? ((CAutomobile*)vehicle)->Damage.m_panelStatus : 0;
vp->velocityX = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */ vp->velocityX = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */
vp->velocityY = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().y)); vp->velocityY = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().y));
vp->velocityZ = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().z)); vp->velocityZ = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().z));
vp->mi = vehicle->GetModelIndex(); vp->mi = vehicle->GetModelIndex();
vp->primary_color = vehicle->m_currentColour1; vp->primary_color = vehicle->m_currentColour1;
vp->secondary_color = vehicle->m_currentColour2; vp->secondary_color = vehicle->m_currentColour2;
@ -1087,7 +1086,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
Playback.m_bSlot = first; Playback.m_bSlot = first;
Playback.m_nOffset = 0; Playback.m_nOffset = 0;
Playback.m_pBase = Buffers[first]; Playback.m_pBase = Buffers[first];
CObject::DeleteAllTempObjectInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f); CObject::DeleteAllTempObjectsInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f);
StoreStuffInMem(); StoreStuffInMem();
EmptyPedsAndVehiclePools(); EmptyPedsAndVehiclePools();
SlowMotion = 1; SlowMotion = 1;
@ -1112,6 +1111,10 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
void CReplay::StoreStuffInMem(void) void CReplay::StoreStuffInMem(void)
{ {
#ifdef FIX_BUGS
for (int i = 0; i < NUMPLAYERS; i++)
nHandleOfPlayerPed[i] = CPools::GetPedPool()->GetIndex(CWorld::Players[i].m_pPed);
#endif
CPools::GetVehiclePool()->Store(pBuf0, pBuf1); CPools::GetVehiclePool()->Store(pBuf0, pBuf1);
CPools::GetPedPool()->Store(pBuf2, pBuf3); CPools::GetPedPool()->Store(pBuf2, pBuf3);
CPools::GetObjectPool()->Store(pBuf4, pBuf5); CPools::GetObjectPool()->Store(pBuf4, pBuf5);
@ -1120,8 +1123,8 @@ void CReplay::StoreStuffInMem(void)
CPools::GetDummyPool()->Store(pBuf10, pBuf11); CPools::GetDummyPool()->Store(pBuf10, pBuf11);
pWorld1 = new uint8[sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y]; pWorld1 = new uint8[sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y];
memcpy(pWorld1, CWorld::GetSector(0, 0), NUMSECTORS_X * NUMSECTORS_Y * sizeof(CSector)); memcpy(pWorld1, CWorld::GetSector(0, 0), NUMSECTORS_X * NUMSECTORS_Y * sizeof(CSector));
WorldPtrList = CWorld::GetMovingEntityList(); WorldPtrList = CWorld::GetMovingEntityList().first; // why
BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_NONE); BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_NONE).first;
pPickups = new uint8[sizeof(CPickup) * NUMPICKUPS]; pPickups = new uint8[sizeof(CPickup) * NUMPICKUPS];
memcpy(pPickups, CPickups::aPickUps, NUMPICKUPS * sizeof(CPickup)); memcpy(pPickups, CPickups::aPickUps, NUMPICKUPS * sizeof(CPickup));
pReferences = new uint8[(sizeof(CReference) * NUMREFERENCES)]; pReferences = new uint8[(sizeof(CReference) * NUMREFERENCES)];
@ -1166,8 +1169,8 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(CWorld::GetSector(0, 0), pWorld1, sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y); memcpy(CWorld::GetSector(0, 0), pWorld1, sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y);
delete[] pWorld1; delete[] pWorld1;
pWorld1 = nil; pWorld1 = nil;
CWorld::GetMovingEntityList() = WorldPtrList; CWorld::GetMovingEntityList().first = WorldPtrList;
CWorld::GetBigBuildingList(LEVEL_NONE) = BigBuildingPtrList; CWorld::GetBigBuildingList(LEVEL_NONE).first = BigBuildingPtrList;
memcpy(CPickups::aPickUps, pPickups, sizeof(CPickup) * NUMPICKUPS); memcpy(CPickups::aPickUps, pPickups, sizeof(CPickup) * NUMPICKUPS);
delete[] pPickups; delete[] pPickups;
pPickups = nil; pPickups = nil;
@ -1182,6 +1185,14 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS); memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
delete[] pRadarBlips; delete[] pRadarBlips;
pRadarBlips = nil; pRadarBlips = nil;
#ifdef FIX_BUGS
for (int i = 0; i < NUMPLAYERS; i++) {
CPlayerPed* pPlayerPed = (CPlayerPed*)CPools::GetPedPool()->GetAt(nHandleOfPlayerPed[i]);
assert(pPlayerPed);
CWorld::Players[i].m_pPed = pPlayerPed;
pPlayerPed->RegisterReference((CEntity**)&CWorld::Players[i].m_pPed);
}
#endif
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted); FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);
CWorld::Players[0] = PlayerInfo; CWorld::Players[0] = PlayerInfo;
int i = CPools::GetPedPool()->GetSize(); int i = CPools::GetPedPool()->GetSize();
@ -1215,7 +1226,7 @@ void CReplay::RestoreStuffFromMem(void)
vehicle->SetModelIndex(mi); vehicle->SetModelIndex(mi);
if (mi == MI_DODO){ if (mi == MI_DODO){
CAutomobile* dodo = (CAutomobile*)vehicle; CAutomobile* dodo = (CAutomobile*)vehicle;
RpAtomicSetFlags(GetFirstObject(dodo->m_aCarNodes[CAR_WHEEL_LF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(dodo->m_aCarNodes[CAR_WHEEL_LF]), 0);
CMatrix tmp1; CMatrix tmp1;
tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false); tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false);
CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false); CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false);
@ -1243,7 +1254,7 @@ void CReplay::RestoreStuffFromMem(void)
vehicle->GetMatrix().Detach(); vehicle->GetMatrix().Detach();
if (vehicle->m_rwObject){ if (vehicle->m_rwObject){
if (RwObjectGetType(vehicle->m_rwObject) == rpATOMIC){ if (RwObjectGetType(vehicle->m_rwObject) == rpATOMIC){
RwFrame* frame = RpAtomicGetFrame(vehicle->m_rwObject); RwFrame* frame = RpAtomicGetFrame((RpAtomic*)vehicle->m_rwObject);
RpAtomicDestroy((RpAtomic*)vehicle->m_rwObject); RpAtomicDestroy((RpAtomic*)vehicle->m_rwObject);
RwFrameDestroy(frame); RwFrameDestroy(frame);
} }
@ -1254,7 +1265,7 @@ void CReplay::RestoreStuffFromMem(void)
int model_id = info->m_wheelId; int model_id = info->m_wheelId;
if (model_id != -1){ if (model_id != -1){
if ((vehicle->m_rwObject = CModelInfo::GetModelInfo(model_id)->CreateInstance())){ if ((vehicle->m_rwObject = CModelInfo::GetModelInfo(model_id)->CreateInstance())){
vehicle->GetMatrix().AttachRW(&((RwFrame*)vehicle->m_rwObject->parent)->modelling, false); vehicle->GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)vehicle->m_rwObject)), false);
} }
} }
} }
@ -1274,7 +1285,7 @@ void CReplay::RestoreStuffFromMem(void)
object->SetModelIndex(mi); object->SetModelIndex(mi);
object->GetMatrix().m_attachment = nil; object->GetMatrix().m_attachment = nil;
if (RwObjectGetType(object->m_rwObject) == rpATOMIC) if (RwObjectGetType(object->m_rwObject) == rpATOMIC)
object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(object->m_rwObject)), false); object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)object->m_rwObject)), false);
} }
i = CPools::GetDummyPool()->GetSize(); i = CPools::GetDummyPool()->GetSize();
while (--i >= 0) { while (--i >= 0) {
@ -1289,7 +1300,7 @@ void CReplay::RestoreStuffFromMem(void)
dummy->SetModelIndex(mi); dummy->SetModelIndex(mi);
dummy->GetMatrix().m_attachment = nil; dummy->GetMatrix().m_attachment = nil;
if (RwObjectGetType(dummy->m_rwObject) == rpATOMIC) if (RwObjectGetType(dummy->m_rwObject) == rpATOMIC)
dummy->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(dummy->m_rwObject)), false); dummy->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)dummy->m_rwObject)), false);
} }
CTimer::SetTimeInMilliseconds(Time1); CTimer::SetTimeInMilliseconds(Time1);
CTimer::SetTimeInMillisecondsNonClipped(Time2); CTimer::SetTimeInMillisecondsNonClipped(Time2);
@ -1397,8 +1408,8 @@ void CReplay::SaveReplayToHD(void)
for (first = (current + 1) % NUM_REPLAYBUFFERS; ; first = (first + 1) % NUM_REPLAYBUFFERS) for (first = (current + 1) % NUM_REPLAYBUFFERS; ; first = (first + 1) % NUM_REPLAYBUFFERS)
if (BufferStatus[first] == REPLAYBUFFER_RECORD || BufferStatus[first] == REPLAYBUFFER_PLAYBACK) if (BufferStatus[first] == REPLAYBUFFER_RECORD || BufferStatus[first] == REPLAYBUFFER_PLAYBACK)
break; break;
for(int i = first;; i = (i + 1) % NUM_REPLAYBUFFERS){ for(int i = first; ; i = (i + 1) % NUM_REPLAYBUFFERS){
CFileMgr::Write(fw, (char*)Buffers[first], sizeof(Buffers[first])); CFileMgr::Write(fw, (char*)Buffers[i], sizeof(Buffers[i]));
if (BufferStatus[i] == REPLAYBUFFER_RECORD) if (BufferStatus[i] == REPLAYBUFFER_RECORD)
break; break;
} }
@ -1501,9 +1512,9 @@ void CReplay::ProcessLookAroundCam(void)
--FramesActiveLookAroundCam; --FramesActiveLookAroundCam;
fBetaAngleLookAroundCam += x_moved; fBetaAngleLookAroundCam += x_moved;
if (CPad::NewMouseControllerState.LMB && CPad::NewMouseControllerState.RMB) if (CPad::NewMouseControllerState.LMB && CPad::NewMouseControllerState.RMB)
fDistanceLookAroundCam = max(3.0f, min(15.0f, fDistanceLookAroundCam + 2.0f * y_moved)); fDistanceLookAroundCam = Max(3.0f, Min(15.0f, fDistanceLookAroundCam + 2.0f * y_moved));
else else
fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved)); fAlphaAngleLookAroundCam = Max(0.1f, Min(1.5f, fAlphaAngleLookAroundCam + y_moved));
CVector camera_pt( CVector camera_pt(
fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam), fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam), fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
@ -1574,16 +1585,3 @@ void CReplay::Display()
if (Mode == MODE_PLAYBACK) if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY")); CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
} }
STARTPATCHES
InjectHook(0x592FE0, &CReplay::Init, PATCH_JUMP);
InjectHook(0x593150, &CReplay::DisableReplays, PATCH_JUMP);
InjectHook(0x593160, &CReplay::EnableReplays, PATCH_JUMP);
InjectHook(0x593170, &CReplay::Update, PATCH_JUMP);
InjectHook(0x595B20, &CReplay::FinishPlayback, PATCH_JUMP);
InjectHook(0x595BD0, &CReplay::EmptyReplayBuffer, PATCH_JUMP);
InjectHook(0x595EE0, &CReplay::Display, PATCH_JUMP);
InjectHook(0x596030, &CReplay::TriggerPlayback, PATCH_JUMP);
InjectHook(0x597560, &CReplay::StreamAllNecessaryCarsAndPeds, PATCH_JUMP);
InjectHook(0x597680, &CReplay::ShouldStandardCameraBeProcessed, PATCH_JUMP);
ENDPATCHES

View file

@ -192,7 +192,7 @@ class CReplay
int8 velocityX; int8 velocityX;
int8 velocityY; int8 velocityY;
int8 velocityZ; int8 velocityZ;
union{ union {
int8 car_gun; int8 car_gun;
int8 wheel_state; int8 wheel_state;
}; };
@ -205,68 +205,71 @@ class CReplay
static_assert(sizeof(tVehicleUpdatePacket) == 48, "tVehicleUpdatePacket: error"); static_assert(sizeof(tVehicleUpdatePacket) == 48, "tVehicleUpdatePacket: error");
private: private:
static uint8 &Mode; static uint8 Mode;
static CAddressInReplayBuffer &Record; static CAddressInReplayBuffer Record;
static CAddressInReplayBuffer &Playback; static CAddressInReplayBuffer Playback;
static uint8 *&pBuf0; static uint8* pBuf0;
static CAutomobile *&pBuf1; static CAutomobile* pBuf1;
static uint8 *&pBuf2; static uint8* pBuf2;
static CPlayerPed *&pBuf3; static CPlayerPed* pBuf3;
static uint8 *&pBuf4; static uint8* pBuf4;
static CCutsceneHead *&pBuf5; static CCutsceneHead* pBuf5;
static uint8 *&pBuf6; static uint8* pBuf6;
static CPtrNode *&pBuf7; static CPtrNode* pBuf7;
static uint8 *&pBuf8; static uint8* pBuf8;
static CEntryInfoNode *&pBuf9; static CEntryInfoNode* pBuf9;
static uint8 *&pBuf10; static uint8* pBuf10;
static CDummyPed *&pBuf11; static CDummyPed* pBuf11;
static uint8 *&pRadarBlips; static uint8* pRadarBlips;
static uint8 *&pStoredCam; static uint8* pStoredCam;
static uint8 *&pWorld1; static uint8* pWorld1;
static CReference *&pEmptyReferences; static CReference* pEmptyReferences;
static CStoredDetailedAnimationState *&pPedAnims; static CStoredDetailedAnimationState* pPedAnims;
static uint8 *&pPickups; static uint8* pPickups;
static uint8 *&pReferences; static uint8* pReferences;
static uint8 (&BufferStatus)[NUM_REPLAYBUFFERS]; static uint8 BufferStatus[NUM_REPLAYBUFFERS];
static uint8 (&Buffers)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE]; static uint8 Buffers[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
static bool &bPlayingBackFromFile; static bool bPlayingBackFromFile;
static bool &bReplayEnabled; static bool bReplayEnabled;
static uint32 &SlowMotion; static uint32 SlowMotion;
static uint32 &FramesActiveLookAroundCam; static uint32 FramesActiveLookAroundCam;
static bool &bDoLoadSceneWhenDone; static bool bDoLoadSceneWhenDone;
static CPtrList &WorldPtrList; static CPtrNode* WorldPtrList;
static CPtrList &BigBuildingPtrList; static CPtrNode* BigBuildingPtrList;
static CWanted &PlayerWanted; static CWanted PlayerWanted;
static CPlayerInfo &PlayerInfo; static CPlayerInfo PlayerInfo;
static uint32 &Time1; static uint32 Time1;
static uint32 &Time2; static uint32 Time2;
static uint32 &Time3; static uint32 Time3;
static uint32 &Time4; static uint32 Time4;
static uint32 &Frame; static uint32 Frame;
static uint8 &ClockHours; static uint8 ClockHours;
static uint8 &ClockMinutes; static uint8 ClockMinutes;
static uint16 &OldWeatherType; static uint16 OldWeatherType;
static uint16 &NewWeatherType; static uint16 NewWeatherType;
static float &WeatherInterpolationValue; static float WeatherInterpolationValue;
static float &TimeStepNonClipped; static float TimeStepNonClipped;
static float &TimeStep; static float TimeStep;
static float &TimeScale; static float TimeScale;
static float &CameraFixedX; static float CameraFixedX;
static float &CameraFixedY; static float CameraFixedY;
static float &CameraFixedZ; static float CameraFixedZ;
static int32 &OldRadioStation; static int32 OldRadioStation;
static int8 &CameraMode; static int8 CameraMode;
static bool &bAllowLookAroundCam; static bool bAllowLookAroundCam;
static float &LoadSceneX; static float LoadSceneX;
static float &LoadSceneY; static float LoadSceneY;
static float &LoadSceneZ; static float LoadSceneZ;
static float &CameraFocusX; static float CameraFocusX;
static float &CameraFocusY; static float CameraFocusY;
static float &CameraFocusZ; static float CameraFocusZ;
static bool &bPlayerInRCBuggy; static bool bPlayerInRCBuggy;
static float &fDistanceLookAroundCam; static float fDistanceLookAroundCam;
static float &fAlphaAngleLookAroundCam; static float fAlphaAngleLookAroundCam;
static float &fBetaAngleLookAroundCam; static float fBetaAngleLookAroundCam;
#ifdef FIX_BUGS
static int nHandleOfPlayerPed[NUMPLAYERS];
#endif
public: public:
static void Init(void); static void Init(void);

View file

@ -1,25 +1,25 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Restart.h" #include "Restart.h"
#include "Zones.h" #include "Zones.h"
#include "PathFind.h" #include "PathFind.h"
uint8 &CRestart::OverrideHospitalLevel = *(uint8*)0x95CD4C; uint8 CRestart::OverrideHospitalLevel;
uint8 &CRestart::OverridePoliceStationLevel = *(uint8*)0x95CD50; uint8 CRestart::OverridePoliceStationLevel;
bool &CRestart::bFadeInAfterNextArrest = *(bool*)0x95CD69; bool CRestart::bFadeInAfterNextArrest;
bool &CRestart::bFadeInAfterNextDeath = *(bool*)0x95CD9D; bool CRestart::bFadeInAfterNextDeath;
bool &CRestart::bOverrideRestart = *(bool*)0x95CD5D; bool CRestart::bOverrideRestart;
CVector &CRestart::OverridePosition = *(CVector*)0x8E2C00; CVector CRestart::OverridePosition;
float &CRestart::OverrideHeading = *(float*)0x8F2A18; float CRestart::OverrideHeading;
CVector(&CRestart::HospitalRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x87F9B0; CVector CRestart::HospitalRestartPoints[NUM_RESTART_POINTS];
float(&CRestart::HospitalRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D40; float CRestart::HospitalRestartHeadings[NUM_RESTART_POINTS];
uint16 &CRestart::NumberOfHospitalRestarts = *(uint16*)0x95CC46; uint16 CRestart::NumberOfHospitalRestarts;
CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x846228; CVector CRestart::PoliceRestartPoints[NUM_RESTART_POINTS];
float(&CRestart::PoliceRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D20; float CRestart::PoliceRestartHeadings[NUM_RESTART_POINTS];
uint16 &CRestart::NumberOfPoliceRestarts = *(uint16*)0x95CC44; uint16 CRestart::NumberOfPoliceRestarts;
void void
CRestart::Initialise() CRestart::Initialise()
@ -247,16 +247,3 @@ INITSAVEBUF
WriteSaveBuf(buf, OverridePoliceStationLevel); WriteSaveBuf(buf, OverridePoliceStationLevel);
VALIDATESAVEBUF(*size); VALIDATESAVEBUF(*size);
} }
STARTPATCHES
InjectHook(0x435E20, &CRestart::Initialise, PATCH_JUMP);
InjectHook(0x436100, &CRestart::AddHospitalRestartPoint, PATCH_JUMP);
InjectHook(0x436150, &CRestart::AddPoliceRestartPoint, PATCH_JUMP);
InjectHook(0x4366C0, &CRestart::OverrideNextRestart, PATCH_JUMP);
InjectHook(0x4366F0, &CRestart::CancelOverrideRestart, PATCH_JUMP);
InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP);
InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP);
InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP);
InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
ENDPATCHES

View file

@ -17,20 +17,20 @@ public:
static void LoadAllRestartPoints(uint8 *buf, uint32 size); static void LoadAllRestartPoints(uint8 *buf, uint32 size);
static void SaveAllRestartPoints(uint8 *buf, uint32 *size); static void SaveAllRestartPoints(uint8 *buf, uint32 *size);
static uint8 &OverrideHospitalLevel; static uint8 OverrideHospitalLevel;
static uint8 &OverridePoliceStationLevel; static uint8 OverridePoliceStationLevel;
static bool &bFadeInAfterNextArrest; static bool bFadeInAfterNextArrest;
static bool &bFadeInAfterNextDeath; static bool bFadeInAfterNextDeath;
static bool &bOverrideRestart; static bool bOverrideRestart;
static CVector &OverridePosition; static CVector OverridePosition;
static float &OverrideHeading; static float OverrideHeading;
static CVector(&HospitalRestartPoints)[NUM_RESTART_POINTS]; static CVector HospitalRestartPoints[NUM_RESTART_POINTS];
static float (&HospitalRestartHeadings)[NUM_RESTART_POINTS]; static float HospitalRestartHeadings[NUM_RESTART_POINTS];
static uint16 &NumberOfHospitalRestarts; static uint16 NumberOfHospitalRestarts;
static CVector (&PoliceRestartPoints)[NUM_RESTART_POINTS]; static CVector PoliceRestartPoints[NUM_RESTART_POINTS];
static float (&PoliceRestartHeadings)[NUM_RESTART_POINTS]; static float PoliceRestartHeadings[NUM_RESTART_POINTS];
static uint16 &NumberOfPoliceRestarts; static uint16 NumberOfPoliceRestarts;
}; };

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "RoadBlocks.h" #include "RoadBlocks.h"
#include "PathFind.h" #include "PathFind.h"
#include "ModelIndices.h" #include "ModelIndices.h"
@ -15,9 +15,9 @@
#include "CarCtrl.h" #include "CarCtrl.h"
#include "General.h" #include "General.h"
int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34; int16 CRoadBlocks::NumRoadBlocks;
int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8; int16 CRoadBlocks::RoadBlockObjects[NUMROADBLOCKS];
bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810; bool CRoadBlocks::InOrOut[NUMROADBLOCKS];
void void
CRoadBlocks::Init(void) CRoadBlocks::Init(void)
@ -195,9 +195,3 @@ CRoadBlocks::GenerateRoadBlocks(void)
} }
} }
} }
STARTPATCHES
InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP);
InjectHook(0x4376A0, &CRoadBlocks::GenerateRoadBlockCopsForCar, PATCH_JUMP);
InjectHook(0x436FA0, &CRoadBlocks::GenerateRoadBlocks, PATCH_JUMP);
ENDPATCHES

View file

@ -6,9 +6,9 @@ class CVehicle;
class CRoadBlocks class CRoadBlocks
{ {
public: public:
static int16 (&NumRoadBlocks); static int16 NumRoadBlocks;
static int16 (&RoadBlockObjects)[NUMROADBLOCKS]; static int16 RoadBlockObjects[NUMROADBLOCKS];
static bool (&InOrOut)[NUMROADBLOCKS]; static bool InOrOut[NUMROADBLOCKS];
static void Init(void); static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode); static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode);

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,95 @@
#pragma once #pragma once
class CPed;
class CVehicle;
struct CMovieCommand
{
int32 m_nCommandId;
CVector m_vecPosition;
CVector m_vecCamera;
int16 m_nActorId;
int16 m_nActor2Id;
int16 m_nVehicleId;
int16 m_nModelIndex;
};
class CSceneEdit class CSceneEdit
{ {
public: public:
static bool &m_bEditOn; enum {
static int32 &m_bCameraFollowActor; MOVIE_DO_NOTHING = 0,
static bool &m_bRecording; MOVIE_NEW_ACTOR,
static CVector &m_vecCurrentPosition; MOVIE_MOVE_ACTOR,
static CVector &m_vecCamHeading; MOVIE_SELECT_ACTOR,
MOVIE_DELETE_ACTOR,
MOVIE_NEW_VEHICLE,
MOVIE_MOVE_VEHICLE,
MOVIE_SELECT_VEHICLE,
MOVIE_DELETE_VEHICLE,
MOVIE_GIVE_WEAPON,
MOVIE_GOTO,
MOVIE_GOTO_WAIT,
MOVIE_GET_IN_CAR,
MOVIE_GET_OUT_CAR,
MOVIE_KILL,
MOVIE_FLEE,
MOVIE_WAIT,
MOVIE_POSITION_CAMERA,
MOVIE_SET_CAMERA_TARGET,
MOVIE_SELECT_CAMERA_MODE,
MOVIE_SAVE_MOVIE,
MOVIE_LOAD_MOVIE,
MOVIE_PLAY_MOVIE,
MOVIE_END,
MOVIE_TOTAL_COMMANDS
};
enum {
NUM_ACTORS_IN_MOVIE = 5,
NUM_VEHICLES_IN_MOVIE = 5,
NUM_COMMANDS_IN_MOVIE = 20
};
static int32 m_bCameraFollowActor;
static CVector m_vecCurrentPosition;
static CVector m_vecCamHeading;
static CVector m_vecGotoPosition;
static int32 m_nVehicle;
static int32 m_nVehicle2;
static int32 m_nActor;
static int32 m_nActor2;
static int32 m_nVehiclemodelId;
static int32 m_nPedmodelId;
static int16 m_nCurrentMovieCommand;
static int16 m_nCurrentCommand;
static int16 m_nCurrentVehicle;
static int16 m_nCurrentActor;
static bool m_bEditOn;
static bool m_bRecording;
static bool m_bCommandActive;
static bool m_bActorSelected;
static bool m_bActor2Selected;
static bool m_bVehicleSelected;
static int16 m_nNumActors;
static int16 m_nNumVehicles;
static int16 m_nNumMovieCommands;
static int16 m_nWeaponType;
static CPed* pActors[NUM_ACTORS_IN_MOVIE];
static CVehicle* pVehicles[NUM_VEHICLES_IN_MOVIE];
static bool m_bDrawGotoArrow;
static CMovieCommand Movie[NUM_COMMANDS_IN_MOVIE];
static void LoadMovie(void);
static void SaveMovie(void);
static void Initialise(void);
static void InitPlayback(void);
static void ReInitialise(void);
static void Update(void); static void Update(void);
static void Init(void); static void Draw(void);
static void ProcessCommand(void);
static void PlayBack(void);
static void ClearForNewCommand(void);
static void SelectActor(void);
static void SelectActor2(void);
static void SelectVehicle(void);
static bool SelectWeapon(void);
}; };

View file

@ -1,10 +1,10 @@
#define WITHWINDOWS // for our script loading hack #define WITHWINDOWS // for our script loading hack
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Script.h" #include "Script.h"
#include "ScriptCommands.h" #include "ScriptCommands.h"
#include "AnimBlendAssociation.h"
#include "Boat.h" #include "Boat.h"
#include "BulletInfo.h" #include "BulletInfo.h"
#include "Camera.h" #include "Camera.h"
@ -18,11 +18,12 @@
#include "Cranes.h" #include "Cranes.h"
#include "Credits.h" #include "Credits.h"
#include "CutsceneMgr.h" #include "CutsceneMgr.h"
#include "Darkel.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "Darkel.h"
#include "EmergencyPed.h" #include "EmergencyPed.h"
#include "Explosion.h" #include "Explosion.h"
#include "FileMgr.h" #include "FileMgr.h"
#include "Fire.h"
#include "Frontend.h" #include "Frontend.h"
#include "Gangs.h" #include "Gangs.h"
#include "Garages.h" #include "Garages.h"
@ -31,7 +32,6 @@
#include "Heli.h" #include "Heli.h"
#include "Hud.h" #include "Hud.h"
#include "Lines.h" #include "Lines.h"
#include "main.h"
#include "Messages.h" #include "Messages.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "Pad.h" #include "Pad.h"
@ -48,13 +48,12 @@
#include "Population.h" #include "Population.h"
#include "PowerPoints.h" #include "PowerPoints.h"
#include "ProjectileInfo.h" #include "ProjectileInfo.h"
#include "Radar.h"
#include "Record.h" #include "Record.h"
#include "Remote.h" #include "Remote.h"
#include "Restart.h"
#include "Replay.h" #include "Replay.h"
#include "Restart.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "Fire.h"
#include "Rubbish.h" #include "Rubbish.h"
#include "Shadows.h" #include "Shadows.h"
#include "SpecialFX.h" #include "SpecialFX.h"
@ -67,7 +66,7 @@
#include "Weather.h" #include "Weather.h"
#include "World.h" #include "World.h"
#include "Zones.h" #include "Zones.h"
#include "Radar.h" #include "main.h"
#define PICKUP_PLACEMENT_OFFSET 0.5f #define PICKUP_PLACEMENT_OFFSET 0.5f
#define PED_FIND_Z_OFFSET 5.0f #define PED_FIND_Z_OFFSET 5.0f
@ -87,47 +86,47 @@
#define FEET_IN_METER 3.33f #define FEET_IN_METER 3.33f
#endif #endif
uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248; uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE];
CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08; CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS];
int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200; int32 CTheScripts::BaseBriefIdForContact[MAX_NUM_CONTACTS];
int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0; int32 CTheScripts::OnAMissionForContactFlag[MAX_NUM_CONTACTS];
intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68; intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108; intro_script_rectangle CTheScripts::IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090; CSprite2d CTheScripts::ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60; script_sphere_struct CTheScripts::ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008; tCollectiveData CTheScripts::CollectiveArray[MAX_NUM_COLLECTIVES];
tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8; tUsedObject CTheScripts::UsedObjectArray[MAX_NUM_USED_OBJECTS];
int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558; int32 CTheScripts::MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30; tBuildingSwap CTheScripts::BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0; CEntity* CTheScripts::InvisibilitySettingArray[MAX_NUM_INVISIBILITY_SETTINGS];
CStoredLine (&CTheScripts::aStoredLines)[MAX_NUM_STORED_LINES] = *(CStoredLine(*)[MAX_NUM_STORED_LINES])*(uintptr*)0x743018; CStoredLine CTheScripts::aStoredLines[MAX_NUM_STORED_LINES];
bool &CTheScripts::DbgFlag = *(bool*)0x95CD87; bool CTheScripts::DbgFlag;
uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F1B64; uint32 CTheScripts::OnAMissionFlag;
int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C; int32 CTheScripts::StoreVehicleIndex;
bool &CTheScripts::StoreVehicleWasRandom = *(bool*)0x95CDBC; bool CTheScripts::StoreVehicleWasRandom;
CRunningScript *&CTheScripts::pIdleScripts = *(CRunningScript**)0x9430D4; CRunningScript *CTheScripts::pIdleScripts;
CRunningScript *&CTheScripts::pActiveScripts = *(CRunningScript**)0x8E2BF4; CRunningScript *CTheScripts::pActiveScripts;
uint32 &CTheScripts::NextFreeCollectiveIndex = *(uint32*)0x942F98; uint32 CTheScripts::NextFreeCollectiveIndex;
int32 &CTheScripts::LastRandomPedId = *(int32*)0x8F251C; int32 CTheScripts::LastRandomPedId;
uint16 &CTheScripts::NumberOfUsedObjects = *(uint16*)0x95CC72; uint16 CTheScripts::NumberOfUsedObjects;
bool &CTheScripts::bAlreadyRunningAMissionScript = *(bool*)0x95CDB3; bool CTheScripts::bAlreadyRunningAMissionScript;
bool &CTheScripts::bUsingAMultiScriptFile = *(bool*)0x95CD55; bool CTheScripts::bUsingAMultiScriptFile;
uint16 &CTheScripts::NumberOfMissionScripts = *(uint16*)0x95CC9A; uint16 CTheScripts::NumberOfMissionScripts;
uint32 &CTheScripts::LargestMissionScriptSize = *(uint32*)0x9414C8; uint32 CTheScripts::LargestMissionScriptSize;
uint32 &CTheScripts::MainScriptSize = *(uint32*)0x9405A4; uint32 CTheScripts::MainScriptSize;
uint8 &CTheScripts::FailCurrentMission = *(uint8*)0x95CD41; uint8 CTheScripts::FailCurrentMission;
uint8 &CTheScripts::CountdownToMakePlayerUnsafe = *(uint8*)0x95CD51; uint8 CTheScripts::CountdownToMakePlayerUnsafe;
uint8 &CTheScripts::DelayMakingPlayerUnsafeThisTime = *(uint8*)0x95CD88; uint8 CTheScripts::DelayMakingPlayerUnsafeThisTime;
uint16 &CTheScripts::NumScriptDebugLines = *(uint16*)0x95CC42; uint16 CTheScripts::NumScriptDebugLines;
uint16 &CTheScripts::NumberOfIntroRectanglesThisFrame = *(uint16*)0x95CC88; uint16 CTheScripts::NumberOfIntroRectanglesThisFrame;
uint16 &CTheScripts::NumberOfIntroTextLinesThisFrame = *(uint16*)0x95CC32; uint16 CTheScripts::NumberOfIntroTextLinesThisFrame;
uint8 &CTheScripts::UseTextCommands = *(uint8*)0x95CD57; uint8 CTheScripts::UseTextCommands;
CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24; CMissionCleanup CTheScripts::MissionCleanup;
CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450; CUpsideDownCarCheck CTheScripts::UpsideDownCars;
CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588; CStuckCarCheck CTheScripts::StuckCars;
uint16 &CTheScripts::CommandsExecuted = *(uint16*)0x95CCA6; uint16 CTheScripts::CommandsExecuted;
uint16 &CTheScripts::ScriptsUpdated = *(uint16*)0x95CC5E; uint16 CTheScripts::ScriptsUpdated;
int32(&ScriptParams)[32] = *(int32(*)[32])*(uintptr*)0x6ED460; int32 ScriptParams[32];
CMissionCleanup::CMissionCleanup() CMissionCleanup::CMissionCleanup()
{ {
@ -2010,7 +2009,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS; car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
car->m_status = STATUS_PHYSICS; car->m_status = STATUS_PHYSICS;
car->bEngineOn = true; car->bEngineOn = true;
car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); car->AutoPilot.m_nCruiseSpeed = Max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0; return 0;
} }
@ -2022,7 +2021,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CCarCtrl::JoinCarWithRoadSystem(car); CCarCtrl::JoinCarWithRoadSystem(car);
car->AutoPilot.m_nCarMission = MISSION_CRUISE; car->AutoPilot.m_nCarMission = MISSION_CRUISE;
car->bEngineOn = true; car->bEngineOn = true;
car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); car->AutoPilot.m_nCruiseSpeed = Max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0; return 0;
} }
@ -2106,7 +2105,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car); assert(car);
car->AutoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity);
return 0; return 0;
} }
case COMMAND_SET_CAR_DRIVING_STYLE: case COMMAND_SET_CAR_DRIVING_STYLE:
@ -3645,7 +3644,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pos.x = (infX + supX) / 2; pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2; pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = max(pos.x - infX, pos.y - infY); float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos, radius); pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos, radius);
return 0; return 0;
@ -4151,7 +4150,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pos.x = (infX + supX) / 2; pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2; pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = max(pos.x - infX, pos.y - infY); float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius); pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius);
return 0; return 0;
@ -4947,7 +4946,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pos.x = (infX + supX) / 2; pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2; pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = max(pos.x - infX, pos.y - infY); float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius); pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius);
return 0; return 0;
@ -5369,7 +5368,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
pos.x = (infX + supX) / 2; pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2; pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = max(pos.x - infX, pos.y - infY); float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius); pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0; return 0;
@ -5606,7 +5605,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE; pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE;
pVehicle->m_status = STATUS_PHYSICS; pVehicle->m_status = STATUS_PHYSICS;
pVehicle->bEngineOn = true; pVehicle->bEngineOn = true;
pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed); pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0; return 0;
} }
@ -5721,7 +5720,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS; pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
pBoat->AutoPilot.m_vecDestinationCoors = pos; pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->m_status = STATUS_PHYSICS; pBoat->m_status = STATUS_PHYSICS;
pBoat->AutoPilot.m_nCruiseSpeed = max(6, pBoat->AutoPilot.m_nCruiseSpeed); pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed);
pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0; return 0;
} }
@ -6306,23 +6305,23 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
return 0; return 0;
case COMMAND_REGISTER_JUMP_DISTANCE: case COMMAND_REGISTER_JUMP_DISTANCE:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CStats::MaximumJumpDistance = max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]); CStats::MaximumJumpDistance = Max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]);
return 0; return 0;
case COMMAND_REGISTER_JUMP_HEIGHT: case COMMAND_REGISTER_JUMP_HEIGHT:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CStats::MaximumJumpHeight = max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]); CStats::MaximumJumpHeight = Max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]);
return 0; return 0;
case COMMAND_REGISTER_JUMP_FLIPS: case COMMAND_REGISTER_JUMP_FLIPS:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CStats::MaximumJumpFlips = max(CStats::MaximumJumpFlips, ScriptParams[0]); CStats::MaximumJumpFlips = Max(CStats::MaximumJumpFlips, ScriptParams[0]);
return 0; return 0;
case COMMAND_REGISTER_JUMP_SPINS: case COMMAND_REGISTER_JUMP_SPINS:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CStats::MaximumJumpSpins = max(CStats::MaximumJumpSpins, ScriptParams[0]); CStats::MaximumJumpSpins = Max(CStats::MaximumJumpSpins, ScriptParams[0]);
return 0; return 0;
case COMMAND_REGISTER_JUMP_STUNT: case COMMAND_REGISTER_JUMP_STUNT:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CStats::BestStuntJump = max(CStats::BestStuntJump, ScriptParams[0]); CStats::BestStuntJump = Max(CStats::BestStuntJump, ScriptParams[0]);
return 0; return 0;
case COMMAND_REGISTER_UNIQUE_JUMP_FOUND: case COMMAND_REGISTER_UNIQUE_JUMP_FOUND:
++CStats::NumberOfUniqueJumpsFound; ++CStats::NumberOfUniqueJumpsFound;
@ -6436,9 +6435,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->FlagToDestroyWhenNextProcessed(); pPed->FlagToDestroyWhenNextProcessed();
} }
else if (CGame::nastyGame && pPed->IsPedInControl()) { else if (CGame::nastyGame && pPed->IsPedInControl()) {
RwMatrix tmp_rw; pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true);
CPedIK::GetWorldMatrix(pPed->m_pFrames[PED_HEAD]->frame, &tmp_rw);
pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, tmp_rw.pos, true);
} }
else { else {
pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
@ -6451,9 +6448,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
assert(pPed); assert(pPed);
if (CGame::nastyGame) { if (CGame::nastyGame) {
RwMatrix tmp_rw; pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true);
CPedIK::GetWorldMatrix(pPed->m_pFrames[PED_HEAD]->frame, &tmp_rw);
pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, tmp_rw.pos, true);
} }
else { else {
pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
@ -6855,10 +6850,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z); CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
int16 collisions; int16 collisions;
CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos, CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos,
min(cp1.x, min(cp2.x, min(cp3.x, cp4.x))), Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
min(cp1.y, min(cp2.y, min(cp3.y, cp4.y))), Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
max(cp1.x, max(cp2.x, max(cp3.x, cp4.x))), Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
max(cp1.y, max(cp2.y, max(cp3.y, cp4.y))), Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
&collisions, 2, nil, false, true, true, false, false); &collisions, 2, nil, false, true, true, false, false);
if (collisions > 0) if (collisions > 0)
obstacleInPath = true; obstacleInPath = true;
@ -6909,11 +6904,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z); CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z); CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
int16 collisions; int16 collisions;
CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos, CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, newPosition,
min(cp1.x, min(cp2.x, min(cp3.x, cp4.x))), Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
min(cp1.y, min(cp2.y, min(cp3.y, cp4.y))), Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
max(cp1.x, max(cp2.x, max(cp3.x, cp4.x))), Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
max(cp1.y, max(cp2.y, max(cp3.y, cp4.y))), Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
&collisions, 2, nil, false, true, true, false, false); &collisions, 2, nil, false, true, true, false, false);
if (collisions > 0) if (collisions > 0)
obstacleInPath = true; obstacleInPath = true;
@ -7746,7 +7741,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVector pos = *(CVector*)&ScriptParams[1]; CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT) if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float size = max(0.0f, *(float*)&ScriptParams[7]); float size = Max(0.0f, *(float*)&ScriptParams[7]);
eParticleObjectType type = (eParticleObjectType)ScriptParams[0]; eParticleObjectType type = (eParticleObjectType)ScriptParams[0];
RwRGBA color; RwRGBA color;
if (type == POBJECT_SMOKE_TRAIL){ if (type == POBJECT_SMOKE_TRAIL){
@ -8931,7 +8926,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed); assert(pPed);
if (ScriptParams[1]) if (ScriptParams[1])
pPed->m_nZoneLevel = -1; pPed->m_nZoneLevel = LEVEL_IGNORE;
else else
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition()); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition());
return 0; return 0;
@ -9130,7 +9125,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle); assert(pVehicle);
if (ScriptParams[1]) if (ScriptParams[1])
pVehicle->m_nZoneLevel = -1; pVehicle->m_nZoneLevel = LEVEL_IGNORE;
else else
pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(pVehicle->GetPosition()); pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(pVehicle->GetPosition());
return 0; return 0;
@ -9147,7 +9142,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
} }
case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER: case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
{ {
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle); assert(pVehicle);
CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false); CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false);
@ -10076,8 +10071,8 @@ void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D: case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
result = !pPlayerInfo->m_pPed->bInVehicle; result = !pPlayerInfo->m_pPed->bInVehicle;
break; break;
case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D: case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D: case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
result = pPlayerInfo->m_pPed->bInVehicle; result = pPlayerInfo->m_pPed->bInVehicle;
break; break;
default: default:
@ -11359,7 +11354,7 @@ VALIDATESAVEBUF(size)
void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity) void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity)
{ {
static CColPoint aTempColPoints[32]; static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
int16 entities = 0; int16 entities = 0;
CEntity* aEntities[16]; CEntity* aEntities[16];
CWorld::FindObjectsKindaColliding(pos, pEntity->GetBoundRadius(), false, &entities, 16, aEntities, false, true, true, false, false); CWorld::FindObjectsKindaColliding(pos, pEntity->GetBoundRadius(), false, &entities, 16, aEntities, false, true, true, false, false);
@ -11456,22 +11451,22 @@ void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, fl
supY = infY = Y; supY = infY = Y;
X = (x2 + x3) / 2; X = (x2 + x3) / 2;
Y = (y2 + y3) / 2; Y = (y2 + y3) / 2;
infX = min(infX, X); infX = Min(infX, X);
supX = max(supX, X); supX = Max(supX, X);
infY = min(infY, Y); infY = Min(infY, Y);
supY = max(supY, Y); supY = Max(supY, Y);
X = (x3 + x4) / 2; X = (x3 + x4) / 2;
Y = (y3 + y4) / 2; Y = (y3 + y4) / 2;
infX = min(infX, X); infX = Min(infX, X);
supX = max(supX, X); supX = Max(supX, X);
infY = min(infY, Y); infY = Min(infY, Y);
supY = max(supY, Y); supY = Max(supY, Y);
X = (x4 + x1) / 2; X = (x4 + x1) / 2;
Y = (y4 + y1) / 2; Y = (y4 + y1) / 2;
infX = min(infX, X); infX = Min(infX, X);
supX = max(supX, X); supX = Max(supX, X);
infY = min(infY, Y); infY = Min(infY, Y);
supY = max(supY, Y); supY = Max(supY, Y);
CVector center; CVector center;
center.x = (infX + supX) / 2; center.x = (infX + supX) / 2;
center.y = (infY + supY) / 2; center.y = (infY + supY) / 2;
@ -11626,17 +11621,3 @@ void CTheScripts::ReadMultiScriptFileOffsetsFromScript()
MultiScriptArray[i] = Read4BytesFromScript(&ip); MultiScriptArray[i] = Read4BytesFromScript(&ip);
} }
} }
STARTPATCHES
InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
InjectHook(0x44FD60, &CTheScripts::UndoEntityInvisibilitySettings, PATCH_JUMP);
InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);
InjectHook(0x453B30, &CTheScripts::LoadAllScripts, PATCH_JUMP);
InjectHook(0x454060, &CTheScripts::ClearSpaceForMissionEntity, PATCH_JUMP);
ENDPATCHES

View file

@ -240,46 +240,46 @@ enum {
class CTheScripts class CTheScripts
{ {
static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE]; static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS]; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS]; static int32 BaseBriefIdForContact[MAX_NUM_CONTACTS];
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS]; static int32 OnAMissionForContactFlag[MAX_NUM_CONTACTS];
static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES]; static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES]; static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES]; static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES]; static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES];
static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS]; static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS];
static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS]; static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS]; static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS]; static CEntity* InvisibilitySettingArray[MAX_NUM_INVISIBILITY_SETTINGS];
static CStoredLine(&aStoredLines)[MAX_NUM_STORED_LINES]; static CStoredLine aStoredLines[MAX_NUM_STORED_LINES];
static bool &DbgFlag; static bool DbgFlag;
static uint32 &OnAMissionFlag; static uint32 OnAMissionFlag;
static CMissionCleanup &MissionCleanup; static CMissionCleanup MissionCleanup;
static CStuckCarCheck &StuckCars; static CStuckCarCheck StuckCars;
static CUpsideDownCarCheck &UpsideDownCars; static CUpsideDownCarCheck UpsideDownCars;
static int32 &StoreVehicleIndex; static int32 StoreVehicleIndex;
static bool &StoreVehicleWasRandom; static bool StoreVehicleWasRandom;
static CRunningScript *&pIdleScripts; static CRunningScript *pIdleScripts;
static CRunningScript *&pActiveScripts; static CRunningScript *pActiveScripts;
static uint32 &NextFreeCollectiveIndex; static uint32 NextFreeCollectiveIndex;
static int32 &LastRandomPedId; static int32 LastRandomPedId;
static uint16 &NumberOfUsedObjects; static uint16 NumberOfUsedObjects;
static bool &bAlreadyRunningAMissionScript; static bool bAlreadyRunningAMissionScript;
static bool &bUsingAMultiScriptFile; static bool bUsingAMultiScriptFile;
static uint16 &NumberOfMissionScripts; static uint16 NumberOfMissionScripts;
static uint32 &LargestMissionScriptSize; static uint32 LargestMissionScriptSize;
static uint32 &MainScriptSize; static uint32 MainScriptSize;
static uint8 &FailCurrentMission; static uint8 FailCurrentMission;
static uint8 &CountdownToMakePlayerUnsafe; static uint8 CountdownToMakePlayerUnsafe;
static uint8 &DelayMakingPlayerUnsafeThisTime; static uint8 DelayMakingPlayerUnsafeThisTime;
static uint16 &NumScriptDebugLines; static uint16 NumScriptDebugLines;
static uint16 &NumberOfIntroRectanglesThisFrame; static uint16 NumberOfIntroRectanglesThisFrame;
static uint16 &NumberOfIntroTextLinesThisFrame; static uint16 NumberOfIntroTextLinesThisFrame;
static uint8 &UseTextCommands; static uint8 UseTextCommands;
static uint16 &CommandsExecuted; static uint16 CommandsExecuted;
static uint16 &ScriptsUpdated; static uint16 ScriptsUpdated;
public: public:
static void Init(); static void Init();

View file

@ -1,19 +1,19 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "General.h"
#include "Camera.h" #include "Camera.h"
#include "World.h"
#include "PathFind.h"
#include "Timer.h"
#include "Clock.h" #include "Clock.h"
#include "Weather.h"
#include "Timecycle.h"
#include "Pointlights.h"
#include "Shadows.h"
#include "Coronas.h" #include "Coronas.h"
#include "General.h"
#include "PathFind.h"
#include "PointLights.h"
#include "Shadows.h"
#include "SpecialFX.h" #include "SpecialFX.h"
#include "Vehicle.h" #include "Timecycle.h"
#include "Timer.h"
#include "TrafficLights.h" #include "TrafficLights.h"
#include "Vehicle.h"
#include "Weather.h"
#include "World.h"
// TODO: figure out the meaning of this // TODO: figure out the meaning of this
enum { SOME_FLAG = 0x80 }; enum { SOME_FLAG = 0x80 };
@ -39,10 +39,10 @@ CTrafficLights::DisplayActualLight(CEntity *ent)
float zMax = mi->Get2dEffect(0)->pos.z; float zMax = mi->Get2dEffect(0)->pos.z;
for(i = 1; i < 6; i++){ for(i = 1; i < 6; i++){
assert(mi->Get2dEffect(i)); assert(mi->Get2dEffect(i));
yMin = min(yMin, mi->Get2dEffect(i)->pos.y); yMin = Min(yMin, mi->Get2dEffect(i)->pos.y);
yMax = max(yMax, mi->Get2dEffect(i)->pos.y); yMax = Max(yMax, mi->Get2dEffect(i)->pos.y);
zMin = min(zMin, mi->Get2dEffect(i)->pos.z); zMin = Min(zMin, mi->Get2dEffect(i)->pos.z);
zMax = max(zMax, mi->Get2dEffect(i)->pos.z); zMax = Max(zMax, mi->Get2dEffect(i)->pos.z);
} }
CVector pos1, pos2; CVector pos1, pos2;
@ -327,9 +327,3 @@ CTrafficLights::LightForCars2(void)
else else
return CAR_LIGHTS_RED; return CAR_LIGHTS_RED;
} }
STARTPATCHES
InjectHook(0x455760, &CTrafficLights::LightForCars1, PATCH_JUMP);
InjectHook(0x455790, &CTrafficLights::LightForCars2, PATCH_JUMP);
InjectHook(0x4557D0, &CTrafficLights::LightForPeds, PATCH_JUMP);
ENDPATCHES

View file

@ -1,12 +1,12 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Accident.h" #include "Accident.h"
#include "Ped.h" #include "Ped.h"
#include "Pools.h" #include "Pools.h"
#include "World.h" #include "World.h"
CAccidentManager& gAccidentManager = *(CAccidentManager*)0x87FD10; CAccidentManager gAccidentManager;
CAccident* CAccident*
CAccidentManager::GetNextFreeAccident() CAccidentManager::GetNextFreeAccident()
@ -122,13 +122,3 @@ CAccidentManager::UnattendedAccidents()
} }
return false; return false;
} }
STARTPATCHES
InjectHook(0x4565A0, &CAccidentManager::GetNextFreeAccident, PATCH_JUMP);
InjectHook(0x4565D0, &CAccidentManager::ReportAccident, PATCH_JUMP);
InjectHook(0x456710, &CAccidentManager::Update, PATCH_JUMP);
InjectHook(0x456760, &CAccidentManager::FindNearestAccident, PATCH_JUMP);
InjectHook(0x456880, &CAccidentManager::CountActiveAccidents, PATCH_JUMP);
InjectHook(0x4568A0, &CAccidentManager::WorkToDoForMedics, PATCH_JUMP);
InjectHook(0x4568D0, &CAccidentManager::UnattendedAccidents, PATCH_JUMP);
ENDPATCHES

View file

@ -29,4 +29,4 @@ public:
bool WorkToDoForMedics(); bool WorkToDoForMedics();
}; };
extern CAccidentManager& gAccidentManager; extern CAccidentManager gAccidentManager;

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Font.h" #include "Font.h"
#include "Pad.h" #include "Pad.h"
#include "Text.h" #include "Text.h"
@ -37,6 +37,7 @@
#include "Shadows.h" #include "Shadows.h"
#include "Radar.h" #include "Radar.h"
#include "Hud.h" #include "Hud.h"
#include "debugmenu.h"
int CAnimViewer::animTxdSlot = 0; int CAnimViewer::animTxdSlot = 0;
CEntity *CAnimViewer::pTarget = nil; CEntity *CAnimViewer::pTarget = nil;
@ -208,7 +209,6 @@ PlayAnimation(RpClump *clump, AssocGroupId animGroup, AnimationId anim)
animAssoc->SetRun(); animAssoc->SetRun();
} }
extern void (*DebugMenuProcess)(void);
void void
CAnimViewer::Update(void) CAnimViewer::Update(void)
{ {
@ -367,7 +367,12 @@ CAnimViewer::Update(void)
} else { } else {
// Originally it was GetPad(1)->LeftShoulder2 // Originally it was GetPad(1)->LeftShoulder2
if (pad->NewState.Triangle) { if (pad->NewState.Triangle) {
CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump())); #ifdef PED_SKIN
if(IsClumpSkinned(pTarget->GetClump()))
((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->AnimatePedColModelSkinned(pTarget->GetClump());
else
#endif
CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump()));
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString); AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
CMessages::AddMessage(gUString, 100, 0); CMessages::AddMessage(gUString, 100, 0);
} }

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "main.h" #include "main.h"
#include "Draw.h" #include "Draw.h"
#include "World.h" #include "World.h"
@ -28,7 +28,7 @@
const float DefaultFOV = 70.0f; // beta: 80.0f const float DefaultFOV = 70.0f; // beta: 80.0f
bool PrintDebugCode = false; bool PrintDebugCode = false;
int16 &DebugCamMode = *(int16*)0x95CCF2; int16 DebugCamMode;
#ifdef FREE_CAM #ifdef FREE_CAM
bool CCamera::bFreeCam = false; bool CCamera::bFreeCam = false;
@ -117,9 +117,9 @@ CCam::Process(void)
float FwdSpeedX = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().x * Fwd.x; float FwdSpeedX = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().x * Fwd.x;
float FwdSpeedY = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().y * Fwd.y; float FwdSpeedY = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().y * Fwd.y;
if(FwdSpeedX + FwdSpeedY > 0.0f) if(FwdSpeedX + FwdSpeedY > 0.0f)
TargetSpeedVar = min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/0.9f, 1.0f); TargetSpeedVar = Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/0.9f, 1.0f);
else else
TargetSpeedVar = -min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f); TargetSpeedVar = -Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f);
SpeedVar = 0.895f*SpeedVar + 0.105*TargetSpeedVar; SpeedVar = 0.895f*SpeedVar + 0.105*TargetSpeedVar;
}else{ }else{
CameraTarget = CamTargetEntity->GetPosition(); CameraTarget = CamTargetEntity->GetPosition();
@ -341,7 +341,7 @@ WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSp
else if(TargetSpeed > 0.0f && *CurrentSpeed > TargetSpeed) else if(TargetSpeed > 0.0f && *CurrentSpeed > TargetSpeed)
*CurrentSpeed = TargetSpeed; *CurrentSpeed = TargetSpeed;
*CurrentValue += *CurrentSpeed * min(10.0f, CTimer::GetTimeStep()); *CurrentValue += *CurrentSpeed * Min(10.0f, CTimer::GetTimeStep());
} }
void void
@ -467,7 +467,7 @@ CCam::ProcessSpecialHeightRoutines(void)
vehicle->IsVehicle()){ vehicle->IsVehicle()){
float height = vehicle->GetColModel()->boundingBox.GetSize().z; float height = vehicle->GetColModel()->boundingBox.GetSize().z;
if(FoundCar){ if(FoundCar){
HighestCar = max(HighestCar, height); HighestCar = Max(HighestCar, height);
}else{ }else{
FoundCar = true; FoundCar = true;
HighestCar = height; HighestCar = height;
@ -481,7 +481,7 @@ CCam::ProcessSpecialHeightRoutines(void)
vehicle->IsVehicle()){ vehicle->IsVehicle()){
float height = vehicle->GetColModel()->boundingBox.GetSize().z; float height = vehicle->GetColModel()->boundingBox.GetSize().z;
if(FoundCar){ if(FoundCar){
HighestCar = max(HighestCar, height); HighestCar = Max(HighestCar, height);
}else{ }else{
FoundCar = true; FoundCar = true;
HighestCar = height; HighestCar = height;
@ -1323,7 +1323,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
else if(ReqSpeed > 0.0f && BetaSpeed > ReqSpeed) else if(ReqSpeed > 0.0f && BetaSpeed > ReqSpeed)
BetaSpeed = ReqSpeed; BetaSpeed = ReqSpeed;
Beta += BetaSpeed * min(10.0f, CTimer::GetTimeStep()); Beta += BetaSpeed * Min(10.0f, CTimer::GetTimeStep());
*/ */
WellBufferMe(FixedTargetOrientation, &Beta, &BetaSpeed, MaxSpeed, Acceleration, true); WellBufferMe(FixedTargetOrientation, &Beta, &BetaSpeed, MaxSpeed, Acceleration, true);
@ -1398,7 +1398,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
// Process height offset to avoid peds and cars // Process height offset to avoid peds and cars
float TargetZOffSet = m_fRoadOffSet + m_fDimensionOfHighestNearCar; float TargetZOffSet = m_fRoadOffSet + m_fDimensionOfHighestNearCar;
TargetZOffSet = max(TargetZOffSet, m_fPedBetweenCameraHeightOffset); TargetZOffSet = Max(TargetZOffSet, m_fPedBetweenCameraHeightOffset);
float TargetHeight = CameraTarget.z + TargetZOffSet - Source.z; float TargetHeight = CameraTarget.z + TargetZOffSet - Source.z;
if(TargetHeight > m_fCamBufferedHeight){ if(TargetHeight > m_fCamBufferedHeight){
@ -1454,7 +1454,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
} }
} }
TargetCoors.z += min(1.0f, m_fCamBufferedHeight/2.0f); TargetCoors.z += Min(1.0f, m_fCamBufferedHeight/2.0f);
m_cvecTargetCoorsForFudgeInter = TargetCoors; m_cvecTargetCoorsForFudgeInter = TargetCoors;
Front = TargetCoors - Source; Front = TargetCoors - Source;
@ -1553,7 +1553,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
#else #else
if(Alpha > fBaseDist) // comparing an angle against a distance? if(Alpha > fBaseDist) // comparing an angle against a distance?
#endif #endif
CamDist = fBaseDist + Cos(min(Alpha*fFalloff, HALFPI))*fAngleDist; CamDist = fBaseDist + Cos(Min(Alpha*fFalloff, HALFPI))*fAngleDist;
else else
CamDist = fBaseDist + Cos(Alpha)*fAngleDist; CamDist = fBaseDist + Cos(Alpha)*fAngleDist;
@ -1585,14 +1585,14 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
PedColDist = (TargetCoors - colPoint.point).Magnitude(); PedColDist = (TargetCoors - colPoint.point).Magnitude();
Source = colPoint.point; Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f) if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f)); RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}else{ }else{
RwCameraSetNearClipPlane(Scene.camera, min(ColCamDist-0.35f, DEFAULT_NEAR)); RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR));
} }
}else{ }else{
Source = colPoint.point; Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f) if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f)); RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
} }
} }
CWorld::pIgnoreEntity = nil; CWorld::pIgnoreEntity = nil;
@ -1609,7 +1609,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
// Try to decrease near clip // Try to decrease near clip
dist = max(min(Near, dist), 0.1f); dist = Max(Min(Near, dist), 0.1f);
if(dist < Near) if(dist < Near)
RwCameraSetNearClipPlane(Scene.camera, dist); RwCameraSetNearClipPlane(Scene.camera, dist);
@ -1639,7 +1639,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
float PlayerDist = (Source - player->GetPosition()).Magnitude(); float PlayerDist = (Source - player->GetPosition()).Magnitude();
if(PlayerDist < 2.75f) if(PlayerDist < 2.75f)
Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f; Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f;
RwCameraSetNearClipPlane(Scene.camera, max(Near, 0.1f)); RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f));
} }
} }
@ -1881,7 +1881,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
} }
if(FoundCamRoof){ if(FoundCamRoof){
// Camera is under something // Camera is under something
float roof = FoundRoofCenter ? min(CamRoof, CarRoof) : CamRoof; float roof = FoundRoofCenter ? Min(CamRoof, CarRoof) : CamRoof;
// Same weirdness again? // Same weirdness again?
TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, roof - CamTargetZ - 1.5f); TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, roof - CamTargetZ - 1.5f);
CamClear = false; CamClear = false;
@ -2139,7 +2139,7 @@ void
CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist) CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist)
{ {
CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth; CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth;
CA_MIN_DISTANCE = min(BaseDist*0.6f, 3.5f); CA_MIN_DISTANCE = Min(BaseDist*0.6f, 3.5f);
CVector Dist = Source - TargetCoors; CVector Dist = Source - TargetCoors;
@ -2361,7 +2361,7 @@ CCam::Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, f
if(FindPlayerPed()->m_pPointGunAt){ if(FindPlayerPed()->m_pPointGunAt){
Dist = (FindPlayerPed()->m_pPointGunAt->GetPosition() - CameraTarget).Magnitude2D(); Dist = (FindPlayerPed()->m_pPointGunAt->GetPosition() - CameraTarget).Magnitude2D();
if(Dist > 6.0f) if(Dist > 6.0f)
HeightTarget = max(HeightTarget, Dist/22.0f*37.0f); HeightTarget = Max(HeightTarget, Dist/22.0f*37.0f);
} }
Source = TargetCoors + CVector(0.0f, -1.0f, 9.0f); Source = TargetCoors + CVector(0.0f, -1.0f, 9.0f);
@ -2776,17 +2776,20 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
if(CamTargetEntity->IsPed()){ if(CamTargetEntity->IsPed()){
// static bool FailedTestTwelveFramesAgo = false; // unused // static bool FailedTestTwelveFramesAgo = false; // unused
RwV3d HeadPos = vecHeadCamOffset; CVector HeadPos = vecHeadCamOffset;
CVector TargetCoors; CVector TargetCoors;
// needs fix for SKINNING ((CPed*)CamTargetEntity)->TransformToNode(HeadPos, PED_HEAD);
RwFrame *frm = ((CPed*)CamTargetEntity)->GetNodeFrame(PED_HEAD); // This is done on PC, but checking for the clump frame is not necessary apparently
/*
RwFrame *frm = ((CPed*)CamTargetEntity)->m_pFrames[PED_HEAD]->frame;
while(frm){ while(frm){
RwV3dTransformPoints(&HeadPos, &HeadPos, 1, RwFrameGetMatrix(frm)); RwV3dTransformPoints(&HeadPos, &HeadPos, 1, RwFrameGetMatrix(frm));
frm = RwFrameGetParent(frm); frm = RwFrameGetParent(frm);
if(frm == RpClumpGetFrame(CamTargetEntity->GetClump())) if(frm == RpClumpGetFrame(CamTargetEntity->GetClump()))
frm = nil; frm = nil;
} }
*/
if(ResetStatics){ if(ResetStatics){
Beta = TargetOrientation; Beta = TargetOrientation;
@ -2813,13 +2816,13 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
m_vecBufferedPlayerBodyOffset.z = m_vecBufferedPlayerBodyOffset.z =
TheCamera.m_fGaitSwayBuffer * m_vecBufferedPlayerBodyOffset.z + TheCamera.m_fGaitSwayBuffer * m_vecBufferedPlayerBodyOffset.z +
(1.0f-TheCamera.m_fGaitSwayBuffer) * HeadPos.z; (1.0f-TheCamera.m_fGaitSwayBuffer) * HeadPos.z;
HeadPos = RwV3d(CamTargetEntity->GetMatrix() * m_vecBufferedPlayerBodyOffset); HeadPos = (CamTargetEntity->GetMatrix() * m_vecBufferedPlayerBodyOffset);
}else{ }else{
float HeadDelta = (HeadPos - InitialHeadPos).Magnitude2D(); float HeadDelta = (HeadPos - InitialHeadPos).Magnitude2D();
CVector Fwd = CamTargetEntity->GetForward(); CVector Fwd = CamTargetEntity->GetForward();
Fwd.z = 0.0f; Fwd.z = 0.0f;
Fwd.Normalise(); Fwd.Normalise();
HeadPos = RwV3d(HeadDelta*1.23f*Fwd + CamTargetEntity->GetPosition()); HeadPos = (HeadDelta*1.23f*Fwd + CamTargetEntity->GetPosition());
HeadPos.z += 0.59f; HeadPos.z += 0.59f;
} }
Source = HeadPos; Source = HeadPos;
@ -3125,7 +3128,7 @@ CCam::Process_Syphon(const CVector &CameraTarget, float, float, float)
Front = TargetCoors - Source; Front = TargetCoors - Source;
m_fMinDistAwayFromCamWhenInterPolating = Front.Magnitude2D(); m_fMinDistAwayFromCamWhenInterPolating = Front.Magnitude2D();
if(m_fMinDistAwayFromCamWhenInterPolating < 1.1f) if(m_fMinDistAwayFromCamWhenInterPolating < 1.1f)
RwCameraSetNearClipPlane(Scene.camera, max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f)); RwCameraSetNearClipPlane(Scene.camera, Max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f));
Front.Normalise(); Front.Normalise();
GetVectorsReadyForRW(); GetVectorsReadyForRW();
} }
@ -3382,7 +3385,7 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl
WellBufferMe(TargetOrientation, &m_fBufferedTargetOrientation, &m_fBufferedTargetOrientationSpeed, 0.07f, 0.004f, true); WellBufferMe(TargetOrientation, &m_fBufferedTargetOrientation, &m_fBufferedTargetOrientationSpeed, 0.07f, 0.004f, true);
TargetCoors = CameraTarget + 0.5f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f); TargetCoors = CameraTarget + 0.5f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f);
TargetCamHeight = CameraTarget.z - Source.z + max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f; TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f;
if(TargetCamHeight > m_fCamBufferedHeight) if(TargetCamHeight > m_fCamBufferedHeight)
WellBufferMe(TargetCamHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.15f, 0.04f, false); WellBufferMe(TargetCamHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.15f, 0.04f, false);
else else
@ -4556,14 +4559,14 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
PedColDist = (TargetCoors - colPoint.point).Magnitude(); PedColDist = (TargetCoors - colPoint.point).Magnitude();
Source = colPoint.point; Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f) if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f)); RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}else{ }else{
RwCameraSetNearClipPlane(Scene.camera, min(ColCamDist-0.35f, DEFAULT_NEAR)); RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR));
} }
}else{ }else{
Source = colPoint.point; Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f) if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f)); RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
} }
} }
CWorld::pIgnoreEntity = nil; CWorld::pIgnoreEntity = nil;
@ -4580,7 +4583,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
// Try to decrease near clip // Try to decrease near clip
dist = max(min(Near, dist), 0.1f); dist = Max(Min(Near, dist), 0.1f);
if(dist < Near) if(dist < Near)
RwCameraSetNearClipPlane(Scene.camera, dist); RwCameraSetNearClipPlane(Scene.camera, dist);
@ -4714,7 +4717,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
minDistForVehType = minDistForVehType * 0.65f; minDistForVehType = minDistForVehType * 0.65f;
} }
float nextDistance = max(newDistance, minDistForVehType); float nextDistance = Max(newDistance, minDistForVehType);
CA_MAX_DISTANCE = newDistance; CA_MAX_DISTANCE = newDistance;
CA_MIN_DISTANCE = 3.5f; CA_MIN_DISTANCE = 3.5f;
@ -4811,7 +4814,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float betaChangeMult2 = (car->m_vecMoveSpeed - DotProduct(car->m_vecMoveSpeed, Front) * Front).Magnitude(); float betaChangeMult2 = (car->m_vecMoveSpeed - DotProduct(car->m_vecMoveSpeed, Front) * Front).Magnitude();
float betaChange = min(1.0f, betaChangeMult1 * betaChangeMult2) * (velocityRightHeading - camRightHeading); float betaChange = Min(1.0f, betaChangeMult1 * betaChangeMult2) * (velocityRightHeading - camRightHeading);
if (betaChange <= betaChangeLimit) { if (betaChange <= betaChangeLimit) {
if (betaChange < -betaChangeLimit) if (betaChange < -betaChangeLimit)
betaChange = -betaChangeLimit; betaChange = -betaChangeLimit;
@ -4827,7 +4830,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float carPosChange = (TargetCoors - m_aTargetHistoryPosTwo).Magnitude(); float carPosChange = (TargetCoors - m_aTargetHistoryPosTwo).Magnitude();
if (carPosChange < newDistance && newDistance > minDistForThisCar) { if (carPosChange < newDistance && newDistance > minDistForThisCar) {
newDistance = max(minDistForThisCar, carPosChange); newDistance = Max(minDistForThisCar, carPosChange);
} }
float maxAlphaAllowed = CARCAM_SET[camSetArrPos][13]; float maxAlphaAllowed = CARCAM_SET[camSetArrPos][13];
@ -4851,7 +4854,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
v200 = (1.5f - carCol->boundingBox.min.y) / Cos(v88); v200 = (1.5f - carCol->boundingBox.min.y) / Cos(v88);
} else { } else {
float a6g = 1.2f + carCol->boundingBox.max.x; float a6g = 1.2f + carCol->boundingBox.max.x;
v200 = a6g / Cos(max(0.0f, HALFPI - v88)); v200 = a6g / Cos(Max(0.0f, HALFPI - v88));
} }
maxAlphaAllowed = Cos(Beta - (car->GetForward().Heading() - HALFPI)) * Atan2(car->GetForward().z, car->GetForward().Magnitude2D()) maxAlphaAllowed = Cos(Beta - (car->GetForward().Heading() - HALFPI)) * Atan2(car->GetForward().z, car->GetForward().Magnitude2D())
+ Atan2(TargetCoors.z - car->GetPosition().z + car->GetHeightAboveRoad(), v200 * 1.2f); + Atan2(TargetCoors.z - car->GetPosition().z + car->GetHeightAboveRoad(), v200 * 1.2f);
@ -4944,7 +4947,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
yMovement = 0.0; yMovement = 0.0;
xMovement = 0.0; xMovement = 0.0;
targetAlpha = Alpha; targetAlpha = Alpha;
stepsLeftToChangeBetaByMouse = max(0.0f, stepsLeftToChangeBetaByMouse - CTimer::GetTimeStep()); stepsLeftToChangeBetaByMouse = Max(0.0f, stepsLeftToChangeBetaByMouse - CTimer::GetTimeStep());
mouseChangesBeta = true; mouseChangesBeta = true;
} }
} }
@ -4963,7 +4966,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9]; float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9];
float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / max(CTimer::GetTimeStep(), 1.0f); float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f);
if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount) if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount)
targetBetaWithStickBlendAmount = -newAngleSpeedMaxBlendAmount; targetBetaWithStickBlendAmount = -newAngleSpeedMaxBlendAmount;
@ -5088,7 +5091,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) {
Source = foundCol.point; Source = foundCol.point;
if (obstacleTargetDist < 1.2f) { if (obstacleTargetDist < 1.2f) {
RwCameraSetNearClipPlane(Scene.camera, max(0.05f, obstacleTargetDist - 0.3f)); RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f));
} }
} else { } else {
if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false)) { if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false)) {
@ -5236,55 +5239,3 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
} }
} }
#endif #endif
STARTPATCHES
InjectHook(0x456F40, WellBufferMe, PATCH_JUMP);
InjectHook(0x458410, &CCam::Init, PATCH_JUMP);
InjectHook(0x4582F0, &CCam::GetVectorsReadyForRW, PATCH_JUMP);
InjectHook(0x457710, &CCam::DoAverageOnVector, PATCH_JUMP);
InjectHook(0x458060, &CCam::GetPedBetaAngleForClearView, PATCH_JUMP);
InjectHook(0x457210, &CCam::Cam_On_A_String_Unobscured, PATCH_JUMP);
InjectHook(0x457A80, &CCam::FixCamWhenObscuredByVehicle, PATCH_JUMP);
InjectHook(0x457B90, &CCam::FixCamIfObscured, PATCH_JUMP);
InjectHook(0x465DA0, &CCam::RotCamIfInFrontCar, PATCH_JUMP);
InjectHook(0x4662D0, &CCam::WorkOutCamHeightWeeCar, PATCH_JUMP);
InjectHook(0x466650, &CCam::WorkOutCamHeight, PATCH_JUMP);
InjectHook(0x458600, &CCam::LookBehind, PATCH_JUMP);
InjectHook(0x458C40, &CCam::LookLeft, PATCH_JUMP);
InjectHook(0x458FB0, &CCam::LookRight, PATCH_JUMP);
InjectHook(0x4574C0, &CCam::ClipIfPedInFrontOfPlayer, PATCH_JUMP);
InjectHook(0x459300, &CCam::KeepTrackOfTheSpeed, PATCH_JUMP);
InjectHook(0x458580, &CCam::IsTargetInWater, PATCH_JUMP);
InjectHook(0x4570C0, &CCam::AvoidWallsTopDownPed, PATCH_JUMP);
InjectHook(0x4595B0, &CCam::PrintMode, PATCH_JUMP);
InjectHook(0x467400, &CCam::ProcessSpecialHeightRoutines, PATCH_JUMP);
InjectHook(0x4596A0, &CCam::Process, PATCH_JUMP);
InjectHook(0x45E3A0, &CCam::Process_FollowPed, PATCH_JUMP);
InjectHook(0x45FF70, &CCam::Process_FollowPedWithMouse, PATCH_JUMP);
InjectHook(0x45BE60, &CCam::Process_BehindCar, PATCH_JUMP);
InjectHook(0x45C090, &CCam::Process_Cam_On_A_String, PATCH_JUMP);
InjectHook(0x463EB0, &CCam::Process_TopDown, PATCH_JUMP);
InjectHook(0x464390, &CCam::Process_TopDownPed, PATCH_JUMP);
InjectHook(0x461AF0, &CCam::Process_Rocket, PATCH_JUMP);
InjectHook(0x460E00, &CCam::Process_M16_1stPerson, PATCH_JUMP);
InjectHook(0x459FA0, &CCam::Process_1stPerson, PATCH_JUMP);
InjectHook(0x462420, &CCam::Process_Sniper, PATCH_JUMP);
InjectHook(0x463130, &CCam::Process_Syphon, PATCH_JUMP);
InjectHook(0x463A70, &CCam::Process_Syphon_Crim_In_Front, PATCH_JUMP);
InjectHook(0x45B470, &CCam::Process_BehindBoat, PATCH_JUMP);
InjectHook(0x45D2F0, &CCam::Process_Fight_Cam, PATCH_JUMP);
InjectHook(0x45DC20, &CCam::Process_FlyBy, PATCH_JUMP);
InjectHook(0x464D10, &CCam::Process_WheelCam, PATCH_JUMP);
InjectHook(0x45DA20, &CCam::Process_Fixed, PATCH_JUMP);
InjectHook(0x461940, &CCam::Process_Player_Fallen_Water, PATCH_JUMP);
InjectHook(0x45C400, &CCam::Process_Circle, PATCH_JUMP);
InjectHook(0x462FC0, &CCam::Process_SpecialFixedForSyphon, PATCH_JUMP);
InjectHook(0x45CCC0, &CCam::Process_Debug, PATCH_JUMP);
InjectHook(0x4656C0, &CCam::ProcessPedsDeadBaby, PATCH_JUMP);
InjectHook(0x465000, &CCam::ProcessArrestCamOne, PATCH_JUMP);
InjectHook(0x4653C0, &CCam::ProcessArrestCamTwo, PATCH_JUMP);
InjectHook(0x456CE0, &FindSplinePathPositionFloat, PATCH_JUMP);
InjectHook(0x4569A0, &FindSplinePathPositionVector, PATCH_JUMP);
ENDPATCHES

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "main.h" #include "main.h"
#include "Draw.h" #include "Draw.h"
#include "World.h" #include "World.h"
@ -29,6 +29,7 @@
#include "SceneEdit.h" #include "SceneEdit.h"
#include "Pools.h" #include "Pools.h"
#include "Debug.h" #include "Debug.h"
#include "GenericGameStorage.h"
#include "Camera.h" #include "Camera.h"
enum enum
@ -57,9 +58,9 @@ enum
#define PLAYER (CWorld::Players[CWorld::PlayerInFocus].m_pPed) #define PLAYER (CWorld::Players[CWorld::PlayerInFocus].m_pPed)
// NB: removed explicit TheCamera from all functions // NB: removed explicit TheCamera from all functions
CCamera &TheCamera = *(CCamera*)0x6FACF8; CCamera TheCamera;
bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8; bool CCamera::m_bUseMouse3rdPerson = true;
bool &bDidWeProcessAnyCinemaCam = *(bool*)0x95CD46; bool bDidWeProcessAnyCinemaCam;
#ifdef IMPROVED_CAMERA #ifdef IMPROVED_CAMERA
#define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k)
@ -466,7 +467,7 @@ CCamera::Process(void)
GetPosition().z += shakeOffset*(((shakeRand&0xF00)>>8)-7); GetPosition().z += shakeOffset*(((shakeRand&0xF00)>>8)-7);
if(shakeOffset > 0.0f && m_BlurType != MBLUR_SNIPER) if(shakeOffset > 0.0f && m_BlurType != MBLUR_SNIPER)
SetMotionBlurAlpha(min((int)(shakeStrength*255.0f) + 25, 150)); SetMotionBlurAlpha(Min((int)(shakeStrength*255.0f) + 25, 150));
if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON && FindPlayerVehicle() && FindPlayerVehicle()->GetUp().z < 0.2f) if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON && FindPlayerVehicle() && FindPlayerVehicle()->GetUp().z < 0.2f)
SetMotionBlur(230, 230, 230, 215, MBLUR_NORMAL); SetMotionBlur(230, 230, 230, 215, MBLUR_NORMAL);
@ -488,19 +489,19 @@ CCamera::Process(void)
CDraw::SetFOV(Cams[2].FOV); CDraw::SetFOV(Cams[2].FOV);
m_vecGameCamPos = Cams[ActiveCam].Source; m_vecGameCamPos = Cams[ActiveCam].Source;
*RwMatrixGetPos(RwFrameGetMatrix(frame)) = (RwV3d)GetPosition(); *RwMatrixGetPos(RwFrameGetMatrix(frame)) = GetPosition().toRwV3d();
*RwMatrixGetAt(RwFrameGetMatrix(frame)) = (RwV3d)GetForward(); *RwMatrixGetAt(RwFrameGetMatrix(frame)) = GetForward().toRwV3d();
*RwMatrixGetUp(RwFrameGetMatrix(frame)) = (RwV3d)GetUp(); *RwMatrixGetUp(RwFrameGetMatrix(frame)) = GetUp().toRwV3d();
*RwMatrixGetRight(RwFrameGetMatrix(frame)) = (RwV3d)GetRight(); *RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight().toRwV3d();
RwMatrixUpdate(RwFrameGetMatrix(frame)); RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame); RwFrameUpdateObjects(frame);
}else{ }else{
RwFrame *frame = RwCameraGetFrame(m_pRwCamera); RwFrame *frame = RwCameraGetFrame(m_pRwCamera);
m_vecGameCamPos = GetPosition(); m_vecGameCamPos = GetPosition();
*RwMatrixGetPos(RwFrameGetMatrix(frame)) = (RwV3d)GetPosition(); *RwMatrixGetPos(RwFrameGetMatrix(frame)) = GetPosition().toRwV3d();
*RwMatrixGetAt(RwFrameGetMatrix(frame)) = (RwV3d)GetForward(); *RwMatrixGetAt(RwFrameGetMatrix(frame)) = GetForward().toRwV3d();
*RwMatrixGetUp(RwFrameGetMatrix(frame)) = (RwV3d)GetUp(); *RwMatrixGetUp(RwFrameGetMatrix(frame)) = GetUp().toRwV3d();
*RwMatrixGetRight(RwFrameGetMatrix(frame)) = (RwV3d)GetRight(); *RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight().toRwV3d();
RwMatrixUpdate(RwFrameGetMatrix(frame)); RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame); RwFrameUpdateObjects(frame);
} }
@ -767,27 +768,27 @@ CCamera::CamControl(void)
if(m_bUseScriptZoomValueCar){ if(m_bUseScriptZoomValueCar){
if(CarZoomValueSmooth < m_fCarZoomValueScript){ if(CarZoomValueSmooth < m_fCarZoomValueScript){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = min(CarZoomValueSmooth, m_fCarZoomValueScript); CarZoomValueSmooth = Min(CarZoomValueSmooth, m_fCarZoomValueScript);
}else{ }else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = max(CarZoomValueSmooth, m_fCarZoomValueScript); CarZoomValueSmooth = Max(CarZoomValueSmooth, m_fCarZoomValueScript);
} }
}else if(m_bFailedCullZoneTestPreviously){ }else if(m_bFailedCullZoneTestPreviously){
CloseInCarHeightTarget = 0.65f; CloseInCarHeightTarget = 0.65f;
if(CarZoomValueSmooth < -0.65f){ if(CarZoomValueSmooth < -0.65f){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = min(CarZoomValueSmooth, -0.65f); CarZoomValueSmooth = Min(CarZoomValueSmooth, -0.65f);
}else{ }else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = max(CarZoomValueSmooth, -0.65f); CarZoomValueSmooth = Max(CarZoomValueSmooth, -0.65f);
} }
}else{ }else{
if(CarZoomValueSmooth < CarZoomValue){ if(CarZoomValueSmooth < CarZoomValue){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = min(CarZoomValueSmooth, CarZoomValue); CarZoomValueSmooth = Min(CarZoomValueSmooth, CarZoomValue);
}else{ }else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
CarZoomValueSmooth = max(CarZoomValueSmooth, CarZoomValue); CarZoomValueSmooth = Max(CarZoomValueSmooth, CarZoomValue);
} }
} }
@ -871,28 +872,28 @@ CCamera::CamControl(void)
if(m_bUseScriptZoomValuePed){ if(m_bUseScriptZoomValuePed){
if(m_fPedZoomValueSmooth < m_fPedZoomValueScript){ if(m_fPedZoomValueSmooth < m_fPedZoomValueScript){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, m_fPedZoomValueScript); m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
}else{ }else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, m_fPedZoomValueScript); m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
} }
}else if(m_bFailedCullZoneTestPreviously){ }else if(m_bFailedCullZoneTestPreviously){
static float PedZoomedInVal = 0.5f; static float PedZoomedInVal = 0.5f;
CloseInPedHeightTarget = 0.7f; CloseInPedHeightTarget = 0.7f;
if(m_fPedZoomValueSmooth < PedZoomedInVal){ if(m_fPedZoomValueSmooth < PedZoomedInVal){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, PedZoomedInVal); m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, PedZoomedInVal);
}else{ }else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, PedZoomedInVal); m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, PedZoomedInVal);
} }
}else{ }else{
if(m_fPedZoomValueSmooth < m_fPedZoomValue){ if(m_fPedZoomValueSmooth < m_fPedZoomValue){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, m_fPedZoomValue); m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, m_fPedZoomValue);
}else{ }else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep(); m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, m_fPedZoomValue); m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, m_fPedZoomValue);
} }
} }
@ -2183,13 +2184,21 @@ CCamera::DrawBordersForWideScreen(void)
SetMotionBlurAlpha(80); SetMotionBlurAlpha(80);
CSprite2d::DrawRect( CSprite2d::DrawRect(
#ifdef FIX_BUGS
CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f),
#else
CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f, CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f,
#endif
SCREEN_WIDTH, 0.0f), SCREEN_WIDTH, 0.0f),
CRGBA(0, 0, 0, 255)); CRGBA(0, 0, 0, 255));
CSprite2d::DrawRect( CSprite2d::DrawRect(
CRect(0.0f, SCREEN_HEIGHT, CRect(0.0f, SCREEN_HEIGHT,
#ifdef FIX_BUGS
SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f)),
#else
SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f), SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f),
#endif
CRGBA(0, 0, 0, 255)); CRGBA(0, 0, 0, 255));
} }
@ -2247,7 +2256,7 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
if(fwd.Magnitude() < 2.0f) if(fwd.Magnitude() < 2.0f)
// very close, fix near clip // very close, fix near clip
SetNearClipScript(max(fwd.Magnitude()*0.5f, 0.05f)); SetNearClipScript(Max(fwd.Magnitude()*0.5f, 0.05f));
// too far and driving away from cam // too far and driving away from cam
if(fwd.Magnitude() > 19.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f) if(fwd.Magnitude() > 19.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true; return true;
@ -2481,6 +2490,10 @@ CCamera::TryToStartNewCamMode(int obbeMode)
TakeControl(FindPlayerEntity(), CCam::MODE_CAM_ON_A_STRING, JUMP_CUT, CAMCONTROL_OBBE); TakeControl(FindPlayerEntity(), CCam::MODE_CAM_ON_A_STRING, JUMP_CUT, CAMCONTROL_OBBE);
return true; return true;
case OBBE_COPCAR: case OBBE_COPCAR:
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return false;
#endif
if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1)
return false; return false;
if(FindPlayerVehicle() == nil) if(FindPlayerVehicle() == nil)
@ -2505,6 +2518,10 @@ CCamera::TryToStartNewCamMode(int obbeMode)
} }
return false; return false;
case OBBE_COPCAR_WHEEL: case OBBE_COPCAR_WHEEL:
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return false;
#endif
if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1)
return false; return false;
if(FindPlayerVehicle() == nil) if(FindPlayerVehicle() == nil)
@ -3377,58 +3394,3 @@ CCamPathSplines::CCamPathSplines(void)
for(i = 0; i < MAXPATHLENGTH; i++) for(i = 0; i < MAXPATHLENGTH; i++)
m_arr_PathData[i] = 0.0f; m_arr_PathData[i] = 0.0f;
} }
STARTPATCHES
InjectHook(0x42C760, (bool (CCamera::*)(const CVector &center, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
InjectHook(0x46FD40, &CCamera::SetMotionBlur, PATCH_JUMP);
InjectHook(0x46FD80, &CCamera::SetMotionBlurAlpha, PATCH_JUMP);
InjectHook(0x46F940, &CCamera::RenderMotionBlur, PATCH_JUMP);
InjectHook(0x46FC90, &CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString, PATCH_JUMP);
InjectHook(0x46FF00, &CCamera::SetWideScreenOn, PATCH_JUMP);
InjectHook(0x46FF10, &CCamera::SetWideScreenOff, PATCH_JUMP);
InjectHook(0x46FCC0, &CCamera::SetCamPositionForFixedMode, PATCH_JUMP);
InjectHook(0x46FEC0, &CCamera::SetRwCamera, PATCH_JUMP);
InjectHook(0x46B920, &CCamera::GetCutSceneFinishTime, PATCH_JUMP);
InjectHook(0x46B560, &CCamera::FinishCutscene, PATCH_JUMP);
InjectHook(0x46FF30, &CCamera::SetZoomValueFollowPedScript, PATCH_JUMP);
InjectHook(0x46FF90, &CCamera::SetZoomValueCamStringScript, PATCH_JUMP);
InjectHook(0x46F8E0, &CCamera::ProcessWideScreenOn, PATCH_JUMP);
InjectHook(0x46FDE0, &CCamera::SetParametersForScriptInterpolation, PATCH_JUMP);
InjectHook(0x46BA20, &CCamera::GetLookingLRBFirstPerson, PATCH_JUMP);
InjectHook(0x470D80, &CCamera::StartTransitionWhenNotFinishedInter, PATCH_JUMP);
InjectHook(0x46FFF0, &CCamera::StartTransition, PATCH_JUMP);
InjectHook(0x46BEB0, &CCamera::InitialiseCameraForDebugMode, PATCH_JUMP);
InjectHook(0x471500, &CCamera::TakeControl, PATCH_JUMP);
InjectHook(0x4715B0, &CCamera::TakeControlNoEntity, PATCH_JUMP);
InjectHook(0x46B3A0, &CCamera::Fade, PATCH_JUMP);
InjectHook(0x46FE20, &CCamera::SetPercentAlongCutScene, PATCH_JUMP);
InjectHook(0x46B100, &CamShakeNoPos, PATCH_JUMP);
InjectHook(0x46B200, &CCamera::CamShake, PATCH_JUMP);
InjectHook(0x46F520, &CCamera::ProcessObbeCinemaCameraPed, PATCH_JUMP);
InjectHook(0x46F3E0, &CCamera::ProcessObbeCinemaCameraCar, PATCH_JUMP);
InjectHook(0x470DA0, &CCamera::StoreValuesDuringInterPol, PATCH_JUMP);
InjectHook(0x46B430, &CCamera::DrawBordersForWideScreen, PATCH_JUMP);
InjectHook(0x46F990, &CCamera::Restore, PATCH_JUMP);
InjectHook(0x46FAE0, &CCamera::RestoreWithJumpCut, PATCH_JUMP);
InjectHook(0x46F080, &CCamera::ProcessFade, PATCH_JUMP);
InjectHook(0x46EEA0, &CCamera::CalculateDerivedValues, PATCH_JUMP);
InjectHook(0x46F1E0, &CCamera::ProcessMusicFade, PATCH_JUMP);
InjectHook(0x46D1D0, &CCamera::LoadPathSplines, PATCH_JUMP);
InjectHook(0x4712A0, &CCamera::UpdateTargetEntity, PATCH_JUMP);
InjectHook(0x46B580, &CCamera::Find3rdPersonCamTargetVector, PATCH_JUMP);
InjectHook(0x46BAD0, &CCamera::Init, PATCH_JUMP);
InjectHook(0x46C9E0, &CCamera::LoadTrainCamNodes, PATCH_JUMP);
InjectHook(0x46F600, &CCamera::Process_Train_Camera_Control, PATCH_JUMP);
InjectHook(0x470EA0, &CCamera::UpdateSoundDistances, PATCH_JUMP);
InjectHook(0x46BF10, &CCamera::IsItTimeForNewcam, PATCH_JUMP);
InjectHook(0x471650, &CCamera::TryToStartNewCamMode, PATCH_JUMP);
// InjectHook(0x46D3F0, &CCamera::Process, PATCH_JUMP);
ENDPATCHES

View file

@ -6,7 +6,7 @@ class CPed;
class CAutomobile; class CAutomobile;
class CGarage; class CGarage;
extern int16 &DebugCamMode; extern int16 DebugCamMode;
enum enum
{ {
@ -415,7 +415,7 @@ uint32 unknown; // some counter having to do with music
float CamFrontXNorm; float CamFrontXNorm;
float CamFrontYNorm; float CamFrontYNorm;
#if 0 // TODO: FIX_BUGS once GenericLoad is done #ifdef FIX_BUGS
int32 CarZoomIndicator; int32 CarZoomIndicator;
#else #else
float CarZoomIndicator; float CarZoomIndicator;
@ -455,7 +455,7 @@ uint32 unknown; // some counter having to do with music
float m_ScreenReductionSpeed; float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson; float m_AlphaForPlayerAnim1rstPerson;
float Orientation; float Orientation;
#if 0 // TODO: FIX_BUGS once GenericLoad is done #ifdef FIX_BUGS
int32 PedZoomIndicator; int32 PedZoomIndicator;
#else #else
float PedZoomIndicator; float PedZoomIndicator;
@ -540,7 +540,7 @@ uint32 unknown; // some counter having to do with music
uint32 m_uiFadeTimeStarted; uint32 m_uiFadeTimeStarted;
uint32 m_uiFadeTimeStartedMusic; uint32 m_uiFadeTimeStartedMusic;
static bool &m_bUseMouse3rdPerson; static bool m_bUseMouse3rdPerson;
#ifdef FREE_CAM #ifdef FREE_CAM
static bool bFreeCam; static bool bFreeCam;
#endif #endif
@ -647,7 +647,7 @@ static_assert(offsetof(CCamera, m_vecCutSceneOffset) == 0x6F8, "CCamera: error")
static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error"); static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error");
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size"); static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
extern CCamera &TheCamera; extern CCamera TheCamera;
void CamShakeNoPos(CCamera*, float); void CamShakeNoPos(CCamera*, float);
void MakeAngleLessThan180(float &Angle); void MakeAngleLessThan180(float &Angle);

View file

@ -1,6 +1,6 @@
#include <windows.h> #define WITHWINDOWS
#include "common.h" #include "common.h"
#include "patcher.h"
#include "CdStream.h" #include "CdStream.h"
#include "rwcore.h" #include "rwcore.h"
#include "RwHelper.h" #include "RwHelper.h"
@ -507,24 +507,3 @@ CdStreamGetNumImages(void)
{ {
return gNumImages; return gNumImages;
} }
STARTPATCHES
InjectHook(0x405B50, CdStreamInitThread, PATCH_JUMP);
InjectHook(0x405C80, CdStreamInit, PATCH_JUMP);
//InjectHook(0x405DB0, debug, PATCH_JUMP);
InjectHook(0x405DC0, GetGTA3ImgSize, PATCH_JUMP);
InjectHook(0x405DD0, CdStreamShutdown, PATCH_JUMP);
InjectHook(0x405E40, CdStreamRead, PATCH_JUMP);
InjectHook(0x405F90, CdStreamGetStatus, PATCH_JUMP);
InjectHook(0x406000, CdStreamGetLastPosn, PATCH_JUMP);
InjectHook(0x406010, CdStreamSync, PATCH_JUMP);
InjectHook(0x4060B0, AddToQueue, PATCH_JUMP);
InjectHook(0x4060F0, GetFirstInQueue, PATCH_JUMP);
InjectHook(0x406110, RemoveFirstInQueue, PATCH_JUMP);
InjectHook(0x406140, CdStreamThread, PATCH_JUMP);
InjectHook(0x406270, CdStreamAddImage, PATCH_JUMP);
InjectHook(0x4062E0, CdStreamGetImageName, PATCH_JUMP);
InjectHook(0x406300, CdStreamRemoveImages, PATCH_JUMP);
InjectHook(0x406370, CdStreamGetNumImages, PATCH_JUMP);
ENDPATCHES

View file

@ -1,22 +1,22 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "Timer.h" #include "Timer.h"
#include "Pad.h" #include "Pad.h"
#include "Clock.h" #include "Clock.h"
#include "Stats.h" #include "Stats.h"
_TODO("gbFastTime"); _TODO("gbFastTime");
bool &gbFastTime = *(bool*)0x95CDBB; bool gbFastTime;
uint8 &CClock::ms_nGameClockHours = *(uint8*)0x95CDA6; uint8 CClock::ms_nGameClockHours;
uint8 &CClock::ms_nGameClockMinutes = *(uint8*)0x95CDC8; uint8 CClock::ms_nGameClockMinutes;
uint16 &CClock::ms_nGameClockSeconds = *(uint16*)0x95CC7C; uint16 CClock::ms_nGameClockSeconds;
uint8 &CClock::ms_Stored_nGameClockHours = *(uint8*)0x95CD7B; uint8 CClock::ms_Stored_nGameClockHours;
uint8 &CClock::ms_Stored_nGameClockMinutes = *(uint8*)0x95CD9B; uint8 CClock::ms_Stored_nGameClockMinutes;
uint16 &CClock::ms_Stored_nGameClockSeconds = *(uint16*)0x95CC9C; uint16 CClock::ms_Stored_nGameClockSeconds;
uint32 &CClock::ms_nMillisecondsPerGameMinute = *(uint32*)0x8F2C64; uint32 CClock::ms_nMillisecondsPerGameMinute;
uint32 &CClock::ms_nLastClockTick = *(uint32*)0x9430E4; uint32 CClock::ms_nLastClockTick;
bool &CClock::ms_bClockHasBeenStored = *(bool*)0x95CD82; bool CClock::ms_bClockHasBeenStored;
void void
CClock::Initialise(uint32 scale) CClock::Initialise(uint32 scale)
@ -115,14 +115,3 @@ CClock::RestoreClock(void)
ms_nGameClockMinutes = ms_Stored_nGameClockMinutes; ms_nGameClockMinutes = ms_Stored_nGameClockMinutes;
ms_nGameClockSeconds = ms_Stored_nGameClockSeconds; ms_nGameClockSeconds = ms_Stored_nGameClockSeconds;
} }
STARTPATCHES
InjectHook(0x473370, CClock::Initialise, PATCH_JUMP);
InjectHook(0x473460, CClock::Update, PATCH_JUMP);
InjectHook(0x4733C0, CClock::SetGameClock, PATCH_JUMP);
InjectHook(0x4733F0, CClock::GetGameClockMinutesUntil, PATCH_JUMP);
InjectHook(0x473420, CClock::GetIsTimeInRange, PATCH_JUMP);
InjectHook(0x473540, CClock::StoreClock, PATCH_JUMP);
InjectHook(0x473570, CClock::RestoreClock, PATCH_JUMP);
ENDPATCHES

View file

@ -3,15 +3,15 @@
class CClock class CClock
{ {
public: public:
static uint8 &ms_nGameClockHours; static uint8 ms_nGameClockHours;
static uint8 &ms_nGameClockMinutes; static uint8 ms_nGameClockMinutes;
static uint16 &ms_nGameClockSeconds; static uint16 ms_nGameClockSeconds;
static uint8 &ms_Stored_nGameClockHours; static uint8 ms_Stored_nGameClockHours;
static uint8 &ms_Stored_nGameClockMinutes; static uint8 ms_Stored_nGameClockMinutes;
static uint16 &ms_Stored_nGameClockSeconds; static uint16 ms_Stored_nGameClockSeconds;
static uint32 &ms_nMillisecondsPerGameMinute; static uint32 ms_nMillisecondsPerGameMinute;
static uint32 &ms_nLastClockTick; static uint32 ms_nLastClockTick;
static bool &ms_bClockHasBeenStored; static bool ms_bClockHasBeenStored;
static void Initialise(uint32 scale); static void Initialise(uint32 scale);
static void Update(void); static void Update(void);

View file

@ -1,5 +1,5 @@
#include "common.h" #include "common.h"
#include "patcher.h"
#include "main.h" #include "main.h"
#include "Lists.h" #include "Lists.h"
#include "Game.h" #include "Game.h"
@ -31,8 +31,8 @@ enum Direction
DIR_Z_NEG, DIR_Z_NEG,
}; };
eLevelName &CCollision::ms_collisionInMemory = *(eLevelName*)0x8F6250; eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> &CCollision::ms_colModelCache = *(CLinkList<CColModel*>*)0x95CB58; CLinkList<CColModel*> CCollision::ms_colModelCache;
void void
CCollision::Init(void) CCollision::Init(void)
@ -153,10 +153,10 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange)
// on water we expect to be between levels // on water we expect to be between levels
multipleLevels = true; multipleLevels = true;
}else{ }else{
xmin = max(sx - 1, 0); xmin = Max(sx - 1, 0);
xmax = min(sx + 1, NUMSECTORS_X-1); xmax = Min(sx + 1, NUMSECTORS_X-1);
ymin = max(sy - 1, 0); ymin = Max(sy - 1, 0);
ymax = min(sy + 1, NUMSECTORS_Y-1); ymax = Min(sy + 1, NUMSECTORS_Y-1);
for(x = xmin; x <= xmax; x++) for(x = xmin; x <= xmax; x++)
for(y = ymin; y <= ymax; y++){ for(y = ymin; y <= ymax; y++){
@ -1355,6 +1355,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
modelB.triangles[aTriangleIndicesB[j]], modelB.triangles[aTriangleIndicesB[j]],
modelB.trianglePlanes[aTriangleIndicesB[j]], modelB.trianglePlanes[aTriangleIndicesB[j]],
spherepoints[numCollisions], coldist); spherepoints[numCollisions], coldist);
if(hasCollided) if(hasCollided)
numCollisions++; numCollisions++;
} }
@ -2139,70 +2140,3 @@ CColModel::operator=(const CColModel &other)
} }
return *this; return *this;
} }
#include <new>
struct CColLine_ : public CColLine
{
CColLine *ctor(CVector *p0, CVector *p1) { return ::new (this) CColLine(*p0, *p1); }
};
struct CColModel_ : public CColModel
{
CColModel *ctor(void) { return ::new (this) CColModel(); }
void dtor(void) { this->CColModel::~CColModel(); }
};
STARTPATCHES
InjectHook(0x4B9C30, (CMatrix& (*)(const CMatrix &src, CMatrix &dst))Invert, PATCH_JUMP);
InjectHook(0x40B380, CCollision::Init, PATCH_JUMP);
InjectHook(0x40B3A0, CCollision::Shutdown, PATCH_JUMP);
InjectHook(0x40B3B0, CCollision::Update, PATCH_JUMP);
InjectHook(0x40B5B0, CCollision::LoadCollisionWhenINeedIt, PATCH_JUMP);
InjectHook(0x40B900, CCollision::SortOutCollisionAfterLoad, PATCH_JUMP);
InjectHook(0x40BB70, CCollision::TestSphereBox, PATCH_JUMP);
InjectHook(0x40E130, CCollision::TestLineBox, PATCH_JUMP);
InjectHook(0x40E5C0, CCollision::TestVerticalLineBox, PATCH_JUMP);
InjectHook(0x40EC10, CCollision::TestLineTriangle, PATCH_JUMP);
InjectHook(0x40DAA0, CCollision::TestLineSphere, PATCH_JUMP);
InjectHook(0x40C580, CCollision::TestSphereTriangle, PATCH_JUMP);
InjectHook(0x40F720, CCollision::TestLineOfSight, PATCH_JUMP);
InjectHook(0x40B9F0, CCollision::ProcessSphereSphere, PATCH_JUMP);
InjectHook(0x40BC00, CCollision::ProcessSphereBox, PATCH_JUMP);
InjectHook(0x40E670, CCollision::ProcessLineBox, PATCH_JUMP);
InjectHook(0x40DE80, CCollision::ProcessLineSphere, PATCH_JUMP);
InjectHook(0x40FB50, CCollision::ProcessVerticalLineTriangle, PATCH_JUMP);
InjectHook(0x40F140, CCollision::ProcessLineTriangle, PATCH_JUMP);
InjectHook(0x40CE30, CCollision::ProcessSphereTriangle, PATCH_JUMP);
InjectHook(0x40F910, CCollision::ProcessLineOfSight, PATCH_JUMP);
InjectHook(0x410120, CCollision::ProcessVerticalLine, PATCH_JUMP);
InjectHook(0x410BE0, CCollision::ProcessColModels, PATCH_JUMP);
InjectHook(0x40B960, CCollision::CalculateTrianglePlanes, PATCH_JUMP);
InjectHook(0x411640, &CLink<CColModel*>::Remove, PATCH_JUMP);
InjectHook(0x411620, &CLink<CColModel*>::Insert, PATCH_JUMP);
InjectHook(0x4115C0, &CLinkList<CColModel*>::Insert, PATCH_JUMP);
InjectHook(0x411600, &CLinkList<CColModel*>::Remove, PATCH_JUMP);
// InjectHook(0x411530, &CLinkList<CColModel*>::Init, PATCH_JUMP);
InjectHook(0x411E40, (void (CColSphere::*)(float, const CVector&, uint8, uint8))&CColSphere::Set, PATCH_JUMP);
InjectHook(0x40B2A0, &CColBox::Set, PATCH_JUMP);
InjectHook(0x40B320, &CColLine_::ctor, PATCH_JUMP);
InjectHook(0x40B350, &CColLine::Set, PATCH_JUMP);
InjectHook(0x411E70, &CColTriangle::Set, PATCH_JUMP);
InjectHook(0x411EA0, &CColTrianglePlane::Set, PATCH_JUMP);
InjectHook(0x412140, &CColTrianglePlane::GetNormal, PATCH_JUMP);
InjectHook(0x411680, &CColModel_::ctor, PATCH_JUMP);
InjectHook(0x4116E0, &CColModel_::dtor, PATCH_JUMP);
InjectHook(0x411D80, &CColModel::RemoveCollisionVolumes, PATCH_JUMP);
InjectHook(0x411CB0, &CColModel::CalculateTrianglePlanes, PATCH_JUMP);
InjectHook(0x411D10, &CColModel::RemoveTrianglePlanes, PATCH_JUMP);
InjectHook(0x411D40, &CColModel::SetLinkPtr, PATCH_JUMP);
InjectHook(0x411D60, &CColModel::GetLinkPtr, PATCH_JUMP);
ENDPATCHES

View file

@ -3,6 +3,13 @@
#include "templates.h" #include "templates.h"
#include "Game.h" // for eLevelName #include "Game.h" // for eLevelName
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
#ifdef FIX_BUGS
#define MAX_COLLISION_POINTS 64
#else
#define MAX_COLLISION_POINTS 32
#endif
struct CColSphere struct CColSphere
{ {
CVector center; CVector center;
@ -110,8 +117,8 @@ struct CColModel
class CCollision class CCollision
{ {
public: public:
static eLevelName &ms_collisionInMemory; static eLevelName ms_collisionInMemory;
static CLinkList<CColModel*> &ms_colModelCache; static CLinkList<CColModel*> ms_colModelCache;
static void Init(void); static void Init(void);
static void Shutdown(void); static void Shutdown(void);

View file

@ -1,7 +1,10 @@
#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
#endif
#include "common.h" #include "common.h"
#include "patcher.h" #include "crossplatform.h"
#include "ControllerConfig.h" #include "ControllerConfig.h"
#include "Pad.h" #include "Pad.h"
#include "FileMgr.h" #include "FileMgr.h"
@ -15,10 +18,9 @@
#include "World.h" #include "World.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "Camera.h" #include "Camera.h"
#include "win.h"
#include "GenericGameStorage.h" #include "GenericGameStorage.h"
CControllerConfigManager &ControlsManager = *(CControllerConfigManager*)0x8F43A4; CControllerConfigManager ControlsManager;
CControllerConfigManager::CControllerConfigManager() CControllerConfigManager::CControllerConfigManager()
{ {
@ -41,14 +43,72 @@ void CControllerConfigManager::MakeControllerActionsBlank()
} }
} }
#ifdef RW_GL3
int MapIdToButtonId(int mapId) {
switch (mapId) {
case GLFW_GAMEPAD_BUTTON_A: // Cross
return 2;
case GLFW_GAMEPAD_BUTTON_B: // Circle
return 1;
case GLFW_GAMEPAD_BUTTON_X: // Square
return 3;
case GLFW_GAMEPAD_BUTTON_Y: // Triangle
return 4;
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
return 7;
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
return 8;
case GLFW_GAMEPAD_BUTTON_BACK:
return 9;
case GLFW_GAMEPAD_BUTTON_START:
return 12;
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
return 10;
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
return 11;
case GLFW_GAMEPAD_BUTTON_DPAD_UP:
return 13;
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
return 14;
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
return 15;
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
return 16;
// GLFW sends those as axes, so I added them here manually.
case 15: // Left trigger
return 5;
case 16: // Right trigger
return 6;
default:
return 0;
}
}
#endif
int32 CControllerConfigManager::GetJoyButtonJustDown() int32 CControllerConfigManager::GetJoyButtonJustDown()
{ {
#ifdef __DINPUT_INCLUDED__ #ifdef __DINPUT_INCLUDED__
#ifdef FIX_BUGS
for (int32 i = 0; i < MAX_BUTTONS; i++)
#else
for (int32 i = 0; i < JOY_BUTTONS; i++) for (int32 i = 0; i < JOY_BUTTONS; i++)
#endif
{ {
if (m_NewState.rgbButtons[i] & 0x80 && !(m_OldState.rgbButtons[i] & 0x80)) if (m_NewState.rgbButtons[i] & 0x80 && !(m_OldState.rgbButtons[i] & 0x80))
return i + 1; return i + 1;
} }
#elif defined RW_GL3
if (m_NewState.isGamepad) {
for (int32 i = 0; i < MAX_BUTTONS; i++) {
if (m_NewState.mappedButtons[i] && !(m_OldState.mappedButtons[i]))
return MapIdToButtonId(i);
}
} else {
for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
if (m_NewState.buttons[i] && !(m_OldState.buttons[i]))
return i + 1;
}
}
#endif #endif
return 0; return 0;
} }
@ -249,8 +309,13 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
if (buttons > 16) if (buttons > 16)
btn = 16; btn = 16;
// Now we use SDL Game Controller DB
#if defined RW_D3D9 || defined RWLIBS
if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427 if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190) && AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
#else
if (0)
#endif
{ {
//GIC USB Joystick, PS2 Gamepad ? //GIC USB Joystick, PS2 Gamepad ?
@ -445,8 +510,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
break; break;
} }
if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427 // Now we use SDL Game Controller DB
#if defined RW_D3D9 || defined RWLIBS
if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190) && AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
#else
if (0)
#endif
{ {
//GIC USB Joystick, PS2 Gamepad ? //GIC USB Joystick, PS2 Gamepad ?
@ -872,8 +942,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
break; break;
} }
if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427 // Now we use SDL Game Controller DB
#if defined RW_D3D9 || defined RWLIBS
if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190) && AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
#else
if (0)
#endif
{ {
//GIC USB Joystick, PS2 Gamepad ? //GIC USB Joystick, PS2 Gamepad ?
@ -1809,7 +1884,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextKeyBoard(e_ControllerAc
static wchar ActionText[50]; static wchar ActionText[50];
static wchar NewStringWithNumber[30]; static wchar NewStringWithNumber[30];
for (int32 i = 0; i < ARRAYSIZE(ActionText); i++) for (int32 i = 0; i < ARRAY_SIZE(ActionText); i++)
ActionText[i] = '\0'; ActionText[i] = '\0';
if (GetControllerKeyAssociatedWithAction(action, type) != rsNULL) if (GetControllerKeyAssociatedWithAction(action, type) != rsNULL)
@ -2266,6 +2341,19 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
else else
m_aButtonStates[i] = false; m_aButtonStates[i] = false;
} }
#elif defined RW_GL3
if (m_NewState.isGamepad) {
for (int32 i = 0; i < MAX_BUTTONS; i++) {
if (i == GLFW_GAMEPAD_BUTTON_GUIDE)
continue;
m_aButtonStates[MapIdToButtonId(i)-1] = m_NewState.mappedButtons[i];
}
} else {
for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
m_aButtonStates[i] = m_NewState.buttons[i];
}
}
#endif #endif
} }
@ -2362,57 +2450,3 @@ void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action)
} }
} }
} }
STARTPATCHES
InjectHook(0x58B7A0, &CControllerConfigManager::MakeControllerActionsBlank, PATCH_JUMP);
InjectHook(0x58B7D0, &CControllerConfigManager::GetJoyButtonJustDown, PATCH_JUMP);
InjectHook(0x58B800, &CControllerConfigManager::SaveSettings, PATCH_JUMP);
InjectHook(0x58B870, &CControllerConfigManager::LoadSettings, PATCH_JUMP);
InjectHook(0x58B930, &CControllerConfigManager::InitDefaultControlConfiguration, PATCH_JUMP);
InjectHook(0x58BD00, &CControllerConfigManager::InitDefaultControlConfigMouse, PATCH_JUMP);
InjectHook(0x58BD90, &CControllerConfigManager::InitDefaultControlConfigJoyPad, PATCH_JUMP);
InjectHook(0x58C060, &CControllerConfigManager::InitialiseControllerActionNameArray, PATCH_JUMP);
InjectHook(0x58C5E0, &CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown, PATCH_JUMP);
InjectHook(0x58C730, &CControllerConfigManager::AffectControllerStateOn_ButtonDown, PATCH_JUMP);
InjectHook(0x58C880, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_Driving, PATCH_JUMP);
InjectHook(0x58CAD0, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnly, PATCH_JUMP);
InjectHook(0x58CB10, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly, PATCH_JUMP);
InjectHook(0x58CBD0, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstAndThirdPersonOnly, PATCH_JUMP);
InjectHook(0x58CD70, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_AllStates, PATCH_JUMP);
InjectHook(0x58CE50, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_VehicleAndThirdPersonOnly, PATCH_JUMP);
InjectHook(0x58CE80, &CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp, PATCH_JUMP);
InjectHook(0x58CFD0, &CControllerConfigManager::AffectControllerStateOn_ButtonUp, PATCH_JUMP);
InjectHook(0x58D090, &CControllerConfigManager::AffectControllerStateOn_ButtonUp_All_Player_States, PATCH_JUMP);
InjectHook(0x58D0C0, &CControllerConfigManager::AffectPadFromKeyBoard, PATCH_JUMP);
InjectHook(0x58D1A0, &CControllerConfigManager::AffectPadFromMouse, PATCH_JUMP);
InjectHook(0x58D220, &CControllerConfigManager::ClearSimButtonPressCheckers, PATCH_JUMP);
InjectHook(0x58D2A0, &CControllerConfigManager::GetIsKeyboardKeyDown, PATCH_JUMP);
InjectHook(0x58D8A0, &CControllerConfigManager::GetIsKeyboardKeyJustDown, PATCH_JUMP);
InjectHook(0x58E280, &CControllerConfigManager::GetIsMouseButtonDown, PATCH_JUMP);
InjectHook(0x58E360, &CControllerConfigManager::GetIsMouseButtonUp, PATCH_JUMP);
InjectHook(0x58E440, &CControllerConfigManager::DeleteMatchingCommonControls, PATCH_JUMP);
InjectHook(0x58E540, &CControllerConfigManager::DeleteMatching3rdPersonControls, PATCH_JUMP);
InjectHook(0x58E630, &CControllerConfigManager::DeleteMatching1rst3rdPersonControls, PATCH_JUMP);
InjectHook(0x58E710, &CControllerConfigManager::DeleteMatchingVehicleControls, PATCH_JUMP);
InjectHook(0x58E890, &CControllerConfigManager::DeleteMatchingVehicle_3rdPersonControls, PATCH_JUMP);
InjectHook(0x58E8D0, &CControllerConfigManager::DeleteMatching1rstPersonControls, PATCH_JUMP);
InjectHook(0x58E920, &CControllerConfigManager::DeleteMatchingActionInitiators, PATCH_JUMP);
InjectHook(0x58EA70, &CControllerConfigManager::GetIsKeyBlank, PATCH_JUMP);
InjectHook(0x58EAD0, &CControllerConfigManager::GetActionType, PATCH_JUMP);
InjectHook(0x58EB40, &CControllerConfigManager::ClearSettingsAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58EBF0, &CControllerConfigManager::GetControllerSettingTextWithOrderNumber, PATCH_JUMP);
InjectHook(0x58EC50, &CControllerConfigManager::GetControllerSettingTextKeyBoard, PATCH_JUMP);
InjectHook(0x58F320, &CControllerConfigManager::GetControllerSettingTextMouse, PATCH_JUMP);
InjectHook(0x58F3D0, &CControllerConfigManager::GetControllerSettingTextJoystick, PATCH_JUMP);
InjectHook(0x58F420, &CControllerConfigManager::GetNumOfSettingsForAction, PATCH_JUMP);
InjectHook(0x58F460, &CControllerConfigManager::GetWideStringOfCommandKeys, PATCH_JUMP);
InjectHook(0x58F590, &CControllerConfigManager::GetControllerKeyAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F5B0, &CControllerConfigManager::UpdateJoyButtonState, PATCH_JUMP);
InjectHook(0x58F660, &CControllerConfigManager::GetIsActionAButtonCombo, PATCH_JUMP);
InjectHook(0x58F690, &CControllerConfigManager::GetButtonComboText, PATCH_JUMP);
InjectHook(0x58F700, &CControllerConfigManager::SetControllerKeyAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F740, &CControllerConfigManager::GetMouseButtonAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F760, &CControllerConfigManager::SetMouseButtonAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F790, &CControllerConfigManager::ResetSettingOrder, PATCH_JUMP);
ENDPATCHES

Some files were not shown because too many files have changed in this diff Show more