Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71c654e5b6 | ||
|
|
570f051281 | ||
|
|
0240721d46 | ||
|
|
e350ec26ac | ||
|
|
96e748715b | ||
|
|
d5ef126264 | ||
|
|
9b71ee447a | ||
|
|
d38a75ea72 | ||
|
|
9fa120d4ad | ||
|
|
ea8f64c940 | ||
|
|
c9c6b7e7fb | ||
|
|
a11c4614ea | ||
|
|
5cbe7a345e | ||
|
|
2add42c1cb | ||
|
|
4039c24372 | ||
|
|
7df68febca | ||
|
|
5ecf5fb9d7 | ||
|
|
c3f449b999 | ||
|
|
8a0a8390b2 | ||
|
|
d39f5ca68b |
No files matched your search
@@ -5,3 +5,6 @@
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||
*.ogg filter=lfs diff=lfs merge=lfs -text
|
||||
*.mp3 filter=lfs diff=lfs merge=lfs -text
|
||||
*.bin filter=lfs diff=lfs merge=lfs -text
|
||||
*.dll filter=lfs diff=lfs merge=lfs -text
|
||||
*.so filter=lfs diff=lfs merge=lfs -text
|
||||
+1
-1
@@ -409,7 +409,7 @@ web_resources/
|
||||
pc_resources/
|
||||
resources_hd/
|
||||
web_resources_x2/
|
||||
|
||||
android_resources/
|
||||
|
||||
.artifacts/
|
||||
|
||||
|
||||
@@ -185,3 +185,44 @@ make -j$(nproc) -C build #Компилируем
|
||||
Для постройки без звука
|
||||
rm -rf build #Очищаем build папку
|
||||
cmake -B build -DAUDIO=1 #Пересоздаём конфигурацию CMake
|
||||
|
||||
|
||||
# Cmake Build NSIS and Portable for Windows:
|
||||
|
||||
```
|
||||
cmake --build . --config Release
|
||||
cpack -C Release
|
||||
```
|
||||
|
||||
Если есть такая ошибка:
|
||||
|
||||
CPack Error: Cannot find NSIS compiler makensis: likely it is not installed, or not in your PATH
|
||||
CPack Error: Could not read NSIS registry value. This is usually caused by NSIS not being installed. Please install NSIS from http://nsis.sourceforge.net
|
||||
CPack Error: Cannot initialize the generator NSIS
|
||||
|
||||
|
||||
То нужно установить nsis отсюда: https://nsis.sourceforge.io/Download
|
||||
|
||||
|
||||
# Steam windows
|
||||
|
||||
```
|
||||
cmake -DSTEAMSDK=ON ..
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
|
||||
# Steam Linux
|
||||
|
||||
```
|
||||
docker run -it --rm -v "${PWD}:/work2" -w /work2 registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest bash
|
||||
|
||||
|
||||
apt-get update
|
||||
apt-get install libboost-dev libeigen3-dev liblua5.4-dev libzip-dev libglu1-mesa-dev
|
||||
|
||||
|
||||
cmake -DSTEAMSDK=ON -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . -j 4
|
||||
|
||||
```
|
||||
@@ -25,7 +25,7 @@ macro(check_and_download URL ARCHIVE_NAME EXTRACTED_DIR_NAME CHECK_FILE)
|
||||
endmacro()
|
||||
|
||||
# 1) ZLIB (Нужна только для инклудов, если не используете emscripten порты)
|
||||
check_and_download("https://www.zlib.net/zlib132.zip" "zlib132.zip" "zlib-1.3.2" "CMakeLists.txt")
|
||||
check_and_download("https://github.com/madler/zlib/releases/download/v1.3.2/zlib132.zip" "zlib132.zip" "zlib-1.3.2" "CMakeLists.txt")
|
||||
|
||||
# 2) SDL2
|
||||
check_and_download("https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.32.10.zip" "release-2.32.10.zip" "SDL-release-2.32.10" "CMakeLists.txt")
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
optimize_web_resources.py - Resize PNG images for the web build.
|
||||
|
||||
Copies <src> to <dst>/resources/, then downscales all PNG files:
|
||||
- resources/w/ui/img/** -> 1/8 original size
|
||||
- all other PNGs -> 1/4 original size
|
||||
|
||||
Files listed in EXCEPTIONS are copied unchanged.
|
||||
|
||||
Usage (manual):
|
||||
python optimize_web_resources.py [--src resources] [--dst web_resources]
|
||||
|
||||
Usage (CMake):
|
||||
${Python3_EXECUTABLE} optimize_web_resources.py --src <abs_src> --dst <abs_dst>
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
raise SystemExit("Pillow is required: pip install Pillow")
|
||||
|
||||
# Paths relative to the resources directory — these files are never resized.
|
||||
EXCEPTIONS = {
|
||||
"loading.png",
|
||||
"loading_land003_en.png",
|
||||
"loading_land003_ru.png",
|
||||
"black.png",
|
||||
"transparent.png",
|
||||
"w/blue.png",
|
||||
"w/red.png",
|
||||
"w/spark.png",
|
||||
"w/star.png",
|
||||
"w/star_red.png",
|
||||
"w/white.png",
|
||||
"w/ui/img/main/aboutPage003android.png",
|
||||
"w/ui_en/img/main/aboutPage003android.png",
|
||||
"w/exterior/texAtlas002.png",
|
||||
}
|
||||
|
||||
# Path prefixes (relative to resources root, forward-slash) that get 8x reduction.
|
||||
HIGH_REDUCTION_PREFIXES = (
|
||||
"w/ui/img",
|
||||
)
|
||||
|
||||
LOW_REDUCTION_POSTFIXES = (
|
||||
"texAtlas002.png",
|
||||
"Building_work014.png",
|
||||
"Building_Floors_tex004.png",
|
||||
"Building_Walls_tex006.png",
|
||||
"asphalt003small.png",
|
||||
"Ext_Building004.png",
|
||||
"Plane3_tex002.png",
|
||||
"darklands_building002.png",
|
||||
"Staircase001.png",
|
||||
"Staircase_Obj002.png"
|
||||
)
|
||||
|
||||
def _resize_factor(rel: str) -> int:
|
||||
norm = rel.replace("\\", "/")
|
||||
for prefix in HIGH_REDUCTION_PREFIXES:
|
||||
if norm.startswith(prefix):
|
||||
return 8
|
||||
for prefix in LOW_REDUCTION_POSTFIXES:
|
||||
if norm.endswith(prefix):
|
||||
return 2
|
||||
return 4
|
||||
|
||||
|
||||
def _next_pot(n: int) -> int:
|
||||
if n < 1:
|
||||
return 1
|
||||
p = 1
|
||||
while p < n:
|
||||
p <<= 1
|
||||
return p
|
||||
|
||||
|
||||
def optimize(src_dir: str, dst_parent: str) -> None:
|
||||
src_dir = os.path.abspath(src_dir)
|
||||
dst_resources = os.path.join(os.path.abspath(dst_parent), "resources")
|
||||
|
||||
print(f"Copying {src_dir} -> {dst_resources}")
|
||||
if os.path.exists(dst_resources):
|
||||
shutil.rmtree(dst_resources)
|
||||
shutil.copytree(src_dir, dst_resources)
|
||||
|
||||
total = 0
|
||||
for root, _dirs, files in os.walk(dst_resources):
|
||||
for filename in files:
|
||||
if not filename.lower().endswith(".png"):
|
||||
continue
|
||||
|
||||
full_path = os.path.join(root, filename)
|
||||
rel = os.path.relpath(full_path, dst_resources).replace("\\", "/")
|
||||
|
||||
if rel in EXCEPTIONS:
|
||||
print(f" skip (exception): {rel}")
|
||||
continue
|
||||
|
||||
factor = _resize_factor(rel)
|
||||
|
||||
with Image.open(full_path) as img:
|
||||
orig_w, orig_h = img.size
|
||||
new_w = _next_pot(max(1, orig_w // factor))
|
||||
new_h = _next_pot(max(1, orig_h // factor))
|
||||
resized = img.resize((new_w, new_h), Image.LANCZOS)
|
||||
resized.save(full_path)
|
||||
|
||||
print(f" {rel}: {orig_w}x{orig_h} -> {new_w}x{new_h} (/{factor} + POT)")
|
||||
total += 1
|
||||
|
||||
print(f"Done. Resized {total} PNG file(s).")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Optimize PNG images for web build")
|
||||
parser.add_argument("--src", default="resources",
|
||||
help="Source resources directory (default: resources)")
|
||||
parser.add_argument("--dst", default="android_resources",
|
||||
help="Destination parent directory; will contain a 'resources' subdir "
|
||||
"(default: android_resources)")
|
||||
args = parser.parse_args()
|
||||
optimize(args.src, args.dst)
|
||||
@@ -27,7 +27,18 @@ except ImportError:
|
||||
# Paths relative to the resources directory — these files are never resized.
|
||||
EXCEPTIONS = {
|
||||
"loading.png",
|
||||
"loading_land003_en.png",
|
||||
"loading_land003_ru.png",
|
||||
"black.png",
|
||||
"transparent.png",
|
||||
"w/blue.png",
|
||||
"w/red.png",
|
||||
"w/spark.png",
|
||||
"w/star.png",
|
||||
"w/star_red.png",
|
||||
"w/white.png",
|
||||
"w/ui/img/main/aboutPage003android.png",
|
||||
"w/ui_en/img/main/aboutPage003android.png"
|
||||
}
|
||||
|
||||
# Path prefixes (relative to resources root, forward-slash) that get 8x reduction.
|
||||
@@ -35,13 +46,28 @@ HIGH_REDUCTION_PREFIXES = (
|
||||
"w/ui/img",
|
||||
)
|
||||
|
||||
LOW_REDUCTION_POSTFIXES = (
|
||||
"texAtlas002.png",
|
||||
"Building_work014.png",
|
||||
"Building_Floors_tex004.png",
|
||||
"Building_Walls_tex006.png",
|
||||
"asphalt003small.png",
|
||||
"Ext_Building004.png",
|
||||
"Plane3_tex002.png",
|
||||
"darklands_building002.png",
|
||||
"Staircase001.png",
|
||||
"Staircase_Obj002.png"
|
||||
)
|
||||
|
||||
def _resize_factor(rel: str) -> int:
|
||||
norm = rel.replace("\\", "/")
|
||||
for prefix in HIGH_REDUCTION_PREFIXES:
|
||||
if norm.startswith(prefix):
|
||||
return 8
|
||||
return 4
|
||||
for prefix in LOW_REDUCTION_POSTFIXES:
|
||||
if norm.endswith(prefix):
|
||||
return 2
|
||||
return 8
|
||||
|
||||
|
||||
def _next_pot(n: int) -> int:
|
||||
|
||||
@@ -61,6 +61,5 @@ app/jni/libpng
|
||||
app/jni/SDL
|
||||
app/jni/zlib
|
||||
|
||||
app/src/main/assets/resources
|
||||
app/src/main/assets/audio
|
||||
app/src/main/assets
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY');
|
||||
def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY')
|
||||
def buildAsApplication = !buildAsLibrary
|
||||
if (buildAsApplication) {
|
||||
apply plugin: 'com.android.application'
|
||||
@@ -15,8 +15,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 37
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionCode 4
|
||||
versionName "1.0.7"
|
||||
externalNativeBuild {
|
||||
/*ndkBuild {
|
||||
arguments "APP_PLATFORM=android-19"
|
||||
@@ -31,7 +31,10 @@ android {
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
// Enables code optimizations.
|
||||
minifyEnabled = true
|
||||
// Enables resource shrinking.
|
||||
shrinkResources = true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ add_library(main SHARED
|
||||
../../../../src/Localization.h
|
||||
../../../../src/render/Renderer.cpp
|
||||
../../../../src/render/Renderer.h
|
||||
../../../../src/render/PathVisualization.cpp
|
||||
../../../../src/render/PathVisualization.h
|
||||
../../../../src/render/ShaderManager.cpp
|
||||
../../../../src/render/ShaderManager.h
|
||||
../../../../src/render/TextureManager.cpp
|
||||
@@ -112,6 +114,7 @@ add_library(main SHARED
|
||||
../../../../src/items/Item.cpp
|
||||
../../../../src/items/ItemRegistry.h
|
||||
../../../../src/items/ItemRegistry.cpp
|
||||
../../../../src/Campaign.cpp
|
||||
../../../../src/items/InteractiveObject.h
|
||||
../../../../src/items/InteractiveObject.cpp
|
||||
../../../../src/items/InteractiveObjectState.h
|
||||
|
||||
Vendored
+12
-6
@@ -16,18 +16,21 @@
|
||||
# public *;
|
||||
#}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class fishrungames.shadowoverbishkek.SDLInputConnection {
|
||||
# SDL2 specific rules
|
||||
-keep class org.libsdl.app.** { *; }
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLInputConnection {
|
||||
void nativeCommitText(java.lang.String, int);
|
||||
void nativeGenerateScancodeForUnichar(char);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses class fishrungames.shadowoverbishkek.SDLActivity {
|
||||
-keep,includedescriptorclasses class org.libsdl.app.SDLActivity {
|
||||
# for some reason these aren't compatible with allowoptimization modifier
|
||||
boolean supportsRelativeMouse();
|
||||
void setWindowStyle(boolean);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class fishrungames.shadowoverbishkek.SDLActivity {
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
|
||||
java.lang.String nativeGetHint(java.lang.String); # Java-side doesn't use this, so it gets minified, but C-side still tries to register it
|
||||
boolean onNativeSoftReturnKey();
|
||||
void onNativeKeyboardFocusLost();
|
||||
@@ -62,7 +65,7 @@
|
||||
boolean showTextInput(int, int, int, int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class fishrungames.shadowoverbishkek.HIDDeviceManager {
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
|
||||
boolean initialize(boolean, boolean);
|
||||
boolean openDevice(int);
|
||||
int sendOutputReport(int, byte[]);
|
||||
@@ -71,7 +74,7 @@
|
||||
void closeDevice(int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class fishrungames.shadowoverbishkek.SDLAudioManager {
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLAudioManager {
|
||||
int[] getAudioOutputDevices();
|
||||
int[] getAudioInputDevices();
|
||||
int[] audioOpen(int, int, int, int, int);
|
||||
@@ -90,9 +93,12 @@
|
||||
native void addAudioDevice(boolean, int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class fishrungames.shadowoverbishkek.SDLControllerManager {
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
|
||||
void pollInputDevices();
|
||||
void pollHapticDevices();
|
||||
void hapticRun(int, float, int);
|
||||
void hapticStop(int);
|
||||
}
|
||||
|
||||
# Keep our main activity
|
||||
-keep class fishrungames.shadowoverbishkek.ShadowOverBishkekActivity { *; }
|
||||
@@ -19,7 +19,7 @@ android.r8.strictFullModeForKeepRules=false
|
||||
android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
|
||||
android.uniquePackageNames=false
|
||||
android.usesSdkInManifest.disallowed=false
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
org.gradle.jvmargs=-Xmx4096m
|
||||
android.useAndroidX=true
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
|
||||
@@ -85,6 +85,8 @@ add_executable(ShadowOverBishkekDemo
|
||||
../src/Localization.h
|
||||
../src/render/Renderer.cpp
|
||||
../src/render/Renderer.h
|
||||
../src/render/PathVisualization.cpp
|
||||
../src/render/PathVisualization.h
|
||||
../src/render/ShaderManager.cpp
|
||||
../src/render/ShaderManager.h
|
||||
../src/render/TextureManager.cpp
|
||||
@@ -137,6 +139,7 @@ add_executable(ShadowOverBishkekDemo
|
||||
../src/items/Item.cpp
|
||||
../src/items/ItemRegistry.h
|
||||
../src/items/ItemRegistry.cpp
|
||||
../src/Campaign.cpp
|
||||
../src/items/InteractiveObject.h
|
||||
../src/items/InteractiveObject.cpp
|
||||
../src/items/InteractiveObjectState.h
|
||||
@@ -290,7 +293,7 @@ endif()
|
||||
# ===========================================
|
||||
set(RUNTIME_RESOURCE_DIRS
|
||||
"resources"
|
||||
"audio"
|
||||
"music"
|
||||
)
|
||||
|
||||
foreach(resdir IN LISTS RUNTIME_RESOURCE_DIRS)
|
||||
|
||||
+44
-14
@@ -8,13 +8,19 @@ if(NOT CMAKE_MAKE_PROGRAM AND WIN32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
project(bishkek-witcher LANGUAGES C CXX)
|
||||
project(ShadowOverBishkekDemo LANGUAGES C CXX)
|
||||
|
||||
option(OPTIMIZE_WEB_RESOURCES "Resize PNG images for web build (requires Python3 + Pillow)" ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
# Максимальная оптимизация кода и LTO (Link-Time Optimization)
|
||||
add_compile_options(-O3 -flto)
|
||||
add_link_options(-O3 -flto)
|
||||
endif()
|
||||
|
||||
# --- АВТО-ЗАГРУЗКА ЗАВИСИМОСТЕЙ ---
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
|
||||
# Теперь гарантированно есть папка ../thirdparty со всеми исходниками
|
||||
@@ -73,6 +79,8 @@ set(SOURCES
|
||||
../src/Localization.h
|
||||
../src/render/Renderer.cpp
|
||||
../src/render/Renderer.h
|
||||
../src/render/PathVisualization.cpp
|
||||
../src/render/PathVisualization.h
|
||||
../src/render/ShaderManager.cpp
|
||||
../src/render/ShaderManager.h
|
||||
../src/render/TextureManager.cpp
|
||||
@@ -125,6 +133,7 @@ set(SOURCES
|
||||
../src/items/Item.cpp
|
||||
../src/items/ItemRegistry.h
|
||||
../src/items/ItemRegistry.cpp
|
||||
../src/Campaign.cpp
|
||||
../src/items/InteractiveObject.h
|
||||
../src/items/InteractiveObject.cpp
|
||||
../src/items/InteractiveObjectState.h
|
||||
@@ -152,10 +161,10 @@ set(SOURCES
|
||||
../src/render/UiQuad.h
|
||||
)
|
||||
|
||||
add_executable(bishkek-witcher ${SOURCES})
|
||||
add_executable(ShadowOverBishkekDemo ${SOURCES})
|
||||
|
||||
# Настройка путей к инклудам (используем скачанные исходники)
|
||||
target_include_directories(bishkek-witcher PRIVATE
|
||||
target_include_directories(ShadowOverBishkekDemo PRIVATE
|
||||
../src
|
||||
../thirdparty/eigen-5.0.0
|
||||
../thirdparty/boost_1_90_0
|
||||
@@ -170,7 +179,7 @@ set(ENABLE_COMMONCRYPTO OFF CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory("../thirdparty/libzip-1.11.4" libzip-build)
|
||||
|
||||
target_link_libraries(bishkek-witcher PRIVATE zip z lua_static websocket.js)
|
||||
target_link_libraries(ShadowOverBishkekDemo PRIVATE zip z lua_static websocket.js)
|
||||
|
||||
# Эмскриптен-флаги
|
||||
set(EMSCRIPTEN_FLAGS
|
||||
@@ -187,7 +196,7 @@ set(EMSCRIPTEN_FLAGS
|
||||
"-DNETWORK"
|
||||
)
|
||||
|
||||
target_compile_options(bishkek-witcher PRIVATE ${EMSCRIPTEN_FLAGS} "-O2")
|
||||
target_compile_options(ShadowOverBishkekDemo PRIVATE ${EMSCRIPTEN_FLAGS} "-O2")
|
||||
|
||||
# Only loading.png and the shaders used before resources.zip is ready are preloaded.
|
||||
# resources.zip is downloaded asynchronously at runtime and served as a separate file.
|
||||
@@ -205,15 +214,14 @@ set(EMSCRIPTEN_LINK_FLAGS
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_interior.lua@resources/start_uni_interior.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_uni_exterior.lua@resources/start_uni_exterior.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_dorm.lua@resources/start_dorm.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../audio@audio"
|
||||
)
|
||||
|
||||
# Применяем настройки линковки
|
||||
target_link_options(bishkek-witcher PRIVATE ${EMSCRIPTEN_LINK_FLAGS})
|
||||
target_link_options(ShadowOverBishkekDemo PRIVATE ${EMSCRIPTEN_LINK_FLAGS})
|
||||
|
||||
# Для совместимости со старыми версиями CMake, если target_link_options недостаточно
|
||||
string(REPLACE ";" " " EMSCRIPTEN_LINK_FLAGS_STR "${EMSCRIPTEN_LINK_FLAGS}")
|
||||
set_target_properties(bishkek-witcher PROPERTIES
|
||||
set_target_properties(ShadowOverBishkekDemo PROPERTIES
|
||||
LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS_STR}"
|
||||
SUFFIX ".html"
|
||||
)
|
||||
@@ -257,23 +265,40 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
# music resources
|
||||
set(MUSIC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../music")
|
||||
set(MUSIC_ZIP "${CMAKE_CURRENT_BINARY_DIR}/music.zip")
|
||||
get_filename_component(MUSIC_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MUSIC_ZIP}"
|
||||
COMMAND ${CMAKE_COMMAND} -E tar "cf" "${MUSIC_ZIP}" --format=zip "music"
|
||||
WORKING_DIRECTORY "${MUSIC_PARENT_DIR}"
|
||||
DEPENDS "${MUSIC_PARENT_DIR}/music"
|
||||
)
|
||||
|
||||
|
||||
add_custom_target(pack_resources DEPENDS "${RESOURCES_ZIP}")
|
||||
add_dependencies(bishkek-witcher pack_resources)
|
||||
add_dependencies(ShadowOverBishkekDemo pack_resources)
|
||||
|
||||
add_custom_target(pack_music DEPENDS "${MUSIC_ZIP}")
|
||||
add_dependencies(ShadowOverBishkekDemo pack_music)
|
||||
|
||||
|
||||
# Определяем путь к директории установки (относительно папки билда)
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/public")
|
||||
|
||||
# 1. Устанавливаем основной HTML файл
|
||||
install(TARGETS bishkek-witcher
|
||||
install(TARGETS ShadowOverBishkekDemo
|
||||
RUNTIME DESTINATION .
|
||||
)
|
||||
|
||||
# 2. Устанавливаем сопутствующие файлы (JS, WASM и сгенерированный архив данных)
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bishkek-witcher.js"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bishkek-witcher.wasm"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bishkek-witcher.data"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ShadowOverBishkekDemo.js"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ShadowOverBishkekDemo.wasm"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ShadowOverBishkekDemo.data"
|
||||
DESTINATION .
|
||||
)
|
||||
|
||||
@@ -281,10 +306,15 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/index.html"
|
||||
DESTINATION .
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/favicon.ico"
|
||||
DESTINATION .
|
||||
)
|
||||
|
||||
# resources.zip is served separately and downloaded asynchronously at runtime
|
||||
install(FILES "${RESOURCES_ZIP}" DESTINATION .)
|
||||
install(FILES "${MUSIC_ZIP}" DESTINATION .)
|
||||
|
||||
add_custom_command(TARGET bishkek-witcher POST_BUILD
|
||||
add_custom_command(TARGET ShadowOverBishkekDemo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} --install .
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
COMMENT "Automatically deploying to public directory..."
|
||||
|
||||
@@ -37,3 +37,14 @@ Run:
|
||||
```
|
||||
emrun --no_browser --port 8080 public
|
||||
```
|
||||
|
||||
# Release build
|
||||
|
||||
|
||||
```
|
||||
mkdir build_release
|
||||
cd build_release
|
||||
emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . --config Release
|
||||
cmake --install . --prefix ../dist
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
<!doctypehtml><html lang=en-us><head><meta charset=utf-8><meta content="text/html; charset=utf-8"http-equiv=Content-Type><title>Emscripten-Generated Code</title><style>body{font-family:arial;margin:0;padding:none}.emscripten{padding-right:0;margin-left:auto;margin-right:auto;display:block}div.emscripten{text-align:center}div.emscripten_border{border:1px solid #000}canvas.emscripten{border:0 none;background-color:#000}#emscripten_logo{display:inline-block;margin:0;padding:6px;width:265px}.spinner{height:30px;width:30px;margin:0;margin-top:20px;margin-left:20px;display:inline-block;vertical-align:top;-webkit-animation:rotation .8s linear infinite;-moz-animation:rotation .8s linear infinite;-o-animation:rotation .8s linear infinite;animation:rotation .8s linear infinite;border-left:5px solid #ebebeb;border-right:5px solid #ebebeb;border-bottom:5px solid #ebebeb;border-top:5px solid #787878;border-radius:100%;background-color:#bdd72e}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0)}to{-moz-transform:rotate(360deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0)}to{-o-transform:rotate(360deg)}}@keyframes rotation{from{transform:rotate(0)}to{transform:rotate(360deg)}}#status{display:inline-block;vertical-align:top;margin-top:30px;margin-left:20px;font-weight:700;color:#787878}#progress{height:20px;width:300px}#controls{display:inline-block;float:right;vertical-align:top;margin-top:30px;margin-right:20px}#output{width:100%;height:200px;margin:0 auto;margin-top:10px;border-left:0;border-right:0px;padding-left:0;padding-right:0;display:block;background-color:#000;color:#fff;font-family:'Lucida Console',Monaco,monospace;outline:0}</style></head><body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>eruda.init();</script>
|
||||
|
||||
<a href=http://emscripten.org><img id=emscripten_logo src=data:image/png;base64,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 truncated
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
+1
-1
@@ -39,7 +39,7 @@
|
||||
|
||||
function loadGameScript() {
|
||||
var s = document.createElement('script');
|
||||
s.src = 'bishkek-witcher.js';
|
||||
s.src = 'ShadowOverBishkekDemo.js';
|
||||
s.async = true;
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<!doctypehtml><html lang=en-us><head><meta charset=utf-8><meta content="text/html; charset=utf-8"http-equiv=Content-Type><title>Emscripten-Generated Code</title><style>body{font-family:arial;margin:0;padding:none}.emscripten{padding-right:0;margin-left:auto;margin-right:auto;display:block}div.emscripten{text-align:center}div.emscripten_border{border:1px solid #000}canvas.emscripten{border:0 none;background-color:#000}#emscripten_logo{display:inline-block;margin:0;padding:6px;width:265px}.spinner{height:30px;width:30px;margin:0;margin-top:20px;margin-left:20px;display:inline-block;vertical-align:top;-webkit-animation:rotation .8s linear infinite;-moz-animation:rotation .8s linear infinite;-o-animation:rotation .8s linear infinite;animation:rotation .8s linear infinite;border-left:5px solid #ebebeb;border-right:5px solid #ebebeb;border-bottom:5px solid #ebebeb;border-top:5px solid #787878;border-radius:100%;background-color:#bdd72e}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0)}to{-moz-transform:rotate(360deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0)}to{-o-transform:rotate(360deg)}}@keyframes rotation{from{transform:rotate(0)}to{transform:rotate(360deg)}}#status{display:inline-block;vertical-align:top;margin-top:30px;margin-left:20px;font-weight:700;color:#787878}#progress{height:20px;width:300px}#controls{display:inline-block;float:right;vertical-align:top;margin-top:30px;margin-right:20px}#output{width:100%;height:200px;margin:0 auto;margin-top:10px;border-left:0;border-right:0px;padding-left:0;padding-right:0;display:block;background-color:#000;color:#fff;font-family:'Lucida Console',Monaco,monospace;outline:0}</style></head><body><script src="https://cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>eruda.init();</script><a href=http://emscripten.org><img id=emscripten_logo src=""></a><div class=spinner id=spinner></div><div class=emscripten id=status>Downloading...</div><span id=controls><span><input type=checkbox id=resize>Resize canvas</span> <span><input type=checkbox id=pointerLock checked>Lock/hide mouse pointer </span><span><input type=button onclick='Module.requestFullscreen(document.getElementById("pointerLock").checked,document.getElementById("resize").checked)'value=Fullscreen></span></span><div class=emscripten><progress hidden id=progress max=100 value=0></progress></div><div class=emscripten_border><canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas></div><textarea id=output rows=8></textarea><script>var statusElement=document.getElementById("status"),progressElement=document.getElementById("progress"),spinnerElement=document.getElementById("spinner"),canvasElement=document.getElementById("canvas"),outputElement=document.getElementById("output");outputElement&&(outputElement.value=""),canvasElement.addEventListener("webglcontextlost",(e=>{alert("WebGL context lost. You will need to reload the page."),e.preventDefault()}),!1);var Module={print(...e){if(console.log(...e),outputElement){var t=e.join(" ");outputElement.value+=t+"\n",outputElement.scrollTop=outputElement.scrollHeight}},canvas:canvasElement,setStatus(e){if(Module.setStatus.last||(Module.setStatus.last={time:Date.now(),text:""}),e!==Module.setStatus.last.text){var t=e.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/),n=Date.now();t&&n-Module.setStatus.last.time<30||(Module.setStatus.last.time=n,Module.setStatus.last.text=e,t?(e=t[1],progressElement.value=100*parseInt(t[2]),progressElement.max=100*parseInt(t[4]),progressElement.hidden=!1,spinnerElement.hidden=!1):(progressElement.value=null,progressElement.max=null,progressElement.hidden=!0,e||(spinnerElement.style.display="none")),statusElement.innerHTML=e)}},totalDependencies:0,monitorRunDependencies(e){this.totalDependencies=Math.max(this.totalDependencies,e),Module.setStatus(e?"Preparing... ("+(this.totalDependencies-e)+"/"+this.totalDependencies+")":"All downloads complete.")}};Module.setStatus("Downloading..."),window.onerror=e=>{Module.setStatus("Exception thrown, see JavaScript console"),spinnerElement.style.display="none",Module.setStatus=e=>{e&&console.error("[post-exception status] "+e)}}</script><script async src="space-game001.js" crossorigin="anonymous"></script></body></html>
|
||||
@@ -1,200 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<title>Sky Trek Tales</title>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0; padding: 0; width: 100%; height: 100%;
|
||||
overflow: hidden; background-color: #000;
|
||||
position: fixed;
|
||||
}
|
||||
#canvas {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 100vw; height: 100vh;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#fs-button {
|
||||
position: absolute;
|
||||
top: 10px; right: 10px;
|
||||
padding: 10px;
|
||||
z-index: 10;
|
||||
background: rgba(255,255,255,0.3);
|
||||
color: white; border: 1px solid white;
|
||||
cursor: pointer;
|
||||
font-family: sans-serif;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#status { color: white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
|
||||
|
||||
/* Nick modal */
|
||||
#nickOverlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0,0,0,0.85);
|
||||
z-index: 9999;
|
||||
}
|
||||
#nickBox {
|
||||
background: #111;
|
||||
border: 1px solid #444;
|
||||
padding: 24px;
|
||||
width: 320px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.6);
|
||||
text-align: center;
|
||||
}
|
||||
#nickBox h2 { margin: 0 0 12px 0; font-size: 18px; color: #eee; }
|
||||
#nickBox input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 12px;
|
||||
border: 1px solid #333;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
#nickBox button {
|
||||
padding: 10px 16px;
|
||||
font-size: 16px;
|
||||
background: #2a9fd6;
|
||||
border: none;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="fs-button">Fullscreen</button>
|
||||
<div id="status">Downloading...</div>
|
||||
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex="-1"></canvas>
|
||||
<div id="nickOverlay" style="display:none;">
|
||||
<div id="nickBox">
|
||||
<h2>Enter your nickname</h2>
|
||||
<input id="nickInput" type="text" maxlength="32" placeholder="Player" />
|
||||
<div>
|
||||
<button id="nickSubmit">Start</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Utility: подготовить глобальный Module до загрузки Emscripten-скрипта
|
||||
function prepareModuleEnvironment() {
|
||||
window.Module = window.Module || {};
|
||||
var canvasEl = document.getElementById('canvas');
|
||||
// Устанавливаем canvas для Emscripten, чтобы createContext не падал
|
||||
window.Module.canvas = canvasEl;
|
||||
// Подготовим заглушку setStatus, если ещё нет
|
||||
window.Module.setStatus = window.Module.setStatus || function (text) {
|
||||
var statusElement = document.getElementById("status");
|
||||
statusElement.innerHTML = text;
|
||||
statusElement.style.display = text ? 'block' : 'none';
|
||||
};
|
||||
}
|
||||
|
||||
// Show overlay only if no nickname saved.
|
||||
function loadGameScript() {
|
||||
var s = document.createElement('script');
|
||||
s.src = 'space-game001.js';
|
||||
s.async = true;
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
|
||||
function showNickOverlay() {
|
||||
var overlay = document.getElementById('nickOverlay');
|
||||
overlay.style.display = 'flex';
|
||||
var input = document.getElementById('nickInput');
|
||||
input.focus();
|
||||
}
|
||||
|
||||
function hideNickOverlay() {
|
||||
var overlay = document.getElementById('nickOverlay');
|
||||
overlay.style.display = 'none';
|
||||
}
|
||||
|
||||
function saveNickAndStart(nick) {
|
||||
try {
|
||||
if (!nick || nick.trim() === '') nick = 'Player';
|
||||
localStorage.setItem('spacegame_nick', nick);
|
||||
} catch (e) {
|
||||
console.warn('localStorage not available', e);
|
||||
}
|
||||
hideNickOverlay();
|
||||
// перед загрузкой скрипта гарантируем, что Module.canvas задан
|
||||
prepareModuleEnvironment();
|
||||
loadGameScript();
|
||||
}
|
||||
|
||||
document.getElementById('fs-button').addEventListener('click', function() {
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen().catch(function(e) {
|
||||
console.error('Fullscreen error: ' + e.message);
|
||||
});
|
||||
} else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Готовим Module сразу — даже если откроется модалка, поле canvas будет доступно для скрипта (если он загружается позже)
|
||||
prepareModuleEnvironment();
|
||||
|
||||
var stored = null;
|
||||
try {
|
||||
stored = localStorage.getItem('spacegame_nick');
|
||||
} catch (e) {
|
||||
console.warn('localStorage not available', e);
|
||||
}
|
||||
|
||||
if (stored && stored.trim() !== '') {
|
||||
// Nick is present — start immediately
|
||||
loadGameScript();
|
||||
} else {
|
||||
// Show modal to request nickname before loading WASM
|
||||
showNickOverlay();
|
||||
var submit = document.getElementById('nickSubmit');
|
||||
var input = document.getElementById('nickInput');
|
||||
|
||||
submit.addEventListener('click', function() {
|
||||
saveNickAndStart(input.value);
|
||||
});
|
||||
|
||||
input.addEventListener('input', function() {
|
||||
// Strip any character that is not a-z, A-Z, 0-9 or space
|
||||
var pos = this.selectionStart;
|
||||
var cleaned = this.value.replace(/[^a-zA-Z0-9 ]/g, '');
|
||||
if (cleaned !== this.value) {
|
||||
this.value = cleaned;
|
||||
this.setSelectionRange(pos - 1, pos - 1);
|
||||
}
|
||||
});
|
||||
|
||||
input.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
saveNickAndStart(input.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("orientationchange", function() {
|
||||
// Chrome на Android обновляет innerWidth/Height не мгновенно.
|
||||
// Ждем завершения анимации поворота.
|
||||
setTimeout(() => {
|
||||
// В Emscripten это вызовет ваш onWindowResized в C++
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 200);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+95
-53
@@ -27,6 +27,8 @@ add_executable(ShadowOverBishkekDemo WIN32
|
||||
../src/Localization.h
|
||||
../src/render/Renderer.cpp
|
||||
../src/render/Renderer.h
|
||||
../src/render/PathVisualization.cpp
|
||||
../src/render/PathVisualization.h
|
||||
../src/render/ShaderManager.cpp
|
||||
../src/render/ShaderManager.h
|
||||
../src/render/TextureManager.cpp
|
||||
@@ -79,6 +81,7 @@ add_executable(ShadowOverBishkekDemo WIN32
|
||||
../src/items/Item.cpp
|
||||
../src/items/ItemRegistry.h
|
||||
../src/items/ItemRegistry.cpp
|
||||
../src/Campaign.cpp
|
||||
../src/items/InteractiveObject.h
|
||||
../src/items/InteractiveObject.cpp
|
||||
../src/items/InteractiveObjectState.h
|
||||
@@ -104,6 +107,7 @@ add_executable(ShadowOverBishkekDemo WIN32
|
||||
../src/cutscene/CutsceneOverlay.h
|
||||
../src/cutscene/CutsceneOverlay.cpp
|
||||
../src/render/UiQuad.h
|
||||
app.rc
|
||||
)
|
||||
|
||||
# Установка проекта по умолчанию для Visual Studio
|
||||
@@ -118,15 +122,10 @@ set_target_properties(ShadowOverBishkekDemo PROPERTIES
|
||||
OUTPUT_NAME "ShadowOverBishkekDemo"
|
||||
)
|
||||
|
||||
# Определения препроцессора:
|
||||
# PNG_ENABLED – включает код PNG в TextureManager
|
||||
# SDL_MAIN_HANDLED – отключает переопределение main -> SDL_main
|
||||
# Определения препроцессора
|
||||
target_compile_definitions(ShadowOverBishkekDemo PRIVATE
|
||||
WIN32_LEAN_AND_MEAN
|
||||
PNG_ENABLED
|
||||
# SDL_MAIN_HANDLED
|
||||
# DEBUG_LIGHT
|
||||
# SHOW_PATH
|
||||
)
|
||||
|
||||
# Линкуем с SDL2main, если он вообще установлен
|
||||
@@ -157,18 +156,15 @@ endif()
|
||||
if(STEAMSDK)
|
||||
message(STATUS "Steamworks SDK integration is ENABLED.")
|
||||
|
||||
# Макрос STEAMSDK для условной компиляции в C++ коде (#ifdef STEAMSDK)
|
||||
target_compile_definitions(ShadowOverBishkekDemo PRIVATE STEAMSDK)
|
||||
|
||||
set(STEAM_SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/steamworks_sdk_164/sdk")
|
||||
|
||||
# Подключение заголовочных файлов Steamworks
|
||||
target_include_directories(ShadowOverBishkekDemo PRIVATE
|
||||
"${STEAM_SDK_DIR}/public"
|
||||
"${STEAM_SDK_DIR}/public/steam"
|
||||
)
|
||||
|
||||
# Определение разрядности сборки (x86 vs x64) для выбора версий lib и dll
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(STEAM_LIB_DIR "${STEAM_SDK_DIR}/redistributable_bin/win64")
|
||||
set(STEAM_LIB_NAME "steam_api64")
|
||||
@@ -179,7 +175,6 @@ if(STEAMSDK)
|
||||
set(STEAM_DLL_NAME "steam_api.dll")
|
||||
endif()
|
||||
|
||||
# Поиск библиотеки линковки (.lib)
|
||||
find_library(STEAM_LIBRARY
|
||||
NAMES ${STEAM_LIB_NAME}
|
||||
PATHS ${STEAM_LIB_DIR}
|
||||
@@ -193,22 +188,18 @@ if(STEAMSDK)
|
||||
message(FATAL_ERROR "Steam API library (${STEAM_LIB_NAME}) NOT found in ${STEAM_LIB_DIR}!")
|
||||
endif()
|
||||
|
||||
# Генерация временного файла steam_appid.txt с ID демо-версии (4945840)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/steam_appid.txt" "4945840")
|
||||
else()
|
||||
message(STATUS "Steamworks SDK integration is DISABLED.")
|
||||
endif()
|
||||
|
||||
# ===========================================
|
||||
# Копирование SDL2d.dll и zlibd.dll рядом с exe
|
||||
# Копирование DLL и ресурсов для локального запуска в Visual Studio
|
||||
# ===========================================
|
||||
if (WIN32)
|
||||
|
||||
# SDL2: в Debug - SDL2d.dll, в Release - SDL2.dll
|
||||
set(SDL2_DLL_SRC "$<IF:$<CONFIG:Debug>,${SDL2_INSTALL_DIR}/bin/SDL2d.dll,${SDL2_INSTALL_DIR}/bin/SDL2.dll>")
|
||||
set(SDL2_DLL_DST "$<IF:$<CONFIG:Debug>,$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/SDL2d.dll,$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/SDL2.dll>")
|
||||
|
||||
|
||||
set(LIBZIP_DLL_SRC "$<IF:$<CONFIG:Debug>,${LIBZIP_BASE_DIR}-Debug/bin/zip.dll,${LIBZIP_BASE_DIR}-Release/bin/zip.dll>")
|
||||
|
||||
set(ZLIB_DLL_SRC "$<IF:$<CONFIG:Debug>,${ZLIB_INSTALL_DIR}/bin/zd.dll,${ZLIB_INSTALL_DIR}/bin/z.dll>")
|
||||
@@ -216,47 +207,26 @@ if (WIN32)
|
||||
|
||||
set(SDL2TTF_DLL_SRC "$<IF:$<CONFIG:Debug>,${SDL2TTF_BASE_DIR}-Debug/bin/SDL2_ttfd.dll,${SDL2TTF_BASE_DIR}-Release/bin/SDL2_ttf.dll>")
|
||||
|
||||
set(SDL2MIXER_DLL_SRC "$<IF:$<CONFIG:Debug>,${SDL2MIXER_BASE_DIR}-Debug/bin/SDL2_mixerd.dll,${SDL2MIXER_BASE_DIR}-Release/bin/SDL2_mixer.dll>")
|
||||
|
||||
add_custom_command(TARGET ShadowOverBishkekDemo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying DLLs to output folder..."
|
||||
|
||||
# Копируем SDL2
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${SDL2_DLL_SRC}"
|
||||
"${SDL2_DLL_DST}"
|
||||
|
||||
# Копируем LIBZIP (целевое имя всегда zip.dll)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${LIBZIP_DLL_SRC}"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/zip.dll"
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${ZLIB_DLL_SRC}"
|
||||
"${ZLIB_DLL_DST}"
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${SDL2TTF_DLL_SRC}"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>"
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2_DLL_SRC}" "${SDL2_DLL_DST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LIBZIP_DLL_SRC}" "$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/zip.dll"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ZLIB_DLL_SRC}" "${ZLIB_DLL_DST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2TTF_DLL_SRC}" "$<TARGET_FILE_DIR:ShadowOverBishkekDemo>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/SDL_mixer-release-2.8.0/install-$<CONFIG>/bin/SDL2_mixer$<$<CONFIG:Debug>:d>.dll"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/SDL2_mixer$<$<CONFIG:Debug>:d>.dll"
|
||||
)
|
||||
|
||||
# Если включен Steam, добавляем шаги копирования DLL и appid в этот же POST_BUILD
|
||||
if(STEAMSDK)
|
||||
add_custom_command(TARGET ShadowOverBishkekDemo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying Steam SDK components..."
|
||||
# Копирование dll к исполняемому файлу
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${STEAM_LIB_DIR}/${STEAM_DLL_NAME}"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/${STEAM_DLL_NAME}"
|
||||
# Копирование steam_appid.txt к исполняемому файлу
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/steam_appid.txt"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/steam_appid.txt"
|
||||
# Дублируем steam_appid.txt в корень сборки (полезно при отладке прямо из MSVC)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/steam_appid.txt"
|
||||
"${CMAKE_BINARY_DIR}/steam_appid.txt"
|
||||
@@ -264,27 +234,99 @@ if (WIN32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ===========================================
|
||||
# Копирование ресурсов после сборки
|
||||
# ===========================================
|
||||
|
||||
# Какие папки с ресурсами нужно копировать
|
||||
set(RUNTIME_RESOURCE_DIRS
|
||||
"resources"
|
||||
"audio"
|
||||
)
|
||||
|
||||
# Копируем ресурсы и шейдеры в папку exe и в корень build/
|
||||
# Копирование ресурсов локально
|
||||
set(RUNTIME_RESOURCE_DIRS "resources" "music")
|
||||
foreach(resdir IN LISTS RUNTIME_RESOURCE_DIRS)
|
||||
add_custom_command(TARGET ShadowOverBishkekDemo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying ${resdir} to runtime folders..."
|
||||
# 1) туда, где лежит exe (build/Debug, build/Release и т.п.)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/../${resdir}"
|
||||
"$<TARGET_FILE_DIR:ShadowOverBishkekDemo>/${resdir}"
|
||||
# 2) в корень build, если захочешь запускать из этой папки
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/../${resdir}"
|
||||
"${CMAKE_BINARY_DIR}/${resdir}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# ===========================================
|
||||
# ПРАВИЛА ИНСТАЛЛЯЦИИ (Для CPack и создания пакетов)
|
||||
# ===========================================
|
||||
|
||||
# 1. Основной исполняемый файл
|
||||
install(TARGETS ShadowOverBishkekDemo DESTINATION .)
|
||||
|
||||
# 2. Необходимые DLL
|
||||
if(WIN32)
|
||||
install(FILES
|
||||
"${SDL2_INSTALL_DIR}/bin/SDL2.dll"
|
||||
"${LIBZIP_BASE_DIR}-Release/bin/zip.dll"
|
||||
"${ZLIB_INSTALL_DIR}/bin/z.dll"
|
||||
"${SDL2TTF_BASE_DIR}-Release/bin/SDL2_ttf.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/SDL_mixer-release-2.8.0/install-Release/bin/SDL2_mixer.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/concrt140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140_1.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140_2.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140_atomic_wait.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140_clr0400.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140_codecvt_ids.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/msvcp140d.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/OpenAL32.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcamp140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vccorlib140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcomp140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcruntime140.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcruntime140_1.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcruntime140_1_clr0400.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/vcruntime140_threads.dll"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dist_dlls/wrap_oal.dll"
|
||||
DESTINATION .
|
||||
)
|
||||
|
||||
if(STEAMSDK)
|
||||
install(FILES
|
||||
"${STEAM_LIB_DIR}/${STEAM_DLL_NAME}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/steam_appid.txt"
|
||||
DESTINATION .
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 3. Директории с ресурсами
|
||||
foreach(resdir IN LISTS RUNTIME_RESOURCE_DIRS)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/../${resdir}" DESTINATION .)
|
||||
endforeach()
|
||||
|
||||
# ===========================================
|
||||
# НАСТРОЙКА CPACK (Создание ZIP Portable и NSIS Installer)
|
||||
# ===========================================
|
||||
set(CPACK_PACKAGE_NAME "ShadowOverBishkekDemo")
|
||||
set(CPACK_PACKAGE_VENDOR "Fish Run Games")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Shadow Over Bishkek Demo Version")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "1")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "0")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "5")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Fish Run Games/Shadow Over Bishkek Demo")
|
||||
|
||||
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
|
||||
|
||||
# Настройки NSIS инсталлятора
|
||||
set(CPACK_NSIS_DISPLAY_NAME "Shadow Over Bishkek Demo")
|
||||
set(CPACK_NSIS_PACKAGE_NAME "Shadow Over Bishkek Demo")
|
||||
set(CPACK_NSIS_HELP_LINK "https://fishrungames.com/contact.html")
|
||||
set(CPACK_NSIS_URL_INFO_ABOUT "https://shadowoverbishkek.com/")
|
||||
set(CPACK_NSIS_MODIFY_PATH OFF)
|
||||
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
||||
|
||||
# Иконки и ярлыки в меню Пуск и на Рабочем столе
|
||||
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icon.ico")
|
||||
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/icon.ico")
|
||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA
|
||||
"CreateShortCut '$DESKTOP\\\\Shadow Over Bishkek Demo.lnk' '$INSTDIR\\\\ShadowOverBishkekDemo.exe'"
|
||||
)
|
||||
|
||||
# Форматы генераторов: ZIP (Portable) и NSIS (Установщик)
|
||||
set(CPACK_GENERATOR "ZIP;NSIS")
|
||||
|
||||
include(CPack)
|
||||
@@ -0,0 +1,21 @@
|
||||
END USER LICENSE AGREEMENT (EULA)
|
||||
|
||||
Game: Shadow Over Bishkek (Demo Version)
|
||||
Developer: Fish Run Games
|
||||
|
||||
1. GRANT OF LICENSE
|
||||
Fish Run Games grants you a non-exclusive, non-transferable, limited license to download, install, and play the Shadow Over Bishkek Demo for personal, non-commercial entertainment purposes.
|
||||
|
||||
2. OWNERSHIP & INTELLECTUAL PROPERTY
|
||||
The game, including all code, graphics, audio, characters, storyline, and assets, is the intellectual property of Fish Run Games and is protected by copyright and other intellectual property laws. You may not reverse engineer, decompile, modify, or redistribute the software without express written permission.
|
||||
|
||||
3. DISCLAIMER OF WARRANTY
|
||||
THIS 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.
|
||||
|
||||
4. USER DATA AND SAVES
|
||||
Save files and local configuration options are stored locally on your device. Fish Run Games is not responsible for any loss of save data resulting from software updates, system crashes, or uninstallation.
|
||||
|
||||
5. TERMINATION
|
||||
This license is effective until terminated. Your rights under this license will terminate automatically without notice from Fish Run Games if you fail to comply with any term(s) of this agreement.
|
||||
|
||||
Copyright (c) 2026 Fish Run Games. All rights reserved.
|
||||
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON "icon.ico"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"campaigns": [
|
||||
{
|
||||
"id": "main",
|
||||
"title": { "ru": "Основная игра", "en": "Main Game" },
|
||||
"locations": [
|
||||
"resources/config/locations/location_dorm.json",
|
||||
"resources/config/locations/uni_exterior.json",
|
||||
"resources/config/locations/uni_interior.json"
|
||||
],
|
||||
"startLocation": "location_dorm",
|
||||
"startMusic": "music/obshaga.ogg",
|
||||
"startState": "resources/config/start_state.json",
|
||||
"quests": "resources/config/quests.json",
|
||||
"tutorial": true,
|
||||
"loadingScreen": "resources/w/ui/screen_loading.json"
|
||||
},
|
||||
{
|
||||
"id": "battle_zone",
|
||||
"title": { "ru": "Зона боя", "en": "Battle Zone" },
|
||||
"locations": [
|
||||
"resources/config/locations/battle_zone_uni_exterior.json"
|
||||
],
|
||||
"startLocation": "uni_exterior",
|
||||
"startMusic": "music/bishkek univer day.ogg",
|
||||
"startState": "resources/config/start_state_battle_zone.json",
|
||||
"quests": "resources/config/quests_battle_zone.json",
|
||||
"tutorial": false,
|
||||
"loadingScreen": "resources/w/ui/screen_loading.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "uni_exterior",
|
||||
"gameObjects": "resources/w/shelter/game_objects.json",
|
||||
"interactiveObjects": "resources/w/shelter/interactive_objects.json",
|
||||
"npcs": "resources/config/npcs_battle_zone.json",
|
||||
"dialogues": "resources/dialogue/battle_zone_dialogues.json",
|
||||
"navigation": [
|
||||
"resources/navigation/dorm0_large.json"
|
||||
],
|
||||
"script": "resources/start_battle_zone.lua",
|
||||
"playerPosition": [-6, 0, 12.8]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"id": "location_dorm",
|
||||
"gameObjects": "resources/config/gameobjects_dorm_new_x.json",
|
||||
"interactiveObjects": "resources/config/interactive_objects_dorm_x.json",
|
||||
"npcs": "resources/config/npcs_dorm.json",
|
||||
"dialogues": "resources/dialogue/dorm_dialogues004.json",
|
||||
"navigation": [
|
||||
"resources/navigation/dorm3_bca.txt",
|
||||
"resources/navigation/dorm3_ca.txt",
|
||||
"resources/navigation/dorm3_ba.txt",
|
||||
"resources/navigation/dorm3_a.txt",
|
||||
"resources/navigation/dorm3_b.txt",
|
||||
"resources/navigation/dorm3_all_open.txt"
|
||||
],
|
||||
"script": "resources/start_dorm.lua",
|
||||
"teleports": "resources/config/teleports_dorm.json",
|
||||
"triggerZones": "resources/config/trigger_zones_dorm.json",
|
||||
"lights": "resources/config/lights_dorm.json",
|
||||
"playerPosition": [6.76345, 0, -14.6022],
|
||||
"taxi": {
|
||||
"triggerPosition": [-19.0, 0, 0],
|
||||
"waypoints": [
|
||||
[-20.85, 0, 30.0],
|
||||
[-19.35, 0, 24.0],
|
||||
[-19.35, 0, 14.0]
|
||||
],
|
||||
"initialPosition": [-20.85, 0, 64],
|
||||
"initialRotation": 0,
|
||||
"waypointReachRadius": 5
|
||||
},
|
||||
"lockInteractiveObjectsDuringTutorial": true
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"id": "uni_exterior",
|
||||
"gameObjects": "resources/config/gameobjects_uni_exterior_x.json",
|
||||
"interactiveObjects": "resources/config/interactive_objects_uni_exterior_x.json",
|
||||
"npcs": "resources/config/npcs_uni_exterior.json",
|
||||
"dialogues": "resources/dialogue/uni_exterior_dialogues003.json",
|
||||
"navigation": [
|
||||
"resources/navigation/uni_exterior3_trees_car.txt",
|
||||
"resources/navigation/uni_exterior3_trees.txt"
|
||||
],
|
||||
"script": "resources/start_uni_exterior.lua",
|
||||
"teleports": "resources/config/teleports_uni_exterior.json",
|
||||
"triggerZones": "resources/config/trigger_zones_uni_exterior.json",
|
||||
"lights": "resources/config/lights_uni_exterior.json",
|
||||
"playerPosition": [5, 0, -18.4],
|
||||
"taxi": {
|
||||
"triggerPosition": [-17.6, 0.05, -45],
|
||||
"waypoints": [
|
||||
[-17.6, 0.05, -90.0],
|
||||
[-17.6, 0.05, -75.0],
|
||||
[-17.6, 0.05, -55.0]
|
||||
],
|
||||
"initialPosition": [-17.6, 0.05, -100],
|
||||
"initialRotation": 180,
|
||||
"waypointReachRadius": 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"id": "uni_interior",
|
||||
"gameObjects": "resources/config/gameobjects_uni_interior_x.json",
|
||||
"interactiveObjects": "resources/config/interactive_objects_uni_interior_x.json",
|
||||
"npcs": "resources/config/npcs_uni_interior.json",
|
||||
"dialogues": "resources/dialogue/uni_interior_dialogues_010.json",
|
||||
"navigation": [
|
||||
"resources/navigation/uni_interior4_unlocked_n2.txt",
|
||||
"resources/navigation/uni_interior3_n2_hall.txt",
|
||||
"resources/navigation/uni_interior4_n2_lr_hall.txt",
|
||||
"resources/navigation/uni_interior4_n2_lr_tr_hall.txt",
|
||||
"resources/navigation/uni_interior3_n2_lr_tr_hall_aiperi.txt",
|
||||
"resources/navigation/uni_interior3_darklands_all_open.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_hall.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_n3.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s1.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s2.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3_s1.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3_hall.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3_n3.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3_n2.txt",
|
||||
"resources/navigation/uni_interior4_unlocked_s3_s2.txt",
|
||||
"resources/navigation/uni_interior4_locked.txt"
|
||||
],
|
||||
"script": "resources/start_uni_interior.lua",
|
||||
"teleports": "resources/config/teleports_uni_interior.json",
|
||||
"triggerZones": "resources/config/trigger_zones_uni_interior.json",
|
||||
"lights": "resources/config/lights_uni_interior.json",
|
||||
"playerPosition": [0.942694, 0, -9.63104]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"npcs": [
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"quests": [
|
||||
]
|
||||
}
|
||||
@@ -530,8 +530,7 @@
|
||||
"z": 14.0
|
||||
}
|
||||
]
|
||||
},
|
||||
"tutorialInteractiveObjectsLocked": true
|
||||
}
|
||||
},
|
||||
"npcStates": [
|
||||
{
|
||||
@@ -737,8 +736,7 @@
|
||||
"z": -55.0
|
||||
}
|
||||
]
|
||||
},
|
||||
"tutorialInteractiveObjectsLocked": false
|
||||
}
|
||||
},
|
||||
"npcStates": [],
|
||||
"playerState": {
|
||||
@@ -1122,12 +1120,11 @@
|
||||
"waypointReachRadius": 3.0,
|
||||
"waypoints": []
|
||||
},
|
||||
"taxiCarTriggerPositionX": -1.7014118346046923e+38,
|
||||
"taxiCarTriggerPositionY": -1.7014118346046923e+38,
|
||||
"taxiCarTriggerPositionZ": -1.7014118346046923e+38,
|
||||
"taxiCarTriggerPositionX": 0.0,
|
||||
"taxiCarTriggerPositionY": 0.0,
|
||||
"taxiCarTriggerPositionZ": 0.0,
|
||||
"taxiDefaultWaypoints": []
|
||||
},
|
||||
"tutorialInteractiveObjectsLocked": false
|
||||
}
|
||||
},
|
||||
"npcStates": [
|
||||
{
|
||||
@@ -1476,7 +1473,6 @@
|
||||
"morning_can_open_door_index": 0,
|
||||
"morning_did_open_door_index": 0,
|
||||
"player_hold_book": false,
|
||||
"player_hold_knife": false,
|
||||
"teacher_arrived_to_library": false,
|
||||
"teacher_door_opened": false,
|
||||
"teacher_told_about_book": false,
|
||||
@@ -1652,13 +1648,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"savedAt": "2026-07-14 14:00",
|
||||
"savedAt": "2026-07-24 23:40",
|
||||
"taxiIsCalled": false,
|
||||
"tutorialJournalPickedUp": false,
|
||||
"tutorialJournalScreenOpened": false,
|
||||
"tutorialNeedOpenTaxiScreen": false,
|
||||
"tutorialPhoneChatScreenOpened": false,
|
||||
"tutorialPhonePickedUp": false,
|
||||
"tutorialStep": 0,
|
||||
"uniIntTutorialState": 0
|
||||
"tutorialStep": 0
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"campaignId": "battle_zone",
|
||||
"chatHistory": [
|
||||
[],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
"chatPreviewMsg": [
|
||||
"",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"chatUnread": [
|
||||
true,
|
||||
true,
|
||||
true
|
||||
],
|
||||
"currentLocationName": "uni_exterior",
|
||||
"globalFloats": {
|
||||
"player_hp": 200.0
|
||||
},
|
||||
"globalInts": {},
|
||||
"inventory": {
|
||||
"items": []
|
||||
},
|
||||
"isDarklands": false,
|
||||
"isDawn": false,
|
||||
"isNight": false,
|
||||
"locations": {
|
||||
"uni_exterior": {
|
||||
"dialogueState": {
|
||||
"active": false
|
||||
},
|
||||
"interactiveObjectStates": [],
|
||||
"locationState": {
|
||||
"activeNavigationIndex": 0,
|
||||
"cameraAzimuth": -2.3499999046325684,
|
||||
"cameraInclination": 1.103600025177002,
|
||||
"isDarklands": false,
|
||||
"isDawn": false,
|
||||
"isNight": false,
|
||||
"targetInteractNpcIndex": -1,
|
||||
"targetInteractiveObjectIndex": -1,
|
||||
"targetTeleportZoneIndex": -1,
|
||||
"taxi": {
|
||||
"taxiArrivedCallbackCalled": false,
|
||||
"taxiCar": {
|
||||
"currentWaypoint": 0,
|
||||
"mode": 1,
|
||||
"positionX": -100.0,
|
||||
"positionY": -100.0,
|
||||
"positionZ": -100.0,
|
||||
"rotation": 0.0,
|
||||
"steeringAngle": 0.0,
|
||||
"velocity": 0.0,
|
||||
"waypointReachRadius": 3.0,
|
||||
"waypoints": []
|
||||
},
|
||||
"taxiCarInitialState": {
|
||||
"currentWaypoint": 0,
|
||||
"mode": 1,
|
||||
"positionX": -100.0,
|
||||
"positionY": -100.0,
|
||||
"positionZ": -100.0,
|
||||
"rotation": 0.0,
|
||||
"steeringAngle": 0.0,
|
||||
"velocity": 0.0,
|
||||
"waypointReachRadius": 3.0,
|
||||
"waypoints": []
|
||||
},
|
||||
"taxiCarTriggerPositionX": 0.0,
|
||||
"taxiCarTriggerPositionY": 0.0,
|
||||
"taxiCarTriggerPositionZ": 0.0,
|
||||
"taxiDefaultWaypoints": []
|
||||
}
|
||||
},
|
||||
"npcStates": [],
|
||||
"playerState": {
|
||||
"attackTargetIndex": -1,
|
||||
"attack_cooldown": 0.0,
|
||||
"battle_state": 0,
|
||||
"currentState": 0,
|
||||
"currentWaypointIndex": 0,
|
||||
"enabled": true,
|
||||
"faceTargetIndex": -1,
|
||||
"facingAngle": 0.0,
|
||||
"homeDriftCheckTimer": 5.0,
|
||||
"homePosition": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"hp": 200.0,
|
||||
"pathWaypoints": [],
|
||||
"position": [
|
||||
-6, 0, 12.8
|
||||
],
|
||||
"requestedWalkTarget": [
|
||||
-6, 0, 12.8
|
||||
],
|
||||
"showWeapon": true,
|
||||
"targetFacingAngle": 0.0,
|
||||
"visibleRange": 6.0,
|
||||
"walkTarget": [
|
||||
-6, 0, 12.8
|
||||
]
|
||||
},
|
||||
"scriptGlobals": null,
|
||||
"teleportZoneState": {},
|
||||
"triggerZoneState": {}
|
||||
}
|
||||
},
|
||||
"money": 5500,
|
||||
"playerHp": 200.0,
|
||||
"playerMaxHp": 200.0,
|
||||
"questJournal": {
|
||||
"quests": []
|
||||
},
|
||||
"savedAt": "2026-07-24 23:40",
|
||||
"taxiIsCalled": false,
|
||||
"tutorialJournalScreenOpened": false,
|
||||
"tutorialNeedOpenTaxiScreen": false,
|
||||
"tutorialPhoneChatScreenOpened": false,
|
||||
"tutorialStep": 9
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"dialogues": [
|
||||
]
|
||||
}
|
||||
@@ -2276,14 +2276,14 @@
|
||||
"en": "And maybe she will even give me some difficult assignment."
|
||||
},
|
||||
{
|
||||
"key": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"ru": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"en": "I'm even sure she's looking for me. She wants to give me some kind of assignment."
|
||||
"key": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"ru": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"en": "I'm sure she's looking for me. She wants to give me some kind of assignment."
|
||||
},
|
||||
{
|
||||
"key": "Пока ты не принесешь мне нож из учительской, никуда я тебя не выпущу. Ошо!",
|
||||
"ru": "Пока ты не принесешь мне нож из учительской, никуда я тебя не выпущу. Ошо!",
|
||||
"en": "Until you bring me a knife from the teachers' room, I won't let you go anywhere."
|
||||
"en": "Until you bring me a knife from the teachers' room, I won't let you go anywhere. Osho!"
|
||||
},
|
||||
{
|
||||
"key": "Я слышала она не смогла сдать курсовую по манасоведению.",
|
||||
@@ -2293,7 +2293,7 @@
|
||||
{
|
||||
"key": "Она прыгнула с окна и разбилась насмерть деп.",
|
||||
"ru": "Она прыгнула с окна и разбилась насмерть деп.",
|
||||
"en": "She jumped from the window and fell to her death, they said."
|
||||
"en": "She jumped from the window and fell to her death, dep."
|
||||
},
|
||||
{
|
||||
"key": "Да она надоела, все время скафнит.",
|
||||
@@ -2308,7 +2308,7 @@
|
||||
{
|
||||
"key": "Так что жду тебя в универе! Не вздумай прогулять! Ошо!",
|
||||
"ru": "Так что жду тебя в универе! Не вздумай прогулять! Ошо!",
|
||||
"en": "So I'm waiting for you at the university! Don't even think about skipping!"
|
||||
"en": "So I'm waiting for you at the university! Don't even think about skipping! Osho!"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -293,14 +293,6 @@
|
||||
"speaker": "Бекзат",
|
||||
"portrait": "resources/dialogue/portrait_hero_neutral.png",
|
||||
"text": "Почему?",
|
||||
"next": "line_30"
|
||||
},
|
||||
{
|
||||
"id": "line_30",
|
||||
"type": "Line",
|
||||
"speaker": "Айпери",
|
||||
"portrait": "resources/dialogue/portrait_aiperi.png",
|
||||
"text": "Она опять будет скафнить.",
|
||||
"next": "line_25"
|
||||
},
|
||||
{
|
||||
@@ -308,7 +300,7 @@
|
||||
"type": "Line",
|
||||
"speaker": "Айпери",
|
||||
"portrait": "resources/dialogue/portrait_aiperi.png",
|
||||
"text": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"text": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||
"next": "line_26"
|
||||
},
|
||||
{
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,11 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
varying vec2 texCoord;
|
||||
varying float fogDistance;
|
||||
|
||||
@@ -9,8 +15,12 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
#ifdef INSTANCED
|
||||
worldPos = mat4(iModel0, iModel1, iModel2, iModel3) * worldPos;
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
varying vec2 texCoord;
|
||||
varying float fogDistance;
|
||||
|
||||
@@ -9,8 +15,12 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
#ifdef INSTANCED
|
||||
worldPos = mat4(iModel0, iModel1, iModel2, iModel3) * worldPos;
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
}
|
||||
@@ -2,6 +2,12 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying vec4 fragPosLightSpace;
|
||||
@@ -15,10 +21,17 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragPosLightSpace = uLightFromCamera * eyePos;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying vec4 fragPosLightSpace;
|
||||
@@ -14,10 +20,17 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragPosLightSpace = uLightFromCamera * eyePos;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
}
|
||||
@@ -2,6 +2,12 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying float fogDistance;
|
||||
@@ -15,11 +21,18 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragViewPos = eyePos.xyz;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragWorldXZ = vPosition.xz;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
fragWorldXZ = worldPos.xz;
|
||||
}
|
||||
@@ -2,6 +2,12 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying vec4 fragPosLightSpace;
|
||||
@@ -17,12 +23,19 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragViewPos = eyePos.xyz;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
fragPosLightSpace = uLightFromCamera * eyePos;
|
||||
fragWorldXZ = vPosition.xz;
|
||||
fragWorldXZ = worldPos.xz;
|
||||
}
|
||||
@@ -2,6 +2,12 @@ precision highp float;
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying vec4 fragPosLightSpace;
|
||||
@@ -17,12 +23,19 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragViewPos = eyePos.xyz;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
fragPosLightSpace = uLightFromCamera * eyePos;
|
||||
fragWorldXZ = vPosition.xz;
|
||||
fragWorldXZ = worldPos.xz;
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
varying vec2 texCoord;
|
||||
varying float fogDistance;
|
||||
@@ -14,11 +20,18 @@ uniform vec3 uPlayerEyePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 eyePos = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
vec3 normal = vNormal;
|
||||
#ifdef INSTANCED
|
||||
mat4 instanceModel = mat4(iModel0, iModel1, iModel2, iModel3);
|
||||
worldPos = instanceModel * worldPos;
|
||||
normal = normalize(mat3(instanceModel) * normal);
|
||||
#endif
|
||||
vec4 eyePos = ModelViewMatrix * worldPos;
|
||||
fogDistance = length(eyePos.xyz - uPlayerEyePos);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
texCoord = vTexCoord;
|
||||
fragViewPos = eyePos.xyz;
|
||||
fragNormal = mat3(ModelViewMatrix) * vNormal;
|
||||
fragWorldXZ = vPosition.xz;
|
||||
fragNormal = mat3(ModelViewMatrix) * normal;
|
||||
fragWorldXZ = worldPos.xz;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
attribute vec3 vPosition;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
uniform vec4 uColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uColor;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform vec4 uColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uColor;
|
||||
}
|
||||
@@ -1,9 +1,19 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
#ifdef INSTANCED
|
||||
attribute vec4 iModel0;
|
||||
attribute vec4 iModel1;
|
||||
attribute vec4 iModel2;
|
||||
attribute vec4 iModel3;
|
||||
#endif
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
vec4 worldPos = vec4(vPosition, 1.0);
|
||||
#ifdef INSTANCED
|
||||
worldPos = mat4(iModel0, iModel1, iModel2, iModel3) * worldPos;
|
||||
#endif
|
||||
gl_Position = ProjectionModelViewMatrix * worldPos;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
-- ============================================
|
||||
-- BATTLE ZONE (campaign "battle_zone")
|
||||
-- uni_exterior level with static objects and navigation only.
|
||||
-- ============================================
|
||||
|
||||
function callback_enter_location()
|
||||
end
|
||||
|
||||
function callback_exit_location()
|
||||
end
|
||||
|
||||
game_api.set_location_callbacks(
|
||||
callback_enter_location,
|
||||
callback_exit_location
|
||||
)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 390 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user