Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryhon0 committed Oct 2, 2024
0 parents commit 9184441
Show file tree
Hide file tree
Showing 14 changed files with 2,110 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Ryhon

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
16 changes: 16 additions & 0 deletions ModLoader.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extends SceneTree

func _initialize():
var modsDir = OS.get_executable_path().get_base_dir() + "/mods"
print("Loading mods from ", modsDir)
var da = DirAccess.open(modsDir)
da.list_dir_begin()
var pck = da.get_next()
while pck:
print("Loading ", pck)
ProjectSettings.load_resource_pack(modsDir + "/" + pck)
pck = da.get_next()
print("Done")

# Change scene to main scene
change_scene_to_packed(load(ProjectSettings.get_setting_with_override("application/run/main_scene")))
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Vostok Mods
This is an experimental mod loader for Road to Vostok.
RTV doesn't natively support mods, so we need to inject a script that loads other PCKs and runs other scripts.
The mod loader is injected by appending a script to the game PCK using [GodotPckTool](https://github.com/hhyyrylainen/GodotPckTool) and using the `--script` option.
Mod PCKs (or ZIPs) will overwrite existing game files at runtime. Partial patches are not supported.

## Installation
Press the green "Code" button at the top of the page and press "Download ZIP".
Extract the contents of the installation of your game so that the `mods` directory is in the same folder as the game executable.
Download [GodotPckTool](https://github.com/hhyyrylainen/GodotPckTool/releases) and put it in your game's directory.
To run the game with mods, run the `run.sh` script in the game directory. Windows is not supported yet.

## Creating mods
Download [GodotPckTool](https://github.com/hhyyrylainen/GodotPckTool) to extract the game PCK.
All the extracted resources will be in a binary form, you can use [Godot RE Tools](https://github.com/bruvzg/gdsdecomp) to convert them back to usable formats.
Decompiling the GDScript scripts requires [v0.7.0-prerelease.1](https://github.com/bruvzg/gdsdecomp/releases/tag/v0.7.0-prerelease.1) or newer.
To create a mod, create a new folder in the `mod_src` directory.
To modify a script or asset, extract it and decompile it.
If a script has a `class_name`, it needs to be removed.
Files must be in the same relative directory to your mod folder as in the PCK (e.g. `res://Scripts/Character.gd` -> `mod_src/MyMod/Character.gd`).

### .remap files
This process may be automated in the future by the build script.

A lot of assets will have a `.remap` file, which acts like a symlink. `.remap` files have the following format:
```
[remap]
path="res://path/to/target.file"
```
Mod PCKs can overwrite the `.remap` files. For example, if you want to overwrite the `res://Scripts/Character.gd` file (which is remapped to `res://Scripts/Character.gdc`), you need to create a `Scripts/Character.gd.remap` file, which remaps to another file, e.g. `Scripts/Character.mod.gd`.

## Sample mods
These mods are included in the `mod_src` directory
### FPS++
Disables 4xMSAA in performance mode, FSR 2.2 is enabled and resolution scale can be adjusted with up/down arrow keys.
## SimpleControls
Simplifies the controls.
Weapon is always ready when not sprinting, arm stamina is only consumed while aiming. Bolt- and pump- action weapons automatically chamber next round and reload automatically with a single reload button press.
2 changes: 2 additions & 0 deletions mod_src/FPS++/Scripts/Camera.gd.remap
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[remap]
path="res://Scripts/Camera.mod.gd"
143 changes: 143 additions & 0 deletions mod_src/FPS++/Scripts/Camera.mod.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
extends Camera3D

var gameData = preload("res://Resources/GameData.tres")

@export var camera: Camera3D
@export var attribute: CameraAttributesPractical
@onready var weapons = $Weapons

var translateSpeed: = 4.0
var rotateSpeed: = 4.0
var nearFarSpeed: = 1.0
var FOVSpeed: = 1.0
var interpolate = false
var currentRID: RID

static var fsr_scale = 1.0
static var fpspp_initialized : bool = false

func _ready() -> void:
if !fpspp_initialized:
InputMap.add_action("fsr_up")
var up = InputEventKey.new()
up.pressed = true
up.keycode = KEY_UP
InputMap.action_add_event("fsr_up", up)

InputMap.add_action("fsr_down")
var down = InputEventKey.new()
down.pressed = true
down.keycode = KEY_DOWN
InputMap.action_add_event("fsr_down", down)
fpspp_initialized = true

currentRID = get_tree().get_root().get_viewport_rid()

func _process(delta):
get_tree().root.scaling_3d_mode = Viewport.SCALING_3D_MODE_FSR2
if Input.is_action_just_pressed("fsr_up"):
fsr_scale += 0.05
fsr_scale = clamp(fsr_scale, 0.1, 1.0)
print("FSR:", fsr_scale)
elif Input.is_action_just_pressed("fsr_down"):
fsr_scale -= 0.05
fsr_scale = clamp(fsr_scale, 0.1, 1.0)
print("FSR:", fsr_scale)

get_tree().root.scaling_3d_scale = fsr_scale

if gameData.isCaching:
return
else :
if gameData.flycam:
camera.fov = 75
Interpolate(delta)
else :
if interpolate:
Interpolate(delta)
FOV(delta)
DOF(delta)
else :
Follow()
FOV(delta)
DOF(delta)

if camera.projection == projection:
var near_far_factor = nearFarSpeed * delta * 10
var fov_factor = FOVSpeed * delta * 10
var new_near = lerp(near, camera.near, near_far_factor) as float
var new_far = lerp(far, camera.far, near_far_factor) as float
var new_fov = lerp(fov, camera.fov, fov_factor) as float
set_perspective(new_fov, new_near, new_far)

func Interpolate(delta):
var translate_factor = translateSpeed * delta * 10
var rotate_factor = rotateSpeed * delta * 10
var target_xform = camera.get_global_transform()
var local_transform_only_origin: = Transform3D(Basis(), get_global_transform().origin)
var local_transform_only_basis: = Transform3D(get_global_transform().basis, Vector3())

local_transform_only_origin = local_transform_only_origin.interpolate_with(target_xform, translate_factor)
local_transform_only_basis = local_transform_only_basis.interpolate_with(target_xform, rotate_factor)
set_global_transform(Transform3D(local_transform_only_basis.basis, local_transform_only_origin.origin))

func Follow():
var local_transform_only_origin: = Transform3D(Basis(), get_global_transform().origin)
var local_transform_only_basis: = Transform3D(get_global_transform().basis, Vector3())
var target_xform: = camera.get_global_transform()

local_transform_only_origin = target_xform
local_transform_only_basis = target_xform
set_global_transform(Transform3D(local_transform_only_basis.basis, local_transform_only_origin.origin))

func FOV(delta):

if gameData.isAiming && !gameData.isRunning && !gameData.isInspecting && !gameData.isPreparing && !gameData.isColliding && !gameData.isReloading && (gameData.weaponType == 0 || gameData.weaponType == 1):
camera.fov = lerp(camera.fov, gameData.aimFOV, delta * 50.0)


elif gameData.isAiming && !gameData.isRunning && !gameData.isInspecting && !gameData.isPreparing && !gameData.isColliding && (gameData.weaponType == 2 || gameData.weaponType == 3):
camera.fov = lerp(camera.fov, gameData.aimFOV, delta * 50.0)


else :
camera.fov = lerp(camera.fov, gameData.baseFOV, delta * 25)

func DOF(delta):

if (gameData.settings || gameData.interface):
UIDOF(delta)

elif gameData.isScoped && gameData.isAiming && !gameData.isReloading && (gameData.weaponType == 0 || gameData.weaponType == 1):
ScopeDOF(delta)

elif gameData.isScoped && gameData.isAiming && (gameData.weaponType == 2 || gameData.weaponType == 3):
ScopeDOF(delta)

else :
ResetDOF(delta)

func UIDOF(delta):
attribute.dof_blur_far_enabled = true
attribute.dof_blur_near_enabled = true
attribute.dof_blur_far_distance = 0.01
attribute.dof_blur_far_transition = 5.0
attribute.dof_blur_near_distance = 400
attribute.dof_blur_near_transition = 1.0
attribute.dof_blur_amount = move_toward(attribute.dof_blur_amount, 0.1, delta)

func ScopeDOF(delta):

attribute.dof_blur_far_enabled = true
attribute.dof_blur_near_enabled = false
attribute.dof_blur_far_distance = 0.01
attribute.dof_blur_far_transition = 5.0
attribute.dof_blur_amount = move_toward(attribute.dof_blur_amount, 0.1, delta)

func ResetDOF(delta):

attribute.dof_blur_amount = move_toward(attribute.dof_blur_amount, 0.0, delta)

if attribute.dof_blur_amount == 0:
attribute.dof_blur_far_enabled = false
attribute.dof_blur_near_enabled = false
2 changes: 2 additions & 0 deletions mod_src/FPS++/Scripts/World.gd.remap
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[remap]
path="res://Scripts/World.mod.gd"
Loading

0 comments on commit 9184441

Please sign in to comment.