Compare commits
239 Commits
Author | SHA1 | Date |
---|---|---|
Zeno Rogue | 7af403490a | |
Zeno Rogue | 2314eaba29 | |
Zeno Rogue | 5d34760290 | |
Zeno Rogue | 50d70097cb | |
Zeno Rogue | c16c064b21 | |
Zeno Rogue | 448397ab1d | |
Zeno Rogue | b482dabb84 | |
Zeno Rogue | 478be692de | |
Zeno Rogue | dda979ad14 | |
Zeno Rogue | 9485495e48 | |
Zeno Rogue | d4a610c2b6 | |
Zeno Rogue | 003ca36ee5 | |
Zeno Rogue | 9752cdede1 | |
Zeno Rogue | fbd2cc6b9d | |
Zeno Rogue | 5324d3d068 | |
Zeno Rogue | d34070f709 | |
Zeno Rogue | 5d576c3344 | |
Zeno Rogue | c6c040eead | |
Zeno Rogue | aec2463f2f | |
Zeno Rogue | ba44e111ca | |
Zeno Rogue | 43d1fd3db8 | |
Zeno Rogue | 727ae8a260 | |
Zeno Rogue | 99bc842c57 | |
Zeno Rogue | a9d6def718 | |
Zeno Rogue | 0d5723dd69 | |
Zeno Rogue | ab0ca74328 | |
Zeno Rogue | e66f071521 | |
Zeno Rogue | b7bfe746cb | |
Zeno Rogue | 093044ba83 | |
Zeno Rogue | 3c29b987ce | |
Zeno Rogue | a755f26075 | |
Zeno Rogue | c1bacb0695 | |
Zeno Rogue | e2c81eeae7 | |
Zeno Rogue | fcc3cae938 | |
Zeno Rogue | 3b3e9e2de6 | |
Zeno Rogue | 5901d9598d | |
Zeno Rogue | 6bf198946c | |
Zeno Rogue | a3261b21da | |
Zeno Rogue | 3da7e4c020 | |
Zeno Rogue | ce09e4910e | |
Zeno Rogue | 95d7ffee08 | |
Zeno Rogue | 82a7077019 | |
Zeno Rogue | 1cc90a6f76 | |
Zeno Rogue | 1323ec446a | |
Zeno Rogue | 8db11dc683 | |
Zeno Rogue | 502469a54a | |
Zeno Rogue | 0df75589ca | |
Zeno Rogue | 358554d60e | |
Zeno Rogue | c594aea40e | |
Zeno Rogue | 03c549b010 | |
Zeno Rogue | 937a291485 | |
Zeno Rogue | 0e09775669 | |
Zeno Rogue | 5c03f9c7fe | |
Zeno Rogue | 8321751cb0 | |
Zeno Rogue | bfacda7207 | |
Zeno Rogue | 4f761c70cb | |
Zeno Rogue | 3ca75bec8e | |
Zeno Rogue | 54443e365d | |
Zeno Rogue | 6ca2051c96 | |
Zeno Rogue | e5e89c4800 | |
Zeno Rogue | bb6df35bf2 | |
Zeno Rogue | ba05c94d7b | |
Zeno Rogue | 90c7f6e927 | |
Zeno Rogue | e6417951de | |
Zeno Rogue | f823a53f84 | |
Zeno Rogue | 83575d9d7d | |
Zeno Rogue | d381caba1f | |
Zeno Rogue | 78cd26f456 | |
Zeno Rogue | 96be05484a | |
Zeno Rogue | 4d57041c9f | |
Zeno Rogue | 5022b76d75 | |
Zeno Rogue | 8caf343390 | |
Zeno Rogue | 203c11f6e1 | |
Zeno Rogue | 322b21e999 | |
Zeno Rogue | f445d02707 | |
Zeno Rogue | 888a34dea6 | |
Zeno Rogue | a20158ab65 | |
Zeno Rogue | a703448144 | |
Zeno Rogue | 480916e4db | |
Zeno Rogue | 998a74800c | |
Zeno Rogue | f4796a10f4 | |
Zeno Rogue | aa4bf4d818 | |
Zeno Rogue | ff8bb20a55 | |
Zeno Rogue | 57691737f0 | |
Zeno Rogue | a4b9b9b0a5 | |
Zeno Rogue | 1c74774bfa | |
Zeno Rogue | a80a73458a | |
Zeno Rogue | d7bde6f175 | |
Zeno Rogue | 9f711627f1 | |
Zeno Rogue | 89763be7d2 | |
Zeno Rogue | 03b89f053b | |
Zeno Rogue | 441f825566 | |
Zeno Rogue | f2d8b4d95e | |
Zeno Rogue | 73dbccbb0e | |
Jacob Mandelson | efc2ce90e0 | |
Zeno Rogue | 7b3d2c2626 | |
Zeno Rogue | 126f45a714 | |
Jacob Mandelson | 11837d9614 | |
Zeno Rogue | 64569f1818 | |
Jacob Mandelson | cd2152ffad | |
Zeno Rogue | eee39b0340 | |
Zeno Rogue | 937c830571 | |
Zeno Rogue | 4ec627b1a1 | |
Zeno Rogue | 1a70e54e24 | |
Zeno Rogue | a70a9dc663 | |
Zeno Rogue | 879549ca5d | |
Zeno Rogue | 7982ea0e58 | |
Zeno Rogue | 7b99248c06 | |
Zeno Rogue | dc136cc937 | |
Jacob Mandelson | 3f78c11e6c | |
Jacob Mandelson | 1dd4da5135 | |
Jacob Mandelson | 601274e67a | |
Zeno Rogue | 7581ba887b | |
Zeno Rogue | 6b03aca3c0 | |
Zeno Rogue | 80df589bd2 | |
Zeno Rogue | 159b47e72a | |
Zeno Rogue | 9a33e63f53 | |
Zeno Rogue | 10184f9087 | |
Zeno Rogue | 6b0dd547bd | |
Zeno Rogue | 542e2520c1 | |
Zeno Rogue | f2d81746a7 | |
Zeno Rogue | a130fbbc50 | |
Zeno Rogue | 2097fde609 | |
Zeno Rogue | bc5e1d78c9 | |
Zeno Rogue | e324ae07f3 | |
Zeno Rogue | 215be1ea17 | |
Zeno Rogue | 53461e6c5a | |
Zeno Rogue | 7a81b6b0de | |
Zeno Rogue | 723422e137 | |
Zeno Rogue | 50881f519f | |
Zeno Rogue | df67249ec0 | |
Zeno Rogue | 0a9714e657 | |
Zeno Rogue | 5eb7cfc17a | |
Zeno Rogue | 000bfd4b97 | |
Zeno Rogue | 0b0ad4abe3 | |
Zeno Rogue | 305d546ae1 | |
Zeno Rogue | c369c08bc9 | |
Zeno Rogue | 52f9cc820b | |
Zeno Rogue | 4c81c0cc5d | |
Zeno Rogue | 51ecd882e1 | |
Zeno Rogue | 9ba9797068 | |
Zeno Rogue | ba972ea8d8 | |
Zeno Rogue | e4b0ebbd89 | |
Zeno Rogue | 35ddcf6fe1 | |
Zeno Rogue | 7c2aca91a4 | |
Zeno Rogue | 43702b82a1 | |
Zeno Rogue | 43a3e8f030 | |
Zeno Rogue | ce825db2c0 | |
Zeno Rogue | b8a7e6e093 | |
Zeno Rogue | 962efb3152 | |
Zeno Rogue | 84666ade8c | |
Zeno Rogue | 9aa15f96e1 | |
Zeno Rogue | bc22d17a16 | |
Zeno Rogue | d9a03ab1d3 | |
Zeno Rogue | 5ae3bc02d1 | |
Zeno Rogue | aafced83aa | |
Zeno Rogue | 33aacfa289 | |
Zeno Rogue | d074606cae | |
Zeno Rogue | 6aecf921bf | |
Zeno Rogue | fa99e83019 | |
Zeno Rogue | 1003808999 | |
Zeno Rogue | 5085853fb4 | |
Zeno Rogue | 9372ecb8f8 | |
Zeno Rogue | 690b2164db | |
Zeno Rogue | 16e3daeab5 | |
Zeno Rogue | 0a16e53561 | |
Zeno Rogue | 443be1acda | |
Zeno Rogue | ba9c41bed2 | |
Zeno Rogue | 329ad76c3c | |
Zeno Rogue | de20daf708 | |
Zeno Rogue | f229c489cd | |
Zeno Rogue | 1e3347590b | |
Zeno Rogue | fd1960191e | |
Zeno Rogue | 942fd9dafb | |
Zeno Rogue | f1e91a1614 | |
Zeno Rogue | e71ddf1140 | |
Zeno Rogue | a0ba84d70c | |
Zeno Rogue | 404b964f28 | |
Jacob Mandelson | b56d2d21bf | |
Zeno Rogue | 27fb2d92d7 | |
Zeno Rogue | ec9be47a83 | |
Jacob Mandelson | 14519dc258 | |
Jacob Mandelson | c3ef9c2733 | |
Jacob Mandelson | c29517b5b0 | |
Zeno Rogue | e91c11ffb7 | |
Zeno Rogue | 7d3d3a0869 | |
Tokarak | d0d4b24f91 | |
Tokarak | 2659d08b78 | |
Tokarak | 45db9977a0 | |
Tokarak | aa78aacdf3 | |
Tokarak | fd128d24c6 | |
Jacob Mandelson | d756224f8d | |
Zeno Rogue | fbea2d91ce | |
Zeno Rogue | d4f449d994 | |
Zeno Rogue | 9807b1b3ba | |
Zeno Rogue | 4d761385ac | |
Zeno Rogue | 05b6cdea3e | |
Zeno Rogue | 10646933db | |
Zeno Rogue | 521b452436 | |
Zeno Rogue | 0323e4100e | |
Zeno Rogue | 0708c0e2bc | |
Zeno Rogue | b7db56812e | |
Zeno Rogue | 7fc90f116b | |
Zeno Rogue | 824fa9a732 | |
Zeno Rogue | 92603dddcc | |
Zeno Rogue | 32d329d81e | |
Zeno Rogue | b9608dcd4c | |
Zeno Rogue | 977bd8ca9d | |
Zeno Rogue | 869c63cb88 | |
Zeno Rogue | 5377147b1a | |
Zeno Rogue | e83d38e267 | |
Zeno Rogue | 1fc02631c8 | |
Zeno Rogue | edff317759 | |
Jacob Mandelson | b8de8155da | |
Zeno Rogue | 9bc4e21f10 | |
Zeno Rogue | a328568ee5 | |
Zeno Rogue | 494fc4ec11 | |
Zeno Rogue | 6f7e5b4d6a | |
Zeno Rogue | ccea416237 | |
Zeno Rogue | 4a908273d0 | |
Zeno Rogue | 5efacd787d | |
Zeno Rogue | b07987b2f4 | |
Zeno Rogue | 84ada5184f | |
Zeno Rogue | 14b68f0b64 | |
Zeno Rogue | 960485ec8e | |
Zeno Rogue | e032e619c0 | |
Zeno Rogue | 57f6fb5f71 | |
Zeno Rogue | d2cd6fa2c1 | |
Zeno Rogue | 8a407f4505 | |
Zeno Rogue | 6abb82174e | |
Zeno Rogue | dea9fea67f | |
Zeno Rogue | d618b10889 | |
Zeno Rogue | d250abf1a4 | |
Zeno Rogue | 89563ebde9 | |
Zeno Rogue | 445c240c79 | |
Zeno Rogue | 15b711e099 | |
Zeno Rogue | 8002f42d71 | |
Zeno Rogue | 79f2940683 | |
Zeno Rogue | 0ec4e46bf0 |
|
@ -1,68 +0,0 @@
|
|||
name: Github CI on Android
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
android_build:
|
||||
name: Test build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Validate gradle-wrapper.jar
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install gcc libsdl1.2-dev libsdl-ttf2.0-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libglew-dev libpng-dev
|
||||
- name: Build
|
||||
run: |
|
||||
cd hyperroid
|
||||
./copy.sh
|
||||
./gradlew assembleDebug
|
||||
- name: Upload APK
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: hyperroid_debug
|
||||
path: hyperroid/app/build/outputs/apk/debug/app-debug.apk
|
||||
|
||||
android_test:
|
||||
needs: android_build
|
||||
name: Test-run in emulator
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Download APK
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: hyperroid_debug
|
||||
- name: Create a helper wait script
|
||||
run: |
|
||||
cat > wait-for-load.sh << ENDOFSCRIPT
|
||||
#!/bin/sh
|
||||
while ! adb logcat -d "HyperRogue:V" "*:S" | grep "Game initialized"
|
||||
do
|
||||
sleep 2
|
||||
done
|
||||
ENDOFSCRIPT
|
||||
chmod u+x wait-for-load.sh
|
||||
- name: Run in emulator
|
||||
uses: ReactiveCircus/android-emulator-runner@v2.11.1
|
||||
with:
|
||||
api-level: 28
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -no-snapstorage -noaudio -no-boot-anim -skin 1440x2560
|
||||
script: |
|
||||
adb wait-for-device
|
||||
adb install -t app-debug.apk
|
||||
adb shell am start -W -n com.roguetemple.hyperroid/com.roguetemple.hyperroid.HyperRogue
|
||||
./wait-for-load.sh
|
||||
adb shell input keyevent 41 # send "M" keypress to display main menu
|
||||
adb shell screencap /sdcard/hyperroid.png
|
||||
adb pull /sdcard/hyperroid.png
|
||||
- name: Upload screenshot
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: screenshot
|
||||
path: hyperroid.png
|
|
@ -13,7 +13,9 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
# os: [ubuntu-latest, macos-latest]
|
||||
# macos is broken for now
|
||||
os: [ubuntu-latest]
|
||||
compiler: [gcc, clang]
|
||||
build_system: [makefile, mymake]
|
||||
hyper_use_rviz: [rviz_1, rviz_0]
|
||||
|
@ -71,13 +73,15 @@ jobs:
|
|||
- name: Do a simple test
|
||||
run: .github/workflows/test_simple.sh
|
||||
|
||||
emscripten:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: |
|
||||
docker run --rm -v $(pwd):/src trzeci/emscripten make emscripten
|
||||
- name: Do a simple test
|
||||
run: |
|
||||
ls -lAF hyper.html hyper.js hyper.wasm
|
||||
# broken for now
|
||||
|
||||
# emscripten:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Build
|
||||
# run: |
|
||||
# docker run --rm -v $(pwd):/src trzeci/emscripten make emscripten
|
||||
# - name: Do a simple test
|
||||
# run: |
|
||||
# ls -lAF hyper.html hyper.js hyper.wasm
|
||||
|
|
|
@ -9,7 +9,9 @@ cat << ENDOFCMDS > .github/workflows/gdb_cmds.txt
|
|||
exit 1
|
||||
ENDOFCMDS
|
||||
|
||||
gdb --batch -x .github/workflows/gdb_cmds.txt ./hyperrogue
|
||||
echo not running gdb -- not working currently
|
||||
echo gdb --batch -x .github/workflows/gdb_cmds.txt ./hyperrogue
|
||||
|
||||
else
|
||||
./hyperrogue --version
|
||||
fi
|
||||
|
|
193
.travis.yml
193
.travis.yml
|
@ -1,193 +0,0 @@
|
|||
language: cpp
|
||||
dist: bionic
|
||||
services:
|
||||
- docker
|
||||
matrix:
|
||||
include:
|
||||
- os: linux # Linux GCC, make
|
||||
compiler: gcc
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=gcc
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
- os: linux # Linux GCC, make, no libpng
|
||||
compiler: gcc
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=gcc
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=0
|
||||
- os: linux # Linux GCC, make, Rogueviz
|
||||
compiler: gcc
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=gcc
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
HYPERROGUE_USE_ROGUEVIZ=1
|
||||
- os: linux # Linux Clang, make
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
- os: linux # Linux Clang, make, Rogueviz
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
HYPERROGUE_USE_ROGUEVIZ=1
|
||||
- os: osx # OSX, make
|
||||
osx_image: xcode12u
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=osx
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
- os: osx # OSX, make, no libpng
|
||||
osx_image: xcode11.6
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=osx
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=0
|
||||
- os: osx # OSX, make, Rogueviz
|
||||
osx_image: xcode11.5
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=osx
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=Makefile
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
HYPERROGUE_USE_ROGUEVIZ=1
|
||||
- os: linux # Linux GCC, mymake
|
||||
compiler: gcc
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=gcc
|
||||
TRAVIS_BUILD_SYSTEM=mymake
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
- os: linux # Linux GCC, mymake, Rogueviz
|
||||
compiler: gcc
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=gcc
|
||||
TRAVIS_BUILD_SYSTEM=mymake
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
HYPERROGUE_USE_ROGUEVIZ=1
|
||||
- os: osx # OSX, mymake
|
||||
osx_image: xcode11.4
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=osx
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=mymake
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
- os: osx # OSX, mymake, Rogueviz
|
||||
osx_image: xcode11.3
|
||||
compiler: clang
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=osx
|
||||
TRAVIS_COMPILER_NAME=clang
|
||||
TRAVIS_BUILD_SYSTEM=mymake
|
||||
HYPERROGUE_USE_GLEW=1
|
||||
HYPERROGUE_USE_PNG=1
|
||||
HYPERROGUE_USE_ROGUEVIZ=1
|
||||
- os: linux # Emscripten
|
||||
env: >-
|
||||
TRAVIS_OS_NAME=linux
|
||||
TRAVIS_COMPILER_NAME=emscripten
|
||||
TRAVIS_BUILD_SYSTEM=emscripten
|
||||
|
||||
before_install:
|
||||
- |-
|
||||
# Install SDL
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq libsdl1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew update
|
||||
brew install sdl sdl_gfx sdl_mixer sdl_ttf
|
||||
# work around https://stackoverflow.com/questions/51034399/ for now
|
||||
(cd /usr/local/include && ln -sf SDL/SDL.h)
|
||||
else
|
||||
exit 'Unsupported OS'
|
||||
fi
|
||||
- |-
|
||||
# Install GLEW if asked for
|
||||
if [[ "$HYPERROGUE_USE_GLEW" == "1" ]]; then
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
sudo apt-get install -qq libglew-dev
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew install glew
|
||||
else
|
||||
exit 'Unsupported OS'
|
||||
fi
|
||||
fi
|
||||
- |-
|
||||
# Install libpng if asked for
|
||||
if [[ "$HYPERROGUE_USE_PNG" == "1" ]]; then
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
echo 'libpng is installed by default'
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew install libpng
|
||||
else
|
||||
exit 'Unsupported OS'
|
||||
fi
|
||||
fi
|
||||
|
||||
script:
|
||||
- |-
|
||||
make clean
|
||||
if [[ "$(git status --porcelain)" ]]; then
|
||||
git status
|
||||
exit 'A build artifact was committed; git rm it and try again'
|
||||
fi
|
||||
- |-
|
||||
# Build hyperrogue.
|
||||
export CXXFLAGS_EARLY=-Werror
|
||||
if [[ "$TRAVIS_BUILD_SYSTEM" == "Makefile" ]]; then
|
||||
make
|
||||
elif [[ "$TRAVIS_BUILD_SYSTEM" == "mymake" ]]; then
|
||||
make mymake
|
||||
if [[ "$HYPERROGUE_USE_ROGUEVIZ" == "1" ]]; then
|
||||
./mymake -rv
|
||||
else
|
||||
./mymake
|
||||
fi
|
||||
mv hyper hyperrogue
|
||||
elif [[ "$TRAVIS_BUILD_SYSTEM" == "emscripten" ]]; then
|
||||
docker run --rm -v $(pwd):/src trzeci/emscripten make emscripten
|
||||
else
|
||||
exit 'Unsupported build system'
|
||||
fi
|
||||
- |-
|
||||
# Test hyperrogue.
|
||||
if [[ "$TRAVIS_BUILD_SYSTEM" == "emscripten" ]]; then
|
||||
ls -lAF hyper.html hyper.js hyper.wasm
|
||||
else
|
||||
./hyperrogue --help
|
||||
fi
|
||||
- |-
|
||||
make clean
|
||||
if [[ "$(git status --porcelain)" ]]; then
|
||||
git status
|
||||
exit 'make clean did not return the repository to its pre-build state'
|
||||
fi
|
39
Makefile
39
Makefile
|
@ -1,16 +1,24 @@
|
|||
# This Makefile works for Mac OS X (El Capitan), MinGW, and Linux.
|
||||
#
|
||||
# Environmental vairables:
|
||||
# If you want to build with Glew, set
|
||||
# HYPERROGUE_USE_GLEW=1
|
||||
# If you want to use libpng, set
|
||||
# HYPERROGUE_USE_PNG=1
|
||||
#
|
||||
# For Mac OS X:
|
||||
# Run "brew install sdl" to install SDL in /usr/local.
|
||||
# Run "brew install sdl_gfx".
|
||||
# Run "brew install sdl_mixer".
|
||||
# Run "brew install sdl_ttf".
|
||||
# Run "make" to build HyperRogue as ./hyperrogue.
|
||||
# Run `brew install sdl12-compat sdl_gfx sdl_mixer sdl_ttf`
|
||||
# Run `brew install glew libpng` to install the optional dependencies
|
||||
# Run `make` to build HyperRogue as `./hyperrogue`.
|
||||
#
|
||||
# For MSYS2 and MinGW-w64:
|
||||
# You might need to run commands such as "pacman -S mingw-w64-x86_64-SDL"
|
||||
# to install SDL and other required libraries.
|
||||
# Run "make" to build HyperRogue as ./hyperrogue.exe.
|
||||
# To install SDL and other required libraries, run these commands
|
||||
# from the MSYS2 shell:
|
||||
# pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-glew
|
||||
# pacman -S mingw-w64-ucrt-x86_64-SDL mingw-w64-ucrt-x86_64-SDL_mixer
|
||||
# pacman -S mingw-w64-ucrt-x86_64-SDL_ttf mingw-w64-ucrt-x86_64-SDL_gfx
|
||||
# pacman -S make
|
||||
# Then run "make" to build HyperRogue as ./hyperrogue.exe.
|
||||
#
|
||||
# For Ubuntu Linux:
|
||||
# Run "sudo apt-get install libsdl-dev" to install SDL in /usr/local.
|
||||
|
@ -54,7 +62,7 @@ ifeq (${OS},linux)
|
|||
endif
|
||||
|
||||
ifeq (${OS},mingw)
|
||||
CXXFLAGS_EARLY += -DWINDOWS -mwindows -D_A_VOLID=8
|
||||
CXXFLAGS_EARLY += -DWINDOWS -mwindows -D_A_VOLID=8 -I/ucrt64/include/SDL
|
||||
EXE_EXTENSION := .exe
|
||||
LDFLAGS_GL := -lopengl32
|
||||
LDFLAGS_GLEW := -lglew32
|
||||
|
@ -68,9 +76,10 @@ ifeq (${OS},mingw)
|
|||
endif
|
||||
|
||||
ifeq (${OS},osx)
|
||||
CXXFLAGS_EARLY += -DMAC -I/usr/local/include
|
||||
HOMEBREW_PREFIX := $(shell brew --prefix)
|
||||
CXXFLAGS_EARLY += -DMAC -I$(HOMEBREW_PREFIX)/include -I$(HOMEBREW_PREFIX)/include/SDL
|
||||
EXE_EXTENSION :=
|
||||
LDFLAGS_EARLY += -L/usr/local/lib
|
||||
LDFLAGS_EARLY += -L$(HOMEBREW_PREFIX)/lib
|
||||
LDFLAGS_GL := -framework AppKit -framework OpenGL
|
||||
LDFLAGS_GLEW := -lGLEW
|
||||
LDFLAGS_PNG := -lpng
|
||||
|
@ -80,7 +89,7 @@ ifeq (${OS},osx)
|
|||
endif
|
||||
|
||||
ifeq (${TOOLCHAIN},clang)
|
||||
CXXFLAGS_STD = -std=c++11
|
||||
CXXFLAGS_STD = -std=c++14
|
||||
CXXFLAGS_EARLY += -fPIC
|
||||
CXXFLAGS_EARLY += -W -Wall -Wextra -Wsuggest-override -pedantic
|
||||
CXXFLAGS_EARLY += -Wno-unused-parameter -Wno-implicit-fallthrough -Wno-maybe-uninitialized -Wno-char-subscripts -Wno-unknown-warning-option
|
||||
|
@ -88,7 +97,7 @@ ifeq (${TOOLCHAIN},clang)
|
|||
endif
|
||||
|
||||
ifeq (${TOOLCHAIN},gcc)
|
||||
CXXFLAGS_STD = -std=c++11
|
||||
CXXFLAGS_STD = -std=c++14
|
||||
CXXFLAGS_EARLY += -fPIC
|
||||
CXXFLAGS_EARLY += -W -Wall -Wextra -pedantic
|
||||
CXXFLAGS_EARLY += -Wno-unused-parameter -Wno-implicit-fallthrough -Wno-maybe-uninitialized
|
||||
|
@ -96,7 +105,7 @@ ifeq (${TOOLCHAIN},gcc)
|
|||
endif
|
||||
|
||||
ifeq (${TOOLCHAIN},mingw)
|
||||
CXXFLAGS_STD = -std=c++11
|
||||
CXXFLAGS_STD = -std=c++14
|
||||
CXXFLAGS_EARLY += -W -Wall -Wextra
|
||||
CXXFLAGS_EARLY += -Wno-unused-parameter -Wno-implicit-fallthrough -Wno-maybe-uninitialized
|
||||
CXXFLAGS_EARLY += -Wno-invalid-offsetof
|
||||
|
@ -173,7 +182,7 @@ mymake$(EXE_EXTENSION): mymake.cpp
|
|||
emscripten: hyper.html
|
||||
|
||||
%.html %.js %.wasm: %.emscripten-sources
|
||||
emcc -std=c++11 -O3 -s USE_ZLIB=1 -s LEGACY_GL_EMULATION=1 -s TOTAL_MEMORY=128MB hyperweb.cpp -o hyper.html
|
||||
emcc -std=c++14 -O3 -s USE_ZLIB=1 -s LEGACY_GL_EMULATION=1 -s TOTAL_MEMORY=128MB hyperweb.cpp -o hyper.html
|
||||
|
||||
hyper.emscripten-sources: *.cpp autohdr.h
|
||||
|
||||
|
|
16
README.md
16
README.md
|
@ -1,11 +1,4 @@
|
|||
# HyperRogue
|
||||
<p>
|
||||
<a href="https://travis-ci.org/zenorogue/hyperrogue/builds">
|
||||
<img src="https://badges.herokuapp.com/travis/zenorogue/hyperrogue?branch=master&env=TRAVIS_BUILD_SYSTEM=Makefile&label=make" alt="TravisCI badge">
|
||||
<img src="https://badges.herokuapp.com/travis/zenorogue/hyperrogue?branch=master&env=TRAVIS_BUILD_SYSTEM=mymake&label=mymake" alt="TravisCI badge">
|
||||
<img src="https://badges.herokuapp.com/travis/zenorogue/hyperrogue?branch=master&env=TRAVIS_BUILD_SYSTEM=emscripten&label=web" alt="TravisCI badge">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
A puzzle roguelike in the hyperbolic plane. See the [HyperRogue website](http://roguetemple.com/z/hyper.php) for detailed and most up-to-date information.
|
||||
Compiled executables can be downloaded from [itch.io](https://zenorogue.itch.io/hyperrogue) and from the [HyperRogue website](http://www.roguetemple.com/z/hyper/download.php).
|
||||
|
@ -62,15 +55,13 @@ On Linux with apt-get:
|
|||
|
||||
On macOS with Homebrew:
|
||||
|
||||
```brew install sdl sdl_ttf sdl_gfx sdl_mixer glew```
|
||||
|
||||
macOS users might also have to edit /usr/local/include/SDL/SDL_gfxPrimitives.h at line 38 to use quote include.
|
||||
```brew install sdl sdl_ttf sdl_gfx sdl_mixer glew libpng```
|
||||
|
||||
### Building HyperRogue from source ###
|
||||
```
|
||||
git clone https://github.com/zenorogue/hyperrogue.git hyperrogue
|
||||
cd hyperrogue
|
||||
make
|
||||
HYPERROGUE_USE_GLEW=1 HYPERROGUE_USE_PNG=1 make
|
||||
```
|
||||
|
||||
The `mymake` program builds HyperRogue in parts. It takes longer than the method shown above, but it uses significantly less memory during compilation, and when you change something, `mymake` will only recompile the changed file.
|
||||
|
@ -83,3 +74,6 @@ make mymake && ./mymake
|
|||
```
|
||||
|
||||
The source code is not documented very well. You can see the current state of the documentation, as generated by Doxygen, [here](https://zenorogue.github.io/hyperrogue-doc/).
|
||||
|
||||
## Discussion ##
|
||||
The best place to discuss HyperRogue is our [Discord server|https://discord.com/invite/8G44XkR].
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include "hyper.h"
|
||||
namespace hr {
|
||||
|
||||
#if HDR
|
||||
#define NUMLEADER 90
|
||||
#endif
|
||||
|
||||
EX bool test_achievements = false;
|
||||
|
||||
|
@ -86,9 +88,27 @@ EX const char* leadernames[NUMLEADER] = {
|
|||
"Crossbow (geometric)", // 89
|
||||
};
|
||||
|
||||
#if HDR
|
||||
#define LB_PRINCESS 36
|
||||
#define LB_STATISTICS 62
|
||||
#define LB_HALLOWEEN 63
|
||||
#define LB_YENDOR_CHALLENGE 40
|
||||
#define LB_PURE_TACTICS 41
|
||||
#define LB_PURE_TACTICS_SHMUP 49
|
||||
#define LB_PURE_TACTICS_COOP 50
|
||||
#define LB_RACING 81
|
||||
#endif
|
||||
|
||||
EX void achievement_init();
|
||||
EX string myname();
|
||||
EX void achievement_close();
|
||||
EX void achievement_pump();
|
||||
|
||||
/** gain the given achievement.
|
||||
* @param s name of the achievement, e.g., DIAMOND1
|
||||
* @param flags one of the constants from namespace rg. The achievement is only awarded if special modes are matched exactly.
|
||||
*/
|
||||
EX void achievement_gain(const char* s, char flags IS(0));
|
||||
|
||||
EX bool haveLeaderboard(int id);
|
||||
EX int get_currentscore(int id);
|
||||
|
@ -96,11 +116,11 @@ EX void set_priority_board(int id);
|
|||
EX int get_sync_status();
|
||||
EX bool score_loaded(int id);
|
||||
EX int score_default(int id);
|
||||
|
||||
EX void improveItemScores();
|
||||
EX void upload_score(int id, int v);
|
||||
|
||||
string achievementMessage[3];
|
||||
int achievementTimer;
|
||||
EX string achievementMessage[3];
|
||||
EX int achievementTimer;
|
||||
/** achievements received this game */
|
||||
EX vector<string> achievementsReceived;
|
||||
|
||||
|
@ -219,29 +239,24 @@ EX void achievement_log(const char* s, char flags) {
|
|||
#endif
|
||||
}
|
||||
|
||||
EX void achievement_init();
|
||||
EX string myname();
|
||||
EX void achievement_close();
|
||||
#ifndef LEADER
|
||||
#define LEADER "Unknown"
|
||||
#define LEADERFULL "Unknown"
|
||||
#endif
|
||||
|
||||
/** gain the given achievement.
|
||||
* @param s name of the achievement, e.g., DIAMOND1
|
||||
* @param flags one of the constants from namespace rg. The achievement is only awarded if special modes are matched exactly.
|
||||
*/
|
||||
EX void achievement_gain(const char* s, char flags IS(0));
|
||||
|
||||
#if ISSTEAM
|
||||
void improveItemScores();
|
||||
#include "private/hypersteam.cpp"
|
||||
#elif !ISANDROID && !ISIOS
|
||||
#if !CAP_ACHIEVE
|
||||
void achievement_init() {}
|
||||
string myname() { return "Rogue"; }
|
||||
void achievement_close() {}
|
||||
// gain the achievement with the given name.
|
||||
// flags: 'e' - for Euclidean, 's' - for Shmup, '7' - for heptagonal
|
||||
// Only awarded if special modes are matched exactly.
|
||||
void achievement_gain(const char* s, char flags IS(0)) {
|
||||
void achievement_gain(const char* s, char flags) {
|
||||
achievement_log(s, flags);
|
||||
}
|
||||
void achievement_pump() {}
|
||||
EX int get_sync_status() { return 0; }
|
||||
EX void set_priority_board(int) { }
|
||||
#endif
|
||||
|
||||
// gain the achievement for collecting a number of 'it'.
|
||||
|
@ -646,7 +661,7 @@ int specific_what = 0;
|
|||
EX void improve_score(int i, eItem what) {
|
||||
if(offlineMode) return;
|
||||
LATE( improve_score(i, what); )
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
#if CAP_ACHIEVE
|
||||
if(haveLeaderboard(i)) updateHi(what, get_currentscore(i));
|
||||
if(items[what] && haveLeaderboard(i)) {
|
||||
if(items[what] > get_currentscore(i) && score_loaded(i)) {
|
||||
|
@ -660,7 +675,7 @@ EX void improve_score(int i, eItem what) {
|
|||
// scores for special challenges
|
||||
EX void achievement_score(int cat, int number) {
|
||||
if(offlineMode) return;
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
#if CAP_ACHIEVE
|
||||
if(cheater) return;
|
||||
if(casual) return;
|
||||
LATE( achievement_score(cat, number); )
|
||||
|
@ -682,6 +697,7 @@ EX void achievement_score(int cat, int number) {
|
|||
return;
|
||||
if(racing::on && cat != LB_RACING) return;
|
||||
if(bow::weapon) return;
|
||||
if(use_custom_land_list) return;
|
||||
upload_score(cat, number);
|
||||
#endif
|
||||
}
|
||||
|
@ -765,7 +781,7 @@ EX void achievement_final(bool really_final) {
|
|||
|
||||
LATE( achievement_final(really_final); )
|
||||
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
#if CAP_ACHIEVE
|
||||
if(ticks > next_stat_tick) {
|
||||
upload_score(LB_STATISTICS, time(NULL));
|
||||
next_stat_tick = ticks + 600000;
|
||||
|
@ -900,7 +916,7 @@ EX void check_total_victory() {
|
|||
EX void achievement_victory(bool hyper) {
|
||||
DEBBI(DF_STEAM, ("achievement_victory"))
|
||||
if(offlineMode) return;
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
#if CAP_ACHIEVE
|
||||
if(cheater) return;
|
||||
if(casual) return;
|
||||
if(bow::weapon) return;
|
||||
|
@ -913,6 +929,7 @@ EX void achievement_victory(bool hyper) {
|
|||
if(tactic::on) return;
|
||||
if(!ls::nice_walls()) return;
|
||||
if(ineligible_starting_land) return;
|
||||
if(use_custom_land_list) return;
|
||||
LATE( achievement_victory(hyper); )
|
||||
DEBB(DF_STEAM, ("after checks"))
|
||||
|
||||
|
@ -1033,13 +1050,9 @@ EX string get_rich_presence_text() {
|
|||
return res;
|
||||
}
|
||||
|
||||
#ifndef HAVE_ACHIEVEMENTS
|
||||
void achievement_pump() {}
|
||||
#endif
|
||||
|
||||
/** display the last achievement gained. */
|
||||
EX void achievement_display() {
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
#if CAP_ACHIEVE
|
||||
if(achievementTimer) {
|
||||
int col = (ticks - achievementTimer);
|
||||
if(col > 5000) { achievementTimer = 0; return; }
|
||||
|
@ -1069,9 +1082,4 @@ EX int score_default(int i) {
|
|||
else return 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_ACHIEVEMENTS
|
||||
EX int get_sync_status() { return 0; }
|
||||
EX void set_priority_board(int) { }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -220,8 +220,7 @@ void ensure_geometry(eGeometryClass c) {
|
|||
|
||||
if(specialland != laCanvas) {
|
||||
canvas_default_wall = waInvisibleFloor;
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = 0xFFFFFF;
|
||||
ccolor::set_plain(0xFFFFFF);
|
||||
enable_canvas();
|
||||
}
|
||||
start_game();
|
||||
|
@ -1283,7 +1282,7 @@ void connection_debugger() {
|
|||
|
||||
curvepoint(sh[0]);
|
||||
|
||||
color_t col = colortables['A'][id];
|
||||
color_t col = ccolor::shape.ctab[id];
|
||||
col = darkena(col, 0, 0xFF);
|
||||
|
||||
if(&p == &last) {
|
||||
|
@ -1868,17 +1867,34 @@ EX void convert_max() {
|
|||
|
||||
EX void convert_minimize(int N, vector<int>& old_shvids, map<int, int>& old_to_new) {
|
||||
vector<pair<int, int>> address;
|
||||
vector<int> next;
|
||||
vector<int> address_start;
|
||||
|
||||
for(int i=0; i<N; i++) {
|
||||
int q = identification[old_shvids[i]].modval;
|
||||
int c = isize(address);
|
||||
address_start.push_back(c);
|
||||
for(int j=0; j<q; j++) {
|
||||
address.emplace_back(i, j);
|
||||
next.emplace_back(j == q-1 ? c : c+j+1);
|
||||
}
|
||||
}
|
||||
|
||||
int K = isize(address);
|
||||
vector<int> next(K), step(K);
|
||||
|
||||
for(int k=0; k<K; k++) {
|
||||
auto i = address[k].first;
|
||||
auto j = address[k].second;
|
||||
|
||||
auto& id = identification[old_shvids[i]];
|
||||
next[k] = address_start[i] + (j+1) % id.modval;
|
||||
|
||||
cell *s = id.sample;
|
||||
cellwalker cw(s, j);
|
||||
cw += wstep;
|
||||
auto idx = get_identification(cw.at);
|
||||
step[k] = address_start[old_to_new.at(idx.target)] + gmod(cw.spin - idx.shift, idx.modval);
|
||||
}
|
||||
|
||||
vector<array<ld, 3> > dists(K);
|
||||
for(int i=0; i<K; i++) {
|
||||
auto pi = address[i];
|
||||
|
@ -1911,11 +1927,18 @@ EX void convert_minimize(int N, vector<int>& old_shvids, map<int, int>& old_to_n
|
|||
|
||||
int chg = 1;
|
||||
while(chg) {
|
||||
for(auto& eq: equal) println(hlog, eq);
|
||||
if(debugflags & DF_GEOM) {
|
||||
println(hlog, "current table of equals:");
|
||||
int eqid = 0;
|
||||
for(auto& eq: equal) {
|
||||
println(hlog, eq, " for ", eqid, ": ", address[eqid], " next= ", next[eqid], " step= ", step[eqid]);
|
||||
eqid++;
|
||||
}
|
||||
}
|
||||
chg = 0;
|
||||
for(int i=0; i<K; i++)
|
||||
for(int j=0; j<K; j++)
|
||||
if(equal[i][j] && !equal[next[i]][next[j]]) {
|
||||
if(equal[i][j] && (!equal[next[i]][next[j]] || !equal[step[i]][step[j]])) {
|
||||
equal[i][j] = false;
|
||||
chg++;
|
||||
}
|
||||
|
@ -1984,6 +2007,10 @@ EX void convert() {
|
|||
sh.vertices.clear();
|
||||
sh.connections.clear();
|
||||
sh.cycle_length = id.modval;
|
||||
if(arcm::in())
|
||||
sh.orig_id = arcm::get_graphical_id(s);
|
||||
else
|
||||
sh.orig_id = shvid(s);
|
||||
sh.repeat_value = t / id.modval;
|
||||
sh.flags = hr::pseudohept(s) ? arcm::sfPH : 0;
|
||||
#if CAP_ARCM
|
||||
|
|
|
@ -1078,6 +1078,20 @@ void archimedean_tiling::parse() {
|
|||
prepare();
|
||||
}
|
||||
|
||||
EX bool load_symbol(const string& s, bool switch_geom) {
|
||||
archimedean_tiling at; at.parse(s);
|
||||
if(at.errors) {
|
||||
DEBB(DF_ERROR | DF_GEOM, ("error: ", at.errormsg));
|
||||
return false;
|
||||
}
|
||||
if(!switch_geom && geometry != gArchimedean) return true;
|
||||
stop_game();
|
||||
set_geometry(gArchimedean);
|
||||
current = at;
|
||||
if(!delayed_start) start_game();
|
||||
return true;
|
||||
}
|
||||
|
||||
#if CAP_COMMANDLINE
|
||||
int readArgs() {
|
||||
using namespace arg;
|
||||
|
@ -1085,17 +1099,9 @@ int readArgs() {
|
|||
if(0) ;
|
||||
else if(argis("-symbol")) {
|
||||
PHASEFROM(2);
|
||||
archimedean_tiling at;
|
||||
shift(); at.parse(args());
|
||||
if(at.errors) {
|
||||
DEBB(DF_ERROR | DF_GEOM, ("error: ", at.errormsg));
|
||||
}
|
||||
else {
|
||||
set_geometry(gArchimedean);
|
||||
current = at;
|
||||
shift(); load_symbol(args(), true);
|
||||
showstartmenu = false;
|
||||
}
|
||||
}
|
||||
else if(argis("-dual")) { PHASEFROM(2); set_variation(eVariation::dual); }
|
||||
else if(argis("-d:arcm"))
|
||||
launch_dialog(show);
|
||||
|
@ -1340,17 +1346,25 @@ EX void enable(archimedean_tiling& arct) {
|
|||
start_game();
|
||||
}
|
||||
|
||||
function<void()> setcanvas(char c) {
|
||||
return [c] () {
|
||||
function<void()> setcanvas(ccolor::data& c) {
|
||||
auto pc = &c;
|
||||
return [pc] () {
|
||||
stop_game();
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = c;
|
||||
ccolor::which = pc;
|
||||
start_game();
|
||||
};
|
||||
}
|
||||
|
||||
dialog::string_dialog se;
|
||||
|
||||
EX void init_symbol_edit() {
|
||||
symbol_editing = true;
|
||||
edited = current;
|
||||
se.start_editing(edited.symbol);
|
||||
edited.parse();
|
||||
}
|
||||
|
||||
EX void show() {
|
||||
if(lastsample < isize(samples)) {
|
||||
string s = samples[lastsample].first;
|
||||
|
@ -1404,12 +1418,7 @@ EX void show() {
|
|||
else {
|
||||
string cs = in() ? current.symbol : XLAT("OFF");
|
||||
dialog::addSelItem("edit", cs, '/');
|
||||
dialog::add_action([] () {
|
||||
symbol_editing = true;
|
||||
edited = current;
|
||||
se.start_editing(edited.symbol);
|
||||
edited.parse();
|
||||
});
|
||||
dialog::add_action(init_symbol_edit);
|
||||
dialog::addBreak(100);
|
||||
int nextpos = spos;
|
||||
int shown = 0;
|
||||
|
@ -1463,13 +1472,15 @@ EX void show() {
|
|||
});
|
||||
|
||||
if(in()) {
|
||||
dialog::addSelItem(XLAT("size of the world"), current.world_size(), 0);
|
||||
dialog::addSelItem(XLAT("size of the world"), current.world_size(), 'S');
|
||||
add_size_action();
|
||||
|
||||
dialog::addSelItem(XLAT("edge length"), current.get_class() == gcEuclid ? (fts(current.edgelength) + XLAT(" (arbitrary)")) : fts(current.edgelength), 0);
|
||||
|
||||
dialog::addItem(XLAT("color by symmetries"), 't');
|
||||
dialog::add_action(setcanvas('A'));
|
||||
dialog::add_action(setcanvas(ccolor::shape));
|
||||
dialog::addItem(XLAT("color by symmetries (reversed tiles marked)"), 'r');
|
||||
dialog::add_action(setcanvas('R'));
|
||||
dialog::add_action(setcanvas(ccolor::shape_mirror));
|
||||
}
|
||||
else {
|
||||
dialog::addBreak(100);
|
||||
|
@ -1479,20 +1490,20 @@ EX void show() {
|
|||
|
||||
if(true) {
|
||||
dialog::addItem(XLAT("color by sides"), 'u');
|
||||
dialog::add_action(setcanvas('B'));
|
||||
dialog::add_action(setcanvas(ccolor::sides));
|
||||
}
|
||||
|
||||
if(geosupport_threecolor() == 2) {
|
||||
dialog::addItem(XLAT("three colors"), 'w');
|
||||
dialog::add_action(setcanvas('T'));
|
||||
dialog::add_action(setcanvas(ccolor::threecolor));
|
||||
}
|
||||
else if(geosupport_football() == 2) {
|
||||
dialog::addItem(XLAT("football"), 'w');
|
||||
dialog::add_action(setcanvas('F'));
|
||||
dialog::add_action(setcanvas(ccolor::football));
|
||||
}
|
||||
else if(geosupport_chessboard()) {
|
||||
dialog::addItem(XLAT("chessboard"), 'w');
|
||||
dialog::add_action(setcanvas('c'));
|
||||
dialog::add_action(setcanvas(ccolor::chessboard));
|
||||
}
|
||||
else dialog::addBreak(100);
|
||||
|
||||
|
@ -1569,6 +1580,14 @@ EX bool is_vertex(heptagon *h) {
|
|||
return id_of(h) >= 2 * current.N;
|
||||
}
|
||||
|
||||
EX int get_graphical_id(cell *c) {
|
||||
int id = arcm::id_of(c->master);
|
||||
int tid = arcm::current.tilegroup[id];
|
||||
int tid2 = arcm::current.tilegroup[id^1];
|
||||
if(tid2 >= 0) tid = min(tid, tid2);
|
||||
return tid;
|
||||
}
|
||||
|
||||
bool archimedean_tiling::get_step_values(int& steps, int& single_step) {
|
||||
|
||||
int nom = -2;
|
||||
|
|
18
attack.cpp
18
attack.cpp
|
@ -151,7 +151,7 @@ EX bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags)
|
|||
if(!(flags & (AF_GUN | AF_SWORD | AF_SWORD_INTO | AF_MAGIC | AF_PLAGUE)))
|
||||
if(c1 != c2 && !logical_adjacent(c1, m1, c2)) return false;
|
||||
|
||||
if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH | AF_GUN | AF_MAGIC | AF_PLAGUE | AF_SIDE)))
|
||||
if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH | AF_GUN | AF_MAGIC | AF_PLAGUE | AF_SIDE | AF_BOW)))
|
||||
if(c1 && c2 && againstRose(c1, c2) && !ignoresSmell(m1))
|
||||
return false;
|
||||
|
||||
|
@ -340,6 +340,10 @@ EX eWall conditional_flip_slime(bool flip, eWall t) {
|
|||
return t;
|
||||
}
|
||||
|
||||
EX void chainspill(cell *c) {
|
||||
if(c->wall == waMagma && c->monst == moSlimeNextTurn) killMonster(c, moNone, 0);
|
||||
}
|
||||
|
||||
EX void spillfix(cell* c, eWall t, int rad) {
|
||||
if(c->wall == waTemporary) {
|
||||
changes.ccell(c);
|
||||
|
@ -348,6 +352,7 @@ EX void spillfix(cell* c, eWall t, int rad) {
|
|||
if(rad) for(auto p: adj_minefield_cells_full(c)) {
|
||||
spillfix(p.c, conditional_flip_slime(p.mirrored, t), rad-1);
|
||||
}
|
||||
chainspill(c);
|
||||
}
|
||||
|
||||
EX void spill(cell* c, eWall t, int rad) {
|
||||
|
@ -362,6 +367,7 @@ EX void spill(cell* c, eWall t, int rad) {
|
|||
si.second.spill_b > si.second.spill_a ? waFloorB :
|
||||
isAlchAny(si.second.orig) ? si.second.orig :
|
||||
waNone;
|
||||
chainspill(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -757,7 +763,7 @@ EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) {
|
|||
// a reward for killing him before he shoots!
|
||||
c->item = itOrbDragon;
|
||||
}
|
||||
if(m == moAsteroid && !shmup::on && c->item == itNone && c->wall != waChasm) {
|
||||
if(m == moAsteroid && !shmup::on && c->item == itNone && c->wall != waChasm && c->land == laAsteroids) {
|
||||
c->item = itAsteroid;
|
||||
changes.value_add(splitrocks, 2);
|
||||
}
|
||||
|
@ -944,6 +950,14 @@ EX void fightmessage(eMonster victim, eMonster attacker, bool stun, flagtype fla
|
|||
else
|
||||
addMessage(XLAT("You pierce %the1.", victim)); // normal
|
||||
}
|
||||
else if(items[itOrbSlaying]) {
|
||||
playSound(NULL, "hit-crush"+pick123());
|
||||
addMessage(XLAT("You crush %the1!", victim)); // normal
|
||||
}
|
||||
else if(stun && items[itCurseWeakness]) {
|
||||
playSound(NULL, "click");
|
||||
addMessage(XLAT("You punch %the1.", victim)); // normal
|
||||
}
|
||||
else if(!peace::on) {
|
||||
playSound(NULL, "hit-sword"+pick123());
|
||||
addMessage(XLAT("You kill %the1.", victim)); // normal
|
||||
|
|
133
barriers.cpp
133
barriers.cpp
|
@ -559,7 +559,9 @@ EX bool isbar4(cell *c) {
|
|||
}
|
||||
|
||||
EX bool barrier_cross(eLand l, eLand r) {
|
||||
if(land_structure == lsVineWalls) return false;
|
||||
if(l == laCrossroads3 || r == laCrossroads3) return hrand(100) < 66;
|
||||
if(land_structure == lsCrossWalls && !among(laCrossroads2, l, r)) return hrand(100) < 90;
|
||||
if(isElemental(l) && isElemental(r)) return hrand(100) < 75;
|
||||
return false;
|
||||
}
|
||||
|
@ -615,6 +617,12 @@ EX void extendBarrier(cell *c) {
|
|||
if(buildBarrier6(cw, 2)) return;
|
||||
}
|
||||
|
||||
if(land_structure == lsCursedWalls && c->barleft != laMirror && c->barright != laMirror && hrand(100) < 80 && !among(laCrossroads2, c->barleft, c->barright)) {
|
||||
cellwalker cw(c, c->bardir);
|
||||
cw = cw + wstep + 3 + wstep - 1;
|
||||
if(buildBarrier6(cw, c->barright, c->barleft)) return;
|
||||
}
|
||||
|
||||
if(barrier_cross(c->barleft, c->barright) || (firstmirror && hrand(100) < 60)) {
|
||||
|
||||
cellwalker cw(c, c->bardir);
|
||||
|
@ -680,6 +688,7 @@ EX void buildBarrier(cell *c, int d, eLand l IS(laNone)) {
|
|||
buildBarrierForce(c, d, l);
|
||||
}
|
||||
|
||||
/** mirror variant of 6-fold walls */
|
||||
EX bool buildBarrier6(cellwalker cw, int type) {
|
||||
limitgen("build6 %p/%d (%d)\n", hr::voidp(cw.at), cw.spin, type);
|
||||
|
||||
|
@ -725,20 +734,27 @@ EX bool buildBarrier6(cellwalker cw, int type) {
|
|||
if(!(PURE?checkBarriersFront:checkBarriersBack)(b[3], 6, true)) return false;
|
||||
}
|
||||
|
||||
eLand m0 = laMirror;
|
||||
eLand m1 = laMirrored;
|
||||
eLand m2 = laMirrored2;
|
||||
eLand mw1 = laMirrorWall;
|
||||
eLand mw2 = laMirrorWall2;
|
||||
eWall w = waMirrorWall;
|
||||
|
||||
for(int d=0; d<4; d++) {
|
||||
b[d].at->bardir = b[d].spin;
|
||||
|
||||
if(PURE) {
|
||||
b[0].at->barleft = laMirrored, b[0].at->barright = laMirrored2;
|
||||
b[1].at->barleft = laMirror, b[1].at->barright = laMirrored;
|
||||
b[2].at->barleft = laMirrored2, b[2].at->barright = laMirrored;
|
||||
b[3].at->barleft = laMirrored, b[3].at->barright = laMirror;
|
||||
b[0].at->barleft = m1, b[0].at->barright = m2;
|
||||
b[1].at->barleft = m0, b[1].at->barright = m1;
|
||||
b[2].at->barleft = m2, b[2].at->barright = m1;
|
||||
b[3].at->barleft = m1, b[3].at->barright = m0;
|
||||
}
|
||||
else {
|
||||
b[0].at->barleft = laMirror, b[0].at->barright = laMirrored;
|
||||
b[1].at->barleft = laMirrored, b[1].at->barright = laMirror;
|
||||
b[2].at->barleft = laMirrored, b[2].at->barright = laMirrored2;
|
||||
b[3].at->barleft = laMirrored2, b[3].at->barright = laMirrored;
|
||||
b[0].at->barleft = m0, b[0].at->barright = m1;
|
||||
b[1].at->barleft = m1, b[1].at->barright = m0;
|
||||
b[2].at->barleft = m1, b[2].at->barright = m2;
|
||||
b[3].at->barleft = m2, b[3].at->barright = m1;
|
||||
}
|
||||
|
||||
(PURE?extendBarrierFront:extendBarrierBack)(b[d].at);
|
||||
|
@ -752,40 +768,82 @@ EX bool buildBarrier6(cellwalker cw, int type) {
|
|||
}
|
||||
|
||||
if(BITRUNCATED) {
|
||||
setland((cw+1).cpeek(), laMirrorWall);
|
||||
setland((cw+2).cpeek(), laMirrored);
|
||||
setland((cw+3).cpeek(), laMirrorWall2);
|
||||
setland((cw+4).cpeek(), laMirrorWall2);
|
||||
setland((cw+5).cpeek(), laMirrored);
|
||||
setland((cw+0).cpeek(), laMirrorWall);
|
||||
setland((b[0]+2).cpeek(), laMirrored);
|
||||
setland((b[3]+6).cpeek(), laMirrored2);
|
||||
setland((b[3]+5).cpeek(), laMirrored2);
|
||||
setland((b[1]-1).cpeek(), laMirrored);
|
||||
setland((b[2]-2).cpeek(), laMirrored);
|
||||
setland((b[1]-2).cpeek(), laMirrored);
|
||||
setland((b[0]-2).cpeek(), laMirror);
|
||||
cw.at->land = laMirrorWall;
|
||||
cw.at->wall = waMirrorWall;
|
||||
setland((cw+1).cpeek(), mw1);
|
||||
setland((cw+2).cpeek(), m1);
|
||||
setland((cw+3).cpeek(), mw2);
|
||||
setland((cw+4).cpeek(), mw2);
|
||||
setland((cw+5).cpeek(), m1);
|
||||
setland((cw+0).cpeek(), mw1);
|
||||
setland((b[0]+2).cpeek(), m1);
|
||||
setland((b[3]+6).cpeek(), m2);
|
||||
setland((b[3]+5).cpeek(), m2);
|
||||
setland((b[1]-1).cpeek(), m1);
|
||||
setland((b[2]-2).cpeek(), m1);
|
||||
setland((b[1]-2).cpeek(), m1);
|
||||
setland((b[0]-2).cpeek(), m0);
|
||||
cw.at->land = mw1;
|
||||
cw.at->wall = w;
|
||||
cw.at->landparam = 1;
|
||||
}
|
||||
else {
|
||||
setland(cw.at, laMirrorWall2);
|
||||
setland((cw+0).cpeek(), laMirrorWall2);
|
||||
setland((cw+1).cpeek(), laMirrored);
|
||||
setland((cw+2).cpeek(), laMirrored);
|
||||
setland((cw+3).cpeek(), laMirrorWall);
|
||||
setland((cw+4).cpeek(), laMirrored);
|
||||
setland((cw+5).cpeek(), laMirrorWall2);
|
||||
setland((cw+6).cpeek(), laMirrored2);
|
||||
setland(cw.at, mw2);
|
||||
setland((cw+0).cpeek(), mw2);
|
||||
setland((cw+1).cpeek(), m1);
|
||||
setland((cw+2).cpeek(), m1);
|
||||
setland((cw+3).cpeek(), mw1);
|
||||
setland((cw+4).cpeek(), m1);
|
||||
setland((cw+5).cpeek(), mw2);
|
||||
setland((cw+6).cpeek(), m2);
|
||||
|
||||
setland((b[1]).cpeek(), laMirrorWall);
|
||||
setland((b[1]+1).cpeek(), laMirror);
|
||||
setland((b[1]+2).cpeek(), laMirrorWall);
|
||||
setland((b[1]+6).cpeek(), laMirrored);
|
||||
setland((b[1]).cpeek(), mw1);
|
||||
setland((b[1]+1).cpeek(), m0);
|
||||
setland((b[1]+2).cpeek(), mw1);
|
||||
setland((b[1]+6).cpeek(), m1);
|
||||
|
||||
setland((b[0] + wstep - 2).cpeek(), laMirrored);
|
||||
setland((b[3] + wstep - 2).cpeek(), laMirrored);
|
||||
setland((b[0] + wstep - 2).cpeek(), m1);
|
||||
setland((b[3] + wstep - 2).cpeek(), m1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EX int curse_percentage = 10;
|
||||
|
||||
/** cursed variant of 6-fold walls */
|
||||
EX bool buildBarrier6(cellwalker cw, eLand m0, eLand m1) {
|
||||
cellwalker b[6];
|
||||
if(buggyGeneration) return true;
|
||||
|
||||
for(int i=0; i<6; i+=2)
|
||||
b[i] = cw + i + wstep;
|
||||
for(int i=1; i<6; i+=2)
|
||||
b[i] = cw + i + wstep + 3 + wstep;
|
||||
|
||||
for(int i=0; i<6; i++) if(i != 1) {
|
||||
if(!(PURE?checkBarriersFront:checkBarriersBack)(b[i], 6, true)) return false;
|
||||
}
|
||||
|
||||
for(int d=0; d<6; d++) {
|
||||
b[d].at->bardir = b[d].spin;
|
||||
b[d].at->barleft = (d&1) ? m1 : m0;
|
||||
b[d].at->barright = (d&1) ? m0 : m1;
|
||||
(PURE?extendBarrierFront:extendBarrierBack)(b[d].at);
|
||||
}
|
||||
|
||||
cw.at->land = laBarrier;
|
||||
cw.at->wall = waBarrier;
|
||||
forCellCM(c, cw.at) { c->land = laBarrier; c->wall = waBarrier; }
|
||||
for(int d=0; d<6; d+=2) {
|
||||
setland((b[d]-2).cpeek(), m0);
|
||||
setland((b[d]+2).cpeek(), m1);
|
||||
setland((b[d+1]-2).cpeek(), m1);
|
||||
setland((b[d+1]+2).cpeek(), m0);
|
||||
}
|
||||
if(hrand(100) < curse_percentage) {
|
||||
setland(cw.at, laCursed);
|
||||
cw.at->wall = waRubble;
|
||||
cw.at->monst = moHexer;
|
||||
cw.at->item = random_curse();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1099,6 +1157,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
|
|||
#endif
|
||||
|
||||
EX bool buildBarrierNowall(cell *c, eLand l2, int forced_dir IS(NODIR)) {
|
||||
if(among(l2, laCrossroads2, laCrossroads5)) return false;
|
||||
return general_barrier_build(NOWALLSEP, c, l2, forced_dir);
|
||||
}
|
||||
|
||||
|
|
|
@ -1516,12 +1516,14 @@ EX void initialize_all() {
|
|||
|
||||
DEBBI(DF_INIT | DF_GRAPH, ("initgraph"));
|
||||
|
||||
DEBB(DF_INIT, ("initconfig"));
|
||||
initConfig();
|
||||
|
||||
#if CAP_SDLJOY
|
||||
joyx = joyy = 0; joydir.d = -1;
|
||||
#endif
|
||||
|
||||
DEBB(DF_INIT, ("restartGraph"));
|
||||
restartGraph();
|
||||
|
||||
if(noGUI) {
|
||||
|
@ -1531,11 +1533,14 @@ EX void initialize_all() {
|
|||
return;
|
||||
}
|
||||
|
||||
DEBB(DF_INIT, ("preparesort"));
|
||||
preparesort();
|
||||
#if CAP_CONFIG
|
||||
DEBB(DF_INIT, ("loadConfig"));
|
||||
loadConfig();
|
||||
#endif
|
||||
#if CAP_ARCM
|
||||
DEBB(DF_INIT, ("parse symbol"));
|
||||
arcm::current.parse();
|
||||
#endif
|
||||
if(mhybrid) geometry = hybrid::underlying;
|
||||
|
@ -1544,19 +1549,26 @@ EX void initialize_all() {
|
|||
arg::read(2);
|
||||
#endif
|
||||
|
||||
DEBB(DF_INIT | DF_GRAPH, ("init graph"));
|
||||
init_graph();
|
||||
DEBB(DF_INIT | DF_POLY, ("check CGI"));
|
||||
check_cgi();
|
||||
DEBB(DF_INIT | DF_POLY, ("require basic"));
|
||||
cgi.require_basics();
|
||||
|
||||
DEBB(DF_INIT | DF_GRAPH, ("init font"));
|
||||
init_font();
|
||||
|
||||
#if CAP_SDLJOY
|
||||
initJoysticks();
|
||||
initJoysticks_async();
|
||||
#endif
|
||||
|
||||
#if CAP_SDLAUDIO
|
||||
DEBB(DF_INIT, ("init audio"));
|
||||
initAudio();
|
||||
#endif
|
||||
|
||||
DEBB(DF_INIT, ("initialize_all done"));
|
||||
}
|
||||
|
||||
EX void quit_all() {
|
||||
|
|
43
bigstuff.cpp
43
bigstuff.cpp
|
@ -703,6 +703,9 @@ EX int coastval(cell *c, eLand base) {
|
|||
if(!c->landparam) return UNKNOWN;
|
||||
return c->landparam & 255;
|
||||
}
|
||||
else if(base == laWestWall) {
|
||||
if(c->land != base) return 0;
|
||||
}
|
||||
else {
|
||||
if(c->land == laOceanWall || c->land == laCaribbean || c->land == laWhirlpool ||
|
||||
c->land == laLivefjord || c->land == laWarpSea || c->land == laKraken || c->land == laDocks || c->land == laBrownian)
|
||||
|
@ -1005,7 +1008,7 @@ EX void buildEquidistant(cell *c) {
|
|||
if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !mhybrid && hrand(10) < 5 && chance)
|
||||
buildAnotherEquidistant(c);
|
||||
|
||||
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !mhybrid && hrand(100) < (PURE?25:5) && items[itBone] >= U10 && chance)
|
||||
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !mhybrid && hrand(100) < (PURE?25:5) && landUnlockedIngame(laHaunted) && chance)
|
||||
buildAnotherEquidistant(c);
|
||||
}
|
||||
|
||||
|
@ -1326,7 +1329,7 @@ EX void setLandEuclid(cell *c) {
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
setland(c, specialland);
|
||||
if(!c->land) setland(c, specialland);
|
||||
if(ls::any_nowall()) {
|
||||
auto co = euc2_coordinates(c);
|
||||
int y = co.second;
|
||||
|
@ -1772,6 +1775,21 @@ EX void build_walls(cell *c, cell *from) {
|
|||
else if(good_for_wall(c) && isWarpedType(c->land) && hrand(10000) < 3000 && c->land &&
|
||||
buildBarrierNowall(c, eLand(c->land ^ laWarpSea ^ laWarpCoast))) { }
|
||||
|
||||
else if(land_structure == lsVineWalls) {
|
||||
int ev = emeraldval(c);
|
||||
if((ev | 11) == 43 && c->bardir == NODIR) {
|
||||
for(int i=0; i<c->type; i++) if(emeraldval(c->cmove(i)) == ev-4) {
|
||||
bool oldleft = true;
|
||||
for(int j=1; j<=3; j++)
|
||||
if(c->modmove(i+j) && c->modmove(i+j)->mpdist < c->mpdist)
|
||||
oldleft = false;
|
||||
buildBarrierStrong(c, i, oldleft, getNewLand(c->land));
|
||||
extendBarrier(c);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else if(ls::single()) return;
|
||||
|
||||
else if(geometry == gNormal && celldist(c) < 3 && !GOLDBERG) {
|
||||
|
@ -1792,11 +1810,11 @@ EX void build_walls(cell *c, cell *from) {
|
|||
return;
|
||||
}
|
||||
|
||||
else if(good_for_wall(c) && c->land == laCrossroads4 && hrand(10000) < 7000 && c->land && !c->master->alt && !tactic::on && !racing::on &&
|
||||
else if(good_for_wall(c) && ls::any_wall() && c->land == laCrossroads4 && hrand(10000) < 7000 && c->land && !c->master->alt && !tactic::on && !racing::on &&
|
||||
buildBarrierNowall(c, getNewLand(laCrossroads4))) ;
|
||||
|
||||
else if(good_for_wall(c) && hrand(I10000) < 20 && !generatingEquidistant && !yendor::on && !tactic::on && !racing::on && !isCrossroads(c->land) &&
|
||||
gold() >= R200 && !weirdhyperbolic && !c->master->alt && c->bardir != NOBARRIERS &&
|
||||
else if(good_for_wall(c) && ls::any_wall() && hrand(I10000) < 20 && !generatingEquidistant && !yendor::on && !tactic::on && !racing::on && !isCrossroads(c->land) &&
|
||||
landUnlockedIngame(laCrossroads4) && !weirdhyperbolic && !c->master->alt && c->bardir != NOBARRIERS &&
|
||||
!inmirror(c) && !isSealand(c->land) && !isHaunted(c->land) && !isGravityLand(c->land) &&
|
||||
(c->land != laRlyeh || rlyehComplete()) &&
|
||||
c->land != laTortoise && c->land != laPrairie && c->land &&
|
||||
|
@ -1876,13 +1894,13 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
items[itEmerald] >= U5)))
|
||||
start_camelot(c);
|
||||
|
||||
if(c->land == laRlyeh && can_start_horo(c) && (quickfind(laTemple) || peace::on || (hrand(I2000) < 100 && items[itStatue] >= U5)))
|
||||
if(c->land == laRlyeh && can_start_horo(c) && (quickfind(laTemple) || (hrand(I2000) < 100 && landUnlockedIngame(laTemple))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
if(c->land == laJungle && can_start_horo(c) && (quickfind(laMountain) || (hrand(I2000) < 100 && landUnlocked(laMountain))))
|
||||
if(c->land == laJungle && can_start_horo(c) && (quickfind(laMountain) || (hrand(I2000) < 100 && landUnlockedIngame(laMountain))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
if(c->land == laOvergrown && can_start_horo(c) && (quickfind(laClearing) || (hrand(I2000) < 25 && items[itMutant] >= U5 && isLandIngame(laClearing)))) {
|
||||
if(c->land == laOvergrown && can_start_horo(c) && (quickfind(laClearing) || (hrand(I2000) < 25 && landUnlockedIngame(laClearing)))) {
|
||||
heptagon *h = create_altmap(c, horo_gen_distance(), hsA);
|
||||
if(h) clearing::bpdata[h].root = NULL;
|
||||
}
|
||||
|
@ -1894,11 +1912,12 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && !peace::on && can_start_horo(c) &&
|
||||
(quickfind(laWhirlpool) || (
|
||||
hrand(2000) < (PURE ? 500 : 1000))))
|
||||
hrand(2000) < (PURE ? 500 : 1000) && landUnlockedIngame(laWhirlpool))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
#if CAP_COMPLEX2
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && hrand(10000) < 20 && no_barriers_in_radius(c, 2) && hyperbolic && !quotient && !tactic::on && !safety && !ls::hv_structure())
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && hrand(10000) < 20 && no_barriers_in_radius(c, 2) && hyperbolic && !quotient && !tactic::on && !safety && !ls::hv_structure()
|
||||
&& landUnlockedIngame(laBrownian))
|
||||
brownian::init_further(c);
|
||||
#endif
|
||||
|
||||
|
@ -1919,7 +1938,7 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
if(c->land == laPalace && can_start_horo(c) && !princess::generating && !shmup::on && multi::players == 1 && !weirdhyperbolic &&
|
||||
(princess::forceMouse ? canReachPlayer(from, moMouse) :
|
||||
(hrand(2000) < (peace::on ? 100 : 20))) &&
|
||||
(princess::challenge || kills[moVizier] || peace::on)) {
|
||||
landUnlockedIngame(laPrincessQuest)) {
|
||||
create_altmap(c, PRADIUS0, hsOrigin, waPalace);
|
||||
celllister cl(c, 5, 1000000, NULL);
|
||||
for(cell *c: cl.lst) if(c->master->alt) currentmap->extend_altmap(c->master);
|
||||
|
@ -2318,7 +2337,7 @@ EX void pregen() {
|
|||
currentlands.clear();
|
||||
if(ls::any_chaos() && !ls::std_chaos())
|
||||
for(eLand l: land_over)
|
||||
if(landUnlocked(l) && isLandIngame(l))
|
||||
if(landUnlockedIngame(l))
|
||||
currentlands.push_back(l);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ EX namespace bt {
|
|||
h->emeraldval = gmod((parent->emeraldval - d1) * 7508, 15015);
|
||||
break;
|
||||
case gTernary:
|
||||
if(d < 2)
|
||||
if(d <= 2)
|
||||
h->emeraldval = gmod(parent->emeraldval * 3 + d, 10010);
|
||||
else
|
||||
h->emeraldval = gmod((parent->emeraldval - d1) * 3337, 10010);
|
||||
|
@ -854,15 +854,36 @@ auto bt_config = arg::add2("-btwidth", [] {arg::shift_arg_formula(vid.binary_wid
|
|||
#endif
|
||||
|
||||
EX bool pseudohept(cell *c) {
|
||||
if(WDIM == 2)
|
||||
return c->type & c->master->distance & 1;
|
||||
else if(geometry == gHoroRec)
|
||||
switch(geometry) {
|
||||
case gBinary4:
|
||||
c->cmove(3);
|
||||
return (c->master->distance & 1) && (c->c.spin(3) == 0);
|
||||
|
||||
case gBinaryTiling:
|
||||
return c->master->distance & c->type & 1;
|
||||
|
||||
case gTernary: {
|
||||
return c->master->emeraldval & 1;
|
||||
/* auto m = dynamic_cast<hrmap_binary*> (current_map());
|
||||
auto o = m->origin;
|
||||
int flips = 0;
|
||||
while(m != o) {
|
||||
if(m->master->distance >= o->master->distance) { if(m->c.spin(4) == 1) flips++; m = m->cmove(4); }
|
||||
}
|
||||
heptagon *origin;
|
||||
c->cmove(4); return (c->c.spin(4) == 1); */
|
||||
}
|
||||
|
||||
case gHoroRec:
|
||||
return c->c.spin(S7-1) == 0 && (c->master->distance & 1) && c->cmove(S7-1)->c.spin(S7-1) == 0;
|
||||
else if(geometry == gHoroTris)
|
||||
|
||||
case gHoroTris:
|
||||
return c->c.spin(S7-1) == 0 && (c->master->distance & 1);
|
||||
else
|
||||
|
||||
default:
|
||||
return (c->master->zebraval == 1) && (c->master->distance & 1);
|
||||
}
|
||||
}
|
||||
|
||||
EX pair<gp::loc, gp::loc> gpvalue(heptagon *h) {
|
||||
int d = h->c.spin(S7-1);
|
||||
|
|
|
@ -94,6 +94,14 @@ void eclectic_red(color_t& col) {
|
|||
|
||||
constexpr ld spinspeed = .75 / M_PI;
|
||||
|
||||
EX color_t apply_mine_knowledge(color_t wcol, cell* c) {
|
||||
if(mine::marked_safe(c))
|
||||
return gradient(wcol, 0x40FF40, 0, 0.2, 1);
|
||||
if(mine::marked_mine(c))
|
||||
return gradient(wcol, 0xFF4040, -1, vid.ispeed ? sintick(100) : 1, 1);
|
||||
return wcol;
|
||||
}
|
||||
|
||||
void celldrawer::setcolors() {
|
||||
|
||||
wcol = fcol = winf[c->wall].color;
|
||||
|
@ -541,10 +549,7 @@ void celldrawer::setcolors() {
|
|||
|
||||
case waMineUnknown: case waMineMine:
|
||||
#if CAP_COMPLEX2
|
||||
if(mine::marked_safe(c))
|
||||
fcol = wcol = gradient(wcol, 0x40FF40, 0, 0.2, 1);
|
||||
else if(mine::marked_mine(c))
|
||||
fcol = wcol = gradient(wcol, 0xFF4040, -1, vid.ispeed ? sintick(100) : 1, 1);
|
||||
if(!mine_markers) fcol = wcol = apply_mine_knowledge(wcol, c);
|
||||
goto fallthrough;
|
||||
#endif
|
||||
|
||||
|
@ -847,13 +852,6 @@ void celldrawer::draw_grid() {
|
|||
|
||||
int prec = grid_prec();
|
||||
|
||||
if(vid.grid && c->bardir != NODIR && c->bardir != NOBARRIERS && c->land != laHauntedWall &&
|
||||
c->barleft != NOWALLSEP_USED && GDIM == 2 && geometry == gNormal && (PURE || BITRUNCATED)) {
|
||||
color_t col = darkena(0x505050, 0, 0xFF);
|
||||
gridline(V, C0, tC0(cgi.heptmove[c->bardir]), col, prec+1);
|
||||
gridline(V, C0, tC0(cgi.hexmove[c->bardir]), col, prec+1);
|
||||
}
|
||||
|
||||
if(inmirrorcount) return;
|
||||
|
||||
if(vid.grid || (c->land == laAsteroids && !(WDIM == 2 && GDIM == 3))) ; else return;
|
||||
|
@ -1386,6 +1384,39 @@ bool celldrawer::set_randompattern_floor() {
|
|||
}
|
||||
|
||||
EX bool numerical_minefield;
|
||||
EX int mine_zero_display = 1;
|
||||
EX bool mine_hollow;
|
||||
EX bool mine_markers;
|
||||
|
||||
EX void draw_mine_numbers(int mines, const shiftmatrix& V, int ct6) {
|
||||
auto hollow = [&] (hpcshape& sh, color_t col) {
|
||||
if(mine_hollow) {
|
||||
dynamicval<color_t> dc(poly_outline, col);
|
||||
queuepoly(V, sh, 0);
|
||||
}
|
||||
else
|
||||
queuepoly(V, sh, col);
|
||||
};
|
||||
if(mines == 0 && mine_zero_display < (WDIM == 3 ? 1 : 2)) return;
|
||||
if(numerical_minefield) {
|
||||
string label = its(mines);
|
||||
queuestr(V, (mines >= 10 ? .5 : 1) * mapfontscale / 100, label, darkened(minecolors[mines]), 8);
|
||||
}
|
||||
else {
|
||||
if(mines >= isize(minecolors)) hollow(cgi.shBigMineMark[ct6], darkena(minecolors[mines/isize(minecolors)], 0, 0xFF));
|
||||
hollow(cgi.shMineMark[ct6], darkena(minecolors[mines], 0, 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
EX void draw_mine_markers(cell *c, const shiftmatrix& V) {
|
||||
if(mine_markers && !mine::marked_safe(c)) {
|
||||
color_t col = 0xFF4040;
|
||||
if(mine::marked_mine(c))
|
||||
col = gradient(winf[waMineMine].color, col, -1, vid.ispeed ? sintick(100) : 1, 1);
|
||||
dynamicval<color_t> dc(poly_outline, (col << 8) | 0xFF);
|
||||
queuepoly(V, cgi.shJoint, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void celldrawer::draw_features() {
|
||||
char xch = winf[c->wall].glyph;
|
||||
|
@ -1631,18 +1662,12 @@ void celldrawer::draw_features() {
|
|||
|
||||
case waMineOpen: {
|
||||
int mines = countMinesAround(c);
|
||||
if(numerical_minefield) {
|
||||
if(mines) {
|
||||
string label = its(mines);
|
||||
queuestr(V, (mines >= 10 ? .5 : 1) * mapfontscale / 100, label, darkened(minecolors[mines]), 8);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(mines >= isize(minecolors))
|
||||
queuepoly(V, cgi.shBigMineMark[ct6], darkena(minecolors[mines/isize(minecolors)], 0, 0xFF));
|
||||
if(mines)
|
||||
queuepoly(V, cgi.shMineMark[ct6], darkena(minecolors[mines], 0, 0xFF));
|
||||
draw_mine_numbers(mines, V, ct6);
|
||||
break;
|
||||
}
|
||||
|
||||
case waMineUnknown: case waMineMine: {
|
||||
draw_mine_markers(c, V);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1772,6 +1797,9 @@ void celldrawer::draw_features_and_walls_3d() {
|
|||
if(anyshiftclick) return;
|
||||
}
|
||||
|
||||
if(among(c->wall, waMineUnknown, waMineMine))
|
||||
draw_mine_markers(c, face_the_player(V));
|
||||
|
||||
if(isWall3(c, wcol)) {
|
||||
if(!no_wall_rendering) {
|
||||
if(c->wall == waChasm && c->land == laMemory && !in_perspective()) {
|
||||
|
@ -1848,6 +1876,12 @@ void celldrawer::draw_features_and_walls_3d() {
|
|||
queuepoly(V, cgi.shPlainWall3D[ofs + a], darkena(wcol2 - d * get_darkval(c, a), 0, 0xFF));
|
||||
}
|
||||
}
|
||||
if(WDIM == 3 && c->wall == waRose) {
|
||||
color_t col = winf[waRose].color;
|
||||
color_t col2 = (col << 8) | 0xFF;
|
||||
if(rosephase == 7) col2 = 0xFFFFFFFF;
|
||||
addradar(V, winf[waRose].glyph, col, col2);
|
||||
}
|
||||
} }
|
||||
else {
|
||||
if(!no_wall_rendering) for(int a=0; a<c->type; a++) if(c->move(a)) {
|
||||
|
@ -1875,9 +1909,7 @@ void celldrawer::draw_features_and_walls_3d() {
|
|||
}
|
||||
else {
|
||||
int mines = countMinesAround(c);
|
||||
if(mines >= isize(minecolors))
|
||||
queuepoly(face_the_player(V), cgi.shBigMineMark[0], darkena(minecolors[mines/isize(minecolors)], 0, 0xFF));
|
||||
queuepoly(face_the_player(V), cgi.shMineMark[0], darkena(minecolors[mines], 0, 0xFF));
|
||||
draw_mine_numbers(mines, face_the_player(V), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2848,7 +2880,7 @@ void celldrawer::draw() {
|
|||
|
||||
if(callhandlers(false, hooks_drawcell, c, V)) return;
|
||||
|
||||
if(history::on || inHighQual || WDIM == 3 || shmup::on || sightrange_bonus > gamerange_bonus || !playermoved) checkTide(c);
|
||||
checkTide(c);
|
||||
|
||||
if(1) {
|
||||
|
||||
|
|
|
@ -5181,3 +5181,101 @@ Bug fixes:
|
|||
* Fixed troll nests in Horodisk/Voronoi.
|
||||
* Fixed a crash when running away from Clearing in single-land mode.
|
||||
* Some values are tracked in savefiles while previously they did not (fatigue, snake oil, crossbow reload time, gun ammo, etc.) (Thanks to jlm)
|
||||
|
||||
2024-03-24 20:10 Update 13.0e:
|
||||
|
||||
* in Steam, option `-achievement-always` to always display achievements, even if you already got them.
|
||||
* rosebushes now show up on the radar in 3D geometries, and they now blink if they are close to going off
|
||||
* if you are in water (and have no Fish), you can now see Orbs of Fish and Aether in adjacent water tiles, and also you can move there and pick them up
|
||||
* crossbow bolt now ignore rose restrictions on attack
|
||||
* migrating to SDL2 caused crashes in shmup, with the game_keys_scroll option, and with the shift-target option -- this should be fixed
|
||||
* 'custom' land list mode is now mentioned in the watermark (bottom left of the screen)
|
||||
|
||||
2024-03-27 23:47 Update 13.0f:
|
||||
|
||||
* new messages on Orb of Phasing, Slaying, and Weakness
|
||||
* more accurate messages on dice pushing
|
||||
* when loading save, load full mode data including custom lands
|
||||
* irregular maps no longer change on every load due to floating point precision
|
||||
* [custom lands list] Space Rock monsters now drop treasure only if in Space Rock land
|
||||
* ineligible starting land also if land is not in game
|
||||
* [custom lands list] do not freeze if no new sealand is available
|
||||
* in countHyperstones, two variants of Mirror are counted once
|
||||
* specially generated lands (horocycles, Brown Islands) now respect Unlocked and LandIngame rules
|
||||
* fixed some more crashes related to SDL2 (e.g., right-click in shmup)
|
||||
|
||||
2024-04-09 02:46 Update 13.0g:
|
||||
|
||||
- New land structures: CR2-like, CR3-like, and "cursed"
|
||||
- Space Rocks and Halloween stuff are now saved correctly (thanks to jlm)
|
||||
- since the Aether users now see adjacent items in water, they can also pick them up
|
||||
- fixed the bug where moving a boat with Compass would cause items to be picked up
|
||||
- pushing an exploding barrel on a mine now causes an explosion
|
||||
- fixed pressing numpad keys with numpad on acting both as moves and quick-keys
|
||||
- a new pseudoheptagon pattern in standard binary and ternary tiling
|
||||
- fixed the Free Fall being not inaccessible from some lands
|
||||
- auto-pause shmup game when it loses focus
|
||||
- fixed some possible crashes: with keys being generated on ivy, when using Orb of Space on Orb of Safety, Ocean in the chaos modes, after killing 400 mutants, when generating YASC message
|
||||
|
||||
2024-05-09 10:45 Update 13.0h
|
||||
|
||||
- Orb of Summoning now works on deep water, shallow water, and Camelot moat tiles
|
||||
- more settings for minefield graphics
|
||||
- removed Haunted and Elemental from the landscape mode
|
||||
- stone gargoyles and statues are now non-blocking for missiles
|
||||
- Orb of Earth now cancels Invisibility only if it is doing something
|
||||
- new line pattern 'wall highlight', and also line patterns are now easier to reach (via creative mode)
|
||||
- fixed the Yendor beacon to appear in the correct place (usually on the boundary, not the closest visible tile)
|
||||
|
||||
Minor bug fixes:
|
||||
- some leaderboards still activated when custom_land_list was used
|
||||
- fixed CR3 generated in CR2 layout
|
||||
- fixed CR2 generated in CR3/CR4 layouts
|
||||
- fixed single wrong tile of the first land when safetying in landscape etc
|
||||
- fixed 534 distance computation
|
||||
- fixed CLI -picload
|
||||
- clear boats from removed Orbs of Water
|
||||
- fixed a crash setting landscape_div to 0
|
||||
- fixed a crash with irregular spherical maps
|
||||
- show weapon watermark with geometric xbow (thanks to @jlm)
|
||||
|
||||
2024-05-10 19:36 Update 13.0i
|
||||
|
||||
- reverted numlock fix on MAC since it apparently does not work as expected
|
||||
- right shift no longer assumes mouse-strafe if no mouse moved
|
||||
- fixed the "display zeros in minefield" option
|
||||
- fixed crashes when adding/deleting colors
|
||||
- rosewaves no longer go through the fake cells in Crystal World
|
||||
- changed the guarding in Power landscape
|
||||
- display Compass and Orb of Yendor beacon on radar
|
||||
- fixed some problems with tides (thanks to jlm)
|
||||
|
||||
2024-05-28 19:35 Update 13.0j
|
||||
|
||||
- display charge count for all orbs, and activation costs for frog-like orbs
|
||||
- "(v) menu" can now be replaced to show turn count or another parameter/formula
|
||||
- Orb of Luck now removes the blue bug bias
|
||||
- fixed the shape pattern for converted tilings
|
||||
- fixed a bug in the tessellation converter
|
||||
- the game spent 5s on startup initializing SDL joysticks -- this now can be avoided
|
||||
- chainspilling lava slimes
|
||||
- more explanation is now available for ON/OFF parameters
|
||||
- fixed product rendering
|
||||
- fixed model orientation for spiral
|
||||
- fixed a crash when changing the 'race angle' setting
|
||||
- fixed a possible crash when trying to build CR2 or CR5 next to CR4
|
||||
|
||||
Changes to the parameter/formula system:
|
||||
- more values and functions are now available in formulas (including the new color formulas, including the 'formula' canvas pattern)
|
||||
|
||||
2024-05-28 20:21 Update 13.0k
|
||||
|
||||
- fixed orb change display
|
||||
- fixed backward incompatible color reading from config
|
||||
- fixed symbol changed enable archimedean unexpectedly
|
||||
|
||||
2024-05-29 13:54 Update 13.0l
|
||||
|
||||
- fixed some more errors with the config file
|
||||
- show charges for Orb of Air, also fixed the line for Orb Energy
|
||||
- fixed some characters not being enterable in SDL2
|
||||
|
|
|
@ -181,9 +181,7 @@ EX bool monstersnear(cell *c, eMonster who) {
|
|||
}
|
||||
|
||||
// consider normal monsters
|
||||
if(c2 &&
|
||||
isArmedEnemy(c2, who) &&
|
||||
(c2->monst != moLancer || isUnarmed(who) || !logical_adjacent(c, who, c2))) {
|
||||
if(c2 && isArmedEnemy(c2, who)) {
|
||||
eMonster m = c2->monst;
|
||||
if(elec::affected(c2)) continue;
|
||||
if(fast && c2->monst != moWitchSpeed) continue;
|
||||
|
@ -390,7 +388,7 @@ EX void create_yasc_message() {
|
|||
if(captures.size() == 2 && context.size() == 1 && cwt.at->type == 6) {
|
||||
vector<int> dirs;
|
||||
forCellIdEx(c1, i, cwt.at) for(auto cap: captures) if(cap.first == c1) dirs.push_back(i);
|
||||
if(abs(dirs[0]-dirs[1]) == 3) {
|
||||
if(isize(dirs) == 2 && abs(dirs[0]-dirs[1]) == 3) {
|
||||
auto c1 = captures.begin(); c1++;
|
||||
yasc_message = XLAT("pinched by %the1 and %the2", captures.begin()->second, c1->second);
|
||||
}
|
||||
|
|
|
@ -105,11 +105,7 @@ EX namespace arg {
|
|||
EX bool argis(const string& s) { if(args()[0] == '-' && args()[1] == '-') return args().substr(1) == s; return args() == s; }
|
||||
|
||||
EX color_t argcolor(int bits) {
|
||||
string s = args();
|
||||
auto p = find_color_by_name(s);
|
||||
if(p && bits == 24) return p->second;
|
||||
if(p && bits == 32) return (p->second << 8) | 0xFF;
|
||||
return strtoll(argcs(), NULL, 16);
|
||||
return parsecolor(args(), bits == 32);
|
||||
}
|
||||
|
||||
int parameter_id;
|
||||
|
@ -445,6 +441,8 @@ EX hookset<int()> hooks_args;
|
|||
|
||||
EX map<string, pair<int, reaction_t>> *added_commands;
|
||||
|
||||
EX bool delayed_start;
|
||||
|
||||
EX namespace arg {
|
||||
|
||||
int read_added_commands() {
|
||||
|
@ -477,6 +475,7 @@ EX namespace arg {
|
|||
void read(int phase) {
|
||||
curphase = phase;
|
||||
callhooks(hooks_config);
|
||||
dynamicval<bool> ds(delayed_start, true);
|
||||
while(pos < isize(argument)) {
|
||||
int r = callhandlers(1, hooks_args);
|
||||
switch (r) {
|
||||
|
|
|
@ -648,7 +648,7 @@ struct info {
|
|||
if(newdist == OUT_OF_PRISON && princess::challenge) {
|
||||
addMessage(XLAT("Congratulations! Your score is %1.", its(i->value)));
|
||||
achievement_gain_once("PRINCESS2", rg::princess);
|
||||
if(!cheater) achievement_score(36, i->value);
|
||||
if(!cheater) achievement_score(LB_PRINCESS, i->value);
|
||||
LATE( showMissionScreen(); )
|
||||
}
|
||||
}
|
||||
|
@ -1688,6 +1688,7 @@ EX namespace hive {
|
|||
|
||||
EX eMonster randomHyperbug() {
|
||||
int h = hivehard();
|
||||
if(h && markOrb(itOrbLuck)) h /= 4;
|
||||
if(hrand(200) < h)
|
||||
return moBug2;
|
||||
return eMonster(moBug0 + hrand(BUGCOLORS));
|
||||
|
|
|
@ -354,6 +354,8 @@ vector<string> knight_names = {
|
|||
"JeLomun", "kip", "Warmonger", "Fooruman", "Zyalin", "Prezombie", "ashley89", "bjobae", "MFErtre", "Roaringdragon2", "howilovepi", "Yulgash", "Sir Endipitous", "Roshlev",
|
||||
"BTernaryTau", "HiGuy", "coper", "Tirear", "qoala _", "Tyzone", "Tiegon", "Airin", "Metroid26", "Sklorg", "Fumblestealth", "Toph", "Tzaphqiel", "jruderman", "ray",
|
||||
"Deathroll", "Sinquetica", "mootmoot", "Noobinator", "freeofme", "Helyea", "Snakebird Priestess", "brisingre", "Khashishi", "Shiny", "kabado", "Berenthas", "Misery", "Altripp", "Aldrenean",
|
||||
// via itch.io and reports on Discord
|
||||
"AntiRogue"
|
||||
};
|
||||
|
||||
map<cell*, int> knight_id;
|
||||
|
|
1486
config.cpp
1486
config.cpp
File diff suppressed because it is too large
Load Diff
|
@ -973,7 +973,7 @@ WALL( '+', 0xFF0000, "giant rug", waGiantRug, ZERO | WF_ON, RESERVED, 0, sgNone,
|
|||
"This is the biggest Hypersian Rug you have ever seen! "
|
||||
"Unfortunately, it is too large to take it as a trophy." )
|
||||
WALL( '#', 0xfffff0, "platform", waPlatform, WF_WALL | WF_HIGHWALL, RESERVED, 0, sgNone, "You can stand here.")
|
||||
WALL( '#', 0x909090, "stone gargoyle", waGargoyle, WF_WALL | WF_HIGHWALL, RESERVED, 0, sgNone, gargdesc)
|
||||
WALL( '#', 0x909090, "stone gargoyle", waGargoyle, WF_WALL | WF_HIGHWALL | WF_NONBLOCK, RESERVED, 0, sgNone, gargdesc)
|
||||
WALL( '.', 0xB0B0B0, "stone gargoyle floor", waGargoyleFloor, ZERO | WF_ON, RESERVED, 1, sgNone, gargdesc)
|
||||
WALL( '.', 0x909090, "rubble", waRubble, ZERO | WF_ON, RESERVED, 1, sgNone, "Some rubble.")
|
||||
WALL( '+', 0x804000, "ladder", waLadder, ZERO | WF_ON, RESERVED, 0, sgNone,
|
||||
|
@ -1018,7 +1018,7 @@ WALL( '+', 0x60C060, "canopy", waCanopy, ZERO, RESERVED, 0, sgNone,
|
|||
)
|
||||
WALL( '#', 0xD0C060, "barrow wall", waBarrowWall, WF_WALL | WF_HIGHWALL, RESERVED, 0, sgNone, "This wall is quite strong. You will need another way in.")
|
||||
WALL( '#', 0x90A060, "barrow", waBarrowDig, WF_WALL | WF_HIGHWALL, RESERVED, 0, sgNone, "Your Orb of the Sword can be used to dig here.")
|
||||
WALL( '#', 0xE0E0E0, "stone statue", waPetrified, WF_WALL | WF_HIGHWALL, RESERVED, 0, sgNone, "A petrified creature.")
|
||||
WALL( '#', 0xE0E0E0, "stone statue", waPetrified, WF_WALL | WF_HIGHWALL | WF_NONBLOCK, RESERVED, 0, sgNone, "A petrified creature.")
|
||||
WALL( '.', 0xE8E8E8, "tower of Camelot", waTower, ZERO, RESERVED, 3, sgNone, camelothelp)
|
||||
WALL( '-', 0x402000, "big bush", waBigBush, ZERO | WF_NOFLIGHT | WF_ON, RESERVED, 0, sgNone,
|
||||
"You can hold this bush to climb the Lost Mountain. "
|
||||
|
@ -1298,7 +1298,7 @@ LAND( 0xE08020, "Canvas", laCanvas, ZERO | LF_TECHNICAL, itNone, RESERVED, "A fa
|
|||
|
||||
LAND( 0x00C000, "Palace Quest", laPrincessQuest, ZERO, itSavedPrincess, RESERVED, princessdesc) // fake
|
||||
NATIVE(isNative(laPalace, m))
|
||||
REQ(ACCONLY(laPalace) KILL(moVizier, laPalace))
|
||||
REQ(ACCONLY(laPalace) INMODE(princess::challenge) KILL(moVizier, laPalace))
|
||||
|
||||
LAND( 0xD0D060, "Wild West", laWildWest, ZERO, itBounty, RESERVED, wildwestdesc)
|
||||
NATIVE((m == moOutlaw) ? 2 : 0)
|
||||
|
@ -1798,3 +1798,4 @@ MONSTER( '*', 0, "vertex", moRogueviz, ZERO | CF_TECHNICAL, RESERVED, moN
|
|||
#undef ACCONLY3
|
||||
#undef ACCONLYF
|
||||
#undef IFINGAME
|
||||
#undef INMODE
|
||||
|
|
66
control.cpp
66
control.cpp
|
@ -212,16 +212,30 @@ EX void mousemovement() {
|
|||
EX SDL_Joystick* sticks[8];
|
||||
EX int numsticks;
|
||||
|
||||
EX void initJoysticks() {
|
||||
EX bool joysticks_initialized;
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
|
||||
{
|
||||
printf("Failed to initialize joysticks.\n");
|
||||
numsticks = 0;
|
||||
return;
|
||||
#if HDR
|
||||
enum eJoystickInit { jiNoJoystick, jiFast, jiWait };
|
||||
#endif
|
||||
EX eJoystickInit joy_init = jiFast;
|
||||
|
||||
#if CAP_THREAD
|
||||
EX std::thread *joythread;
|
||||
std::atomic<bool> joystick_done(false);
|
||||
#endif
|
||||
|
||||
EX void initJoysticks_async() {
|
||||
if(joy_init == jiNoJoystick) return;
|
||||
#if CAP_THREAD
|
||||
if(joy_init == jiWait) { initJoysticks(); return; }
|
||||
joythread = new std::thread([] { initJoysticks(); joystick_done = true; });
|
||||
#else
|
||||
initJoysticks();
|
||||
#endif
|
||||
}
|
||||
|
||||
DEBB(DF_INIT, ("init joysticks"));
|
||||
EX void countJoysticks() {
|
||||
DEBB(DF_INIT, ("opening joysticks"));
|
||||
numsticks = SDL_NumJoysticks();
|
||||
if(numsticks > 8) numsticks = 8;
|
||||
for(int i=0; i<numsticks; i++) {
|
||||
|
@ -235,6 +249,22 @@ EX void initJoysticks() {
|
|||
}
|
||||
}
|
||||
|
||||
EX void initJoysticks() {
|
||||
|
||||
DEBBI(DF_INIT, ("init joystick"));
|
||||
|
||||
DEBB(DF_INIT, ("init joystick subsystem"));
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
|
||||
{
|
||||
printf("Failed to initialize joysticks.\n");
|
||||
numsticks = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
countJoysticks();
|
||||
joysticks_initialized = true;
|
||||
}
|
||||
|
||||
EX void closeJoysticks() {
|
||||
DEBB(DF_INIT, ("close joysticks"));
|
||||
for(int i=0; i<numsticks; i++) {
|
||||
|
@ -376,6 +406,7 @@ EX void full_ystrafe_camera(ld t) {
|
|||
EX ld third_person_rotation = 0;
|
||||
|
||||
EX void full_rotate_camera(int dir, ld val) {
|
||||
if(!val) return;
|
||||
if(rug::rug_control() && lshiftclick) {
|
||||
val *= camera_rot_speed;
|
||||
hyperpoint h;
|
||||
|
@ -524,7 +555,7 @@ EX void handleKeyNormal(int sym, int uni) {
|
|||
|
||||
if(!(uni >= 'A' && uni <= 'Z') && DEFAULTCONTROL && !game_keys_scroll) {
|
||||
for(int i=0; i<8; i++)
|
||||
if(among(sym, keys_vi[i], keys_wasd[i], keys_numpad[i]))
|
||||
if(among(sym, keys_vi[i], keys_wasd[i], (uni >= '0' && uni <= '9' && !ISMAC) ? -1 : keys_numpad[i]))
|
||||
movepckeydir(i);
|
||||
}
|
||||
|
||||
|
@ -872,7 +903,7 @@ EX void mainloopiter() {
|
|||
targetclick = pandora_leftclick | pandora_rightclick;
|
||||
pandora_leftclick = pandora_rightclick = 0;
|
||||
#else
|
||||
targetclick = keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT];
|
||||
targetclick = keystate[SDL12(SDLK_RSHIFT, SDL_SCANCODE_RSHIFT)] | keystate[SDL12(SDLK_LSHIFT, SDL_SCANCODE_LSHIFT)];
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
@ -957,7 +988,7 @@ EX void mainloopiter() {
|
|||
}
|
||||
else sc_ticks = ticks;
|
||||
|
||||
if(game_keys_scroll && !shmup::on && (cmode & sm::NORMAL) && !keystate[SDLK_LALT] && !keystate[SDLK_RALT]) {
|
||||
if(game_keys_scroll && !shmup::on && (cmode & sm::NORMAL) && !keystate[SDL12(SDLK_LALT, SDL_SCANCODE_LALT)] && !keystate[SDL12(SDLK_RALT, SDL_SCANCODE_RALT)]) {
|
||||
rug::using_rugview urv;
|
||||
auto& lastticks = sc_ticks2;
|
||||
ld t = (ticks - lastticks) * shiftmul / 1000.;
|
||||
|
@ -999,6 +1030,7 @@ EX void mainloopiter() {
|
|||
fix_mouseh();
|
||||
#if CAP_SDLJOY
|
||||
if(joydir.d != -1) checkjoy();
|
||||
if(joystick_done && joythread) { joythread->join(); delete joythread; joystick_done = false; }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1014,8 +1046,7 @@ EX void handle_event(SDL_Event& ev) {
|
|||
/* if(ev.type == SDL_JOYDEVICEADDED || ev.type == SDL_JOYDEVICEREMOVED) {
|
||||
joyx = joyy = 0;
|
||||
panjoyx = panjoyy = 0;
|
||||
closeJoysticks();
|
||||
initJoysticks();
|
||||
countJoysticks();
|
||||
} */
|
||||
|
||||
#if CAP_SDL2
|
||||
|
@ -1100,6 +1131,17 @@ EX void handle_event(SDL_Event& ev) {
|
|||
sym = ev.key.keysym.sym;
|
||||
#if CAP_SDL2
|
||||
uni = ev.key.keysym.sym;
|
||||
if(uni == '=' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '+';
|
||||
if(uni == '1' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '!';
|
||||
if(uni == '2' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '@';
|
||||
if(uni == '3' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '#';
|
||||
if(uni == '4' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '$';
|
||||
if(uni == '5' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '%';
|
||||
if(uni == '6' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '^';
|
||||
if(uni == '7' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '&';
|
||||
if(uni == '8' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '*';
|
||||
if(uni == '9' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = '(';
|
||||
if(uni == '0' && (ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) uni = ')';
|
||||
if(uni >= 'a' && uni <= 'z') {
|
||||
if(ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) uni -= 32;
|
||||
else if(ev.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) uni -= 96;
|
||||
|
|
|
@ -28,6 +28,7 @@ EX namespace bow {
|
|||
#if HDR
|
||||
enum eWeapon { wBlade, wCrossbow };
|
||||
enum eCrossbowStyle { cbBull, cbGeodesic, cbGeometric };
|
||||
const string bowName[] = { "bull", "geod", "geom" };
|
||||
#endif
|
||||
|
||||
EX eWeapon weapon;
|
||||
|
|
|
@ -660,6 +660,9 @@ int read_cheat_args() {
|
|||
PHASEFROM(2);
|
||||
shift(); vid.stereo_mode = eStereo(argi());
|
||||
}
|
||||
else if(argis("-save-cheats")) {
|
||||
save_cheats = true;
|
||||
}
|
||||
else if(argis("-cmove")) {
|
||||
PHASE(3); shift();
|
||||
for(char c: args()) cheat_move(c);
|
||||
|
|
73
dialogs.cpp
73
dialogs.cpp
|
@ -70,12 +70,20 @@ EX namespace dialog {
|
|||
scaler sc;
|
||||
int *intval; ld intbuf;
|
||||
bool animatable;
|
||||
bool *boolval;
|
||||
void draw() override;
|
||||
void apply_edit();
|
||||
void apply_slider();
|
||||
string disp(ld x);
|
||||
void reset_str() { s = disp(*editwhat); }
|
||||
};
|
||||
|
||||
/** bool dialog */
|
||||
struct bool_dialog : extdialog {
|
||||
bool *editwhat, dft;
|
||||
reaction_t switcher;
|
||||
void draw() override;
|
||||
};
|
||||
#endif
|
||||
|
||||
EX number_dialog& get_ne() {
|
||||
|
@ -215,12 +223,16 @@ EX namespace dialog {
|
|||
EX string keyname(int k) {
|
||||
if(k == 0) return "";
|
||||
if(k == SDLK_ESCAPE) return "Esc";
|
||||
if(k == SDLK_F5) return "F5";
|
||||
if(k == SDLK_F10) return "F10";
|
||||
if(k == SDLK_F9) return "F9";
|
||||
if(k == SDLK_F1) return "F1";
|
||||
if(k == SDLK_F4) return "F4";
|
||||
if(k == SDLK_F2) return "F2";
|
||||
if(k == SDLK_F3) return "F3";
|
||||
if(k == SDLK_F4) return "F4";
|
||||
if(k == SDLK_F5) return "F5";
|
||||
if(k == SDLK_F6) return "F6";
|
||||
if(k == SDLK_F7) return "F7";
|
||||
if(k == SDLK_F8) return "F8";
|
||||
if(k == SDLK_F9) return "F9";
|
||||
if(k == SDLK_F10) return "F10";
|
||||
if(k >= 10000 && k < 10500) return "";
|
||||
if(k == SDLK_HOME) return "Home";
|
||||
if(k == SDLK_BACKSPACE) return "Backspace";
|
||||
|
@ -1227,6 +1239,7 @@ EX namespace dialog {
|
|||
if(p) p->load_as_animation(formula);
|
||||
}
|
||||
catch(hr_parse_exception&) { }
|
||||
catch(param_exception&) { }
|
||||
};
|
||||
dialog::get_di().dialogflags |= dialogflags;
|
||||
});
|
||||
|
@ -1298,6 +1311,7 @@ EX namespace dialog {
|
|||
}
|
||||
catch(const hr_parse_exception&) {
|
||||
}
|
||||
catch(param_exception&) { }
|
||||
}
|
||||
|
||||
EX void bound_low(ld val) {
|
||||
|
@ -1368,12 +1382,12 @@ EX namespace dialog {
|
|||
dialog::addBreak(50);
|
||||
auto f = find_edit(!ptr ? nullptr : ne.intval ? (void*) ne.intval : (void*) ne.editwhat);
|
||||
if(f)
|
||||
dialog::addHelp(XLAT("Parameter names, e.g. '%1'", f->parameter_name));
|
||||
dialog::addHelp(XLAT("Parameter names, e.g. '%1'", f->name));
|
||||
else
|
||||
dialog::addHelp(XLAT("Parameter names"));
|
||||
dialog::addBreak(50);
|
||||
for(auto& ap: anims::aps) {
|
||||
dialog::addInfo(ap.par->parameter_name + " = " + ap.formula);
|
||||
dialog::addInfo(ap.par->name + " = " + ap.formula);
|
||||
}
|
||||
#endif
|
||||
dialog::addBreak(50);
|
||||
|
@ -1486,6 +1500,42 @@ EX namespace dialog {
|
|||
};
|
||||
}
|
||||
|
||||
void bool_dialog::draw() {
|
||||
cmode = dialogflags;
|
||||
gamescreen();
|
||||
init(title);
|
||||
|
||||
dialog::addBreak(100);
|
||||
|
||||
auto switch_to = [this] (bool b) {
|
||||
bool do_switch = (*editwhat != b);
|
||||
auto sw = switcher;
|
||||
auto re = reaction;
|
||||
popScreen();
|
||||
if(do_switch) { sw(); if(re) re(); }
|
||||
};
|
||||
|
||||
dialog::addBoolItem(XLAT("disable"), false, '0');
|
||||
dialog::add_action([switch_to] { switch_to(false); });
|
||||
|
||||
dialog::addBoolItem(XLAT("enable"), true, '1');
|
||||
dialog::add_action([switch_to] { switch_to(true); });
|
||||
|
||||
dialog::addBoolItem(XLAT("switch"), !*editwhat, 's');
|
||||
dialog::add_action([switch_to, this] { switch_to(!*editwhat); });
|
||||
|
||||
dialog::addBoolItem(XLAT("set default"), dft, 'd');
|
||||
dialog::add_action([switch_to, this] { switch_to(dft); });
|
||||
|
||||
dialog::addBreak(100);
|
||||
|
||||
if(help != "") addHelp(help);
|
||||
|
||||
if(extra_options) extra_options();
|
||||
|
||||
display();
|
||||
}
|
||||
|
||||
int nlpage = 1;
|
||||
int wheelshift = 0;
|
||||
|
||||
|
@ -1565,6 +1615,17 @@ EX namespace dialog {
|
|||
return get_ne();
|
||||
}
|
||||
|
||||
EX extdialog& editBool(bool& b, bool dft, string title, string help, const reaction_t& switcher) {
|
||||
bool_dialog be;
|
||||
be.editwhat = &b;
|
||||
be.dft = dft;
|
||||
be.title = title;
|
||||
be.help = help;
|
||||
be.switcher = switcher;
|
||||
pushScreen(be);
|
||||
return get_di();
|
||||
}
|
||||
|
||||
EX number_dialog& editNumber(int& x, int vmin, int vmax, ld step, int dft, string title, string help) {
|
||||
ld tmp;
|
||||
auto& ne = editNumber(tmp, vmin, vmax, step, dft, title, help);
|
||||
|
|
|
@ -402,7 +402,7 @@ struct emb_none : embedding_method {
|
|||
return embedding_method::flatten(a);
|
||||
}
|
||||
|
||||
hyperpoint normalize_flat(hyperpoint a) override { return normalize(a); }
|
||||
hyperpoint normalize_flat(hyperpoint a) override { return gproduct ? flatten(a) : normalize(a); }
|
||||
|
||||
transmatrix base_to_actual(const transmatrix& T) override { return T; }
|
||||
hyperpoint base_to_actual(hyperpoint h) override { return h; }
|
||||
|
|
|
@ -368,7 +368,7 @@ EX void bfs() {
|
|||
c2->wall = waSea;
|
||||
|
||||
if(c2 && signed(c2->cpdist) > d+1) {
|
||||
if(WDIM == 3 && !gmatrix.count(c2)) {
|
||||
if(WDIM == 3 && (d > 2 && !gmatrix.count(c2))) {
|
||||
if(!first7) first7 = qb;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Hyperbolic Rogue -- fake mobile target
|
||||
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
||||
//
|
||||
// Compile with: g++ fake-mobile.cpp -o fake-mobile -I/usr/include/SDL -lSDL -lSDL_gfx -lGL -lSDL_ttf -lz -Wno-invalid-offsetof
|
||||
|
||||
#define ISFAKEMOBILE 1
|
||||
#define MOBPAR_FORMAL int
|
||||
|
@ -9,7 +11,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace hr {
|
||||
string scorefile = "fakemobile_score.txt";
|
||||
std::string scorefile = "fakemobile_score.txt";
|
||||
}
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
@ -55,6 +57,17 @@ int gdpop() { return graphdata[gdpos++]; }
|
|||
|
||||
TTF_Font *font[256];
|
||||
|
||||
const char* fontname = "DejaVuSans-Bold.ttf";
|
||||
|
||||
void load_font() {
|
||||
if(!font[size])
|
||||
font[size] = TTF_OpenFont(fontname, size);
|
||||
if(!font[size]) {
|
||||
fprintf(stderr, "failed to open font: %s", fontname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool rawdisplaystr(int x, int y, int shift, int size, const char *str, int color, int align) {
|
||||
|
||||
if(strlen(str) == 0) return false;
|
||||
|
@ -69,8 +82,7 @@ bool rawdisplaystr(int x, int y, int shift, int size, const char *str, int color
|
|||
|
||||
col.r >>= darken; col.g >>= darken; col.b >>= darken;
|
||||
|
||||
if(!font[size])
|
||||
font[size] = TTF_OpenFont("VeraBd.ttf", size);
|
||||
load_font();
|
||||
|
||||
SDL_Surface *txt = TTF_RenderText_Solid(font[size], str, col);
|
||||
|
||||
|
@ -95,7 +107,7 @@ bool rawdisplaystr(int x, int y, int shift, int size, const char *str, int color
|
|||
int textwidth(int siz, const string &str) {
|
||||
if(isize(str) == 0) return 0;
|
||||
|
||||
if(!font[siz]) font[siz] = TTF_OpenFont("VeraBd.ttf", siz);
|
||||
load_font();
|
||||
|
||||
int w, h;
|
||||
TTF_SizeUTF8(font[siz], str.c_str(), &w, &h);
|
||||
|
|
1
fake.cpp
1
fake.cpp
|
@ -75,6 +75,7 @@ EX namespace fake {
|
|||
}
|
||||
|
||||
hrmap_fake() {
|
||||
underlying_map = nullptr;
|
||||
in_underlying([this] { initcells(); underlying_map = currentmap; });
|
||||
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
|
||||
}
|
||||
|
|
2
game.cpp
2
game.cpp
|
@ -347,6 +347,8 @@ EX void pushThumper(const movei& mi) {
|
|||
if(w == waThumperOn)
|
||||
explode = 2;
|
||||
}
|
||||
if(w == waExplosiveBarrel && cto->wall == waMineMine)
|
||||
explode = 2;
|
||||
destroyTrapsOn(cto);
|
||||
if(cto->wall == waOpenPlate || cto->wall == waClosePlate) {
|
||||
toggleGates(cto, cto->wall);
|
||||
|
|
15
geom-exp.cpp
15
geom-exp.cpp
|
@ -944,6 +944,13 @@ EX geometry_data compute_geometry_data() {
|
|||
return gd;
|
||||
}
|
||||
|
||||
EX void add_size_action() {
|
||||
if(WDIM == 2 || reg3::exact_rules()) dialog::add_action([] {
|
||||
if(!viewdists) { enable_viewdists(); pushScreen(viewdist_configure_dialog); }
|
||||
else if(viewdists) viewdists = false;
|
||||
});
|
||||
}
|
||||
|
||||
EX void showEuclideanMenu() {
|
||||
// for(int i=2; i<lt; i++) landvisited[i] = true;
|
||||
|
||||
|
@ -1113,7 +1120,7 @@ EX void showEuclideanMenu() {
|
|||
}
|
||||
|
||||
dialog::addBoolItem(XLAT("pattern"), specialland == laCanvas, 'p');
|
||||
if(specialland == laCanvas) dialog::lastItem().value = patterns::whichCanvas;
|
||||
if(specialland == laCanvas) dialog::lastItem().value = ccolor::which->name;
|
||||
dialog::add_action_push(patterns::showPrePattern);
|
||||
validity_info();
|
||||
if(WDIM == 3) {
|
||||
|
@ -1151,11 +1158,7 @@ EX void showEuclideanMenu() {
|
|||
}
|
||||
|
||||
dialog::addSelItem(XLAT("size of the world"), gd.size_str, '3');
|
||||
|
||||
if(WDIM == 2 || reg3::exact_rules()) dialog::add_action([] {
|
||||
if(!viewdists) { enable_viewdists(); pushScreen(viewdist_configure_dialog); }
|
||||
else if(viewdists) viewdists = false;
|
||||
});
|
||||
add_size_action();
|
||||
|
||||
if(closed_manifold) {
|
||||
dialog::addSelItem(XLAT("Euler characteristics"), its(gd.euler), 0);
|
||||
|
|
|
@ -1177,7 +1177,7 @@ EX namespace geom3 {
|
|||
}
|
||||
|
||||
EX void apply_settings_full() {
|
||||
if(vid.always3) {
|
||||
if(cgip && vid.always3) {
|
||||
changing_embedded_settings = true;
|
||||
geom3::switch_fpp();
|
||||
#if MAXMDIM >= 4
|
||||
|
@ -1192,7 +1192,7 @@ EX namespace geom3 {
|
|||
|
||||
EX void apply_settings_light() {
|
||||
#if MAXMDIM >= 4
|
||||
if(vid.always3) {
|
||||
if(cgip && vid.always3) {
|
||||
changing_embedded_settings = true;
|
||||
geom3::switch_always3();
|
||||
geom3::switch_always3();
|
||||
|
|
|
@ -1269,6 +1269,7 @@ EX namespace gp {
|
|||
}
|
||||
|
||||
hrmap_inverse() {
|
||||
underlying_map = nullptr;
|
||||
if(0) {
|
||||
println(hlog, "making ucgi");
|
||||
dynamicval<eVariation> gva(variation, variation_for(param));
|
||||
|
|
35
graph.cpp
35
graph.cpp
|
@ -209,6 +209,7 @@ void drawSpeed(const shiftmatrix& V, ld scale=1) {
|
|||
}
|
||||
|
||||
void drawSafety(const shiftmatrix& V, int ct) {
|
||||
if(inHighQual) return;
|
||||
#if CAP_QUEUE
|
||||
ld ds = ptick(50);
|
||||
color_t col = darkena(iinf[itOrbSafety].color, 0, 0xFF);
|
||||
|
@ -878,6 +879,7 @@ EX bool mark_compass(cell *c, shiftpoint& P1) {
|
|||
// queuestr(V, 1, its(compassDist(c)), 0x10101 * int(128 - 100 * sin(ticks / 150.)), 1);
|
||||
queue_goal_text(P1, 1, its(-compassDist(c)), 0x10101 * int(128 - 100 * sintick(150)));
|
||||
addauraspecial(P1, 0xFF0000, 0);
|
||||
addradar(P, 'X', iinf[itCompass].color, 0xFF, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -4028,12 +4030,16 @@ EX int colorhash(color_t i) {
|
|||
return (i * 0x471211 + i*i*0x124159 + i*i*i*0x982165) & 0xFFFFFF;
|
||||
}
|
||||
|
||||
EX int mine_opacity = 255;
|
||||
|
||||
EX bool isWall3(cell *c, color_t& wcol) {
|
||||
if(c->wall == waRose) { wcol = gradient(0, wcol, -5 - 5 * (7-rosephase), sintick(50 * (8 - rosephase)), 1); }
|
||||
if(isWall(c)) return true;
|
||||
if(c->wall == waChasm && c->land == laMemory && (anyshiftclick || !(cgflags & qFRACTAL))) { wcol = 0x606000; return true; }
|
||||
if(c->wall == waInvisibleFloor) return false;
|
||||
// if(chasmgraph(c)) return true;
|
||||
if(among(c->wall, waMirror, waCloud, waMineUnknown, waMineMine)) return true;
|
||||
if(among(c->wall, waMirror, waCloud)) return true;
|
||||
if(among(c->wall, waMineUnknown, waMineMine) && mine_opacity == 255) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4076,6 +4082,8 @@ EX color_t transcolor(cell *c, cell *c2, color_t wcol) {
|
|||
}
|
||||
if(among(c->wall, waRubble, waDeadfloor2) && !snakelevel(c2)) return darkena3(winf[c->wall].color, 0, 0x40);
|
||||
if(c->wall == waMagma && c2->wall != waMagma) return darkena3(magma_color(lavatide(c, -1)/4), 0, 0x80);
|
||||
if(among(c->wall, waMineUnknown, waMineMine) && !among(c2->wall, waMineMine, waMineUnknown) && mine_opacity > 0 && mine_opacity < 255)
|
||||
return 0xFFFFFF00 | mine_opacity;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4793,13 +4801,13 @@ EX void drawMarkers() {
|
|||
using namespace yendor;
|
||||
if(yii < isize(yi) && !yi[yii].found) {
|
||||
cell *keycell = NULL;
|
||||
int i;
|
||||
for(i=0; i<YDIST; i++)
|
||||
int last_i = 0;
|
||||
for(int i=0; i<YDIST; i++)
|
||||
if(yi[yii].path[i]->cpdist <= get_sightrange_ambush()) {
|
||||
keycell = yi[yii].path[i];
|
||||
keycell = yi[yii].path[i]; last_i = i;
|
||||
}
|
||||
if(keycell) {
|
||||
for(; i<YDIST; i++) {
|
||||
for(int i = last_i+1; i<YDIST; i++) {
|
||||
cell *c = yi[yii].path[i];
|
||||
if(inscreenrange(c))
|
||||
keycell = c;
|
||||
|
@ -4812,12 +4820,12 @@ EX void drawMarkers() {
|
|||
int cd2 = celldistance(cwt.at, yi[yii].path[i2]);
|
||||
if(cd2 != DISTANCE_UNKNOWN) {
|
||||
cd = cd2 + (YDIST-1-i2);
|
||||
println(hlog, "i2 = ", i2, " cd = ", celldistance(cwt.at, keycell));
|
||||
}
|
||||
}
|
||||
queue_goal_text(H, 1, its(cd), 0x10101 * int(128 - 100 * sintick(150)));
|
||||
#endif
|
||||
addauraspecial(H, iinf[itOrbYendor].color, 0);
|
||||
addradar(ggmatrix(keycell), 'X', iinf[itKey].color, kind_outline(itKey), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5666,6 +5674,8 @@ EX bool just_refreshing;
|
|||
EX int menu_darkening = 2;
|
||||
EX bool centered_menus = false;
|
||||
|
||||
EX string menu_format = "";
|
||||
|
||||
EX void gamescreen() {
|
||||
|
||||
if(cmode & sm::NOSCR) {
|
||||
|
@ -5791,13 +5801,15 @@ EX void normalscreen() {
|
|||
cmode = sm::NORMAL | sm::DOTOUR | sm::CENTER;
|
||||
if(viewdists && show_distance_lists) cmode |= sm::SIDE | sm::MAYDARK;
|
||||
gamescreen(); drawStats();
|
||||
if(nomenukey || ISMOBILE)
|
||||
if(menu_format != "")
|
||||
displayButton(vid.xres-8, vid.yres-vid.fsize, eval_programmable_string(menu_format), 'v', 16);
|
||||
else if(nomenukey || ISMOBILE)
|
||||
;
|
||||
#if CAP_TOUR
|
||||
else if(tour::on)
|
||||
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(ESC) tour menu"), SDLK_ESCAPE, 16);
|
||||
else
|
||||
#endif
|
||||
else
|
||||
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
|
||||
keyhandler = handleKeyNormal;
|
||||
|
||||
|
@ -5922,8 +5934,11 @@ EX void drawscreen() {
|
|||
color_t col = linf[cwt.at->land].color;
|
||||
if(cwt.at->land == laRedRock) col = 0xC00000;
|
||||
if(titlecolor) col = titlecolor;
|
||||
if(nohelp != 1)
|
||||
displayfr(vid.xres/2, vid.fsize, 2, vid.fsize, mouseovers, col, 8);
|
||||
if(nohelp != 1) {
|
||||
int size = vid.fsize;
|
||||
while(size > 3 && textwidth(size, mouseovers) > vid.xres) size--;
|
||||
displayfr(vid.xres/2, vid.fsize, 2, size, mouseovers, col, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
drawmessages();
|
||||
|
|
49
help.cpp
49
help.cpp
|
@ -236,12 +236,12 @@ EX void buildCredits() {
|
|||
help += XLAT(
|
||||
"special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n",
|
||||
"Konstantin Stupnik, ortoslon, chrysn, Adam Borowski, Damyan Ivanov, Ryan Farnsley, mcobit, Darren Grey, tricosahedron, Maciej Chojecki, Marek Čtrnáct, "
|
||||
"wonderfullizardofoz, Piotr Migdał, tehora, Michael Heerdegen, Sprite Guard, zelda0x181e, Vipul, snowyowl0, Patashu, phenomist, Alan Malloy, Tom Fryers, Sinquetica, _monad, CtrlAltDestroy, jruderman, "
|
||||
"wonderfullizardofoz, Piotr Migdał, Tehora Rogue, Michael Heerdegen, Sprite Guard, zelda0x181e, Vipul, snowyowl0, Patashu, phenomist, Alan Malloy, Tom Fryers, Sinquetica, _monad, CtrlAltDestroy, jruderman, "
|
||||
"Kojiguchi Kazuki, baconcow, Alan, SurelyYouJest, hotdogPi, DivisionByZero, xXxWeedGokuxXx, jpystynen, Dmitry Marakasov, Alexandre Moine, Arthur O'Dwyer, "
|
||||
"Triple_Agent_AAA, bluetailedgnat, Allalinor, Shitford, KittyTac, Christopher King, KosGD, TravelDemon, Bubbles, rdococ, frozenlake, MagmaMcFry, "
|
||||
"Snakebird Priestess, roaringdragon2, Stopping Dog, bengineer8, Sir Light IJIJ, ShadeBlade, Saplou, shnourok, Ralith, madasa, 6% remaining, Chimera245, Remik Pi, alien foxcat thing, "
|
||||
"Piotr Grochowski, Ann, still-flow, tyzone, Paradoxica, LottieRatWorld, aismallard, albatross, EncodedSpirit, Jacob Mandelson, CrashTuvai, cvoight, jennlbw, Kali Ranya, spiritbackup, Dylan, L_Lord, AntiRogue, "
|
||||
"masonlgreen, A human"
|
||||
"masonlgreen, A human, Pasu4"
|
||||
);
|
||||
#ifdef EXTRALICENSE
|
||||
help += EXTRALICENSE;
|
||||
|
@ -528,6 +528,33 @@ EX string generateHelpForItem(eItem it) {
|
|||
}
|
||||
}
|
||||
|
||||
int oc = orbcharges(it); if(oc) {
|
||||
|
||||
if(items[itOrbIntensity]) {
|
||||
int oc2 = intensify(oc);
|
||||
help += XLAT("\n\nOrb charges gained on pickup: %1 (increased to %2 by %the3)", its(oc), its(oc2), itOrbIntensity);
|
||||
}
|
||||
else
|
||||
help += XLAT("\n\nOrb charges gained on pickup: %1", its(oc));
|
||||
}
|
||||
|
||||
int ac = 0;
|
||||
if(among(it, itOrbFrog, itOrbPhasing, itOrbDash)) ac = 5;
|
||||
if(among(it, itOrbSummon)) ac = 20;
|
||||
if(among(it, itOrbPsi)) ac = 30;
|
||||
if(among(it, itOrbStunning)) ac = 10;
|
||||
if(among(it, itOrbMorph)) ac = 3;
|
||||
if(among(it, itOrbIllusion)) ac = 5;
|
||||
if(among(it, itOrbDragon)) ac = 5;
|
||||
if(among(it, itOrbAir)) ac = 1;
|
||||
|
||||
if(ac) {
|
||||
if(items[itOrbEnergy])
|
||||
help += XLAT("\n\nActivation cost: %1 charges (reduced to %2 by %the3)\n", its(ac), its((1+ac)/2), itOrbEnergy);
|
||||
else
|
||||
help += XLAT("\n\nActivation cost: %1 charges\n", its(ac));
|
||||
}
|
||||
|
||||
if(it == itOrb37 && (S7 != 7 || !BITRUNCATED))
|
||||
help += "\n\n" + other_geometry() + forbidden_unmarked();
|
||||
|
||||
|
@ -553,6 +580,20 @@ EX string generateHelpForItem(eItem it) {
|
|||
return help;
|
||||
}
|
||||
|
||||
void mine_dialog() {
|
||||
cmode = sm::SIDE;
|
||||
gamescreen();
|
||||
dialog::init("Minefield graphics");
|
||||
add_edit(numerical_minefield);
|
||||
add_edit(mine_zero_display);
|
||||
add_edit(mine_opacity);
|
||||
add_edit(mine_hollow);
|
||||
add_edit(mine_markers);
|
||||
dialog::addItem(XLAT("minefield colors"), 'c');
|
||||
dialog::add_action_push([] { edit_color_table(minecolors); });
|
||||
dialog::display();
|
||||
}
|
||||
|
||||
void addMinefieldExplanation(string& s) {
|
||||
|
||||
s += XLAT(
|
||||
|
@ -568,7 +609,7 @@ void addMinefieldExplanation(string& s) {
|
|||
s += XLAT("Known mines may be marked by touching while in drag mode. Your allies won't step on marked mines.");
|
||||
#endif
|
||||
|
||||
help_extensions.push_back(help_extension{'n', XLAT("toggle numerical display"), [] () { numerical_minefield = !numerical_minefield; }});
|
||||
help_extensions.push_back(help_extension{'c', XLAT("configure"), [] () { pushScreen(mine_dialog); } });
|
||||
}
|
||||
|
||||
EX string generateHelpForWall(eWall w) {
|
||||
|
@ -700,6 +741,7 @@ void add_reqs(eLand l, string& s) {
|
|||
#define COND(x,y) s += (y);
|
||||
#define ITEMS_TOTAL(list, z) \
|
||||
{ int now = 0; string t = "("; for(eItem i: list) { if(t!="(") t += " | "; t += XLATN(iinf[i].name); now += items[i]; } t += ")"; s += XLAT("Treasure required: %1 x %2.\n", its(z), t); buteol(s, now, z); }
|
||||
#define INMODE(x) ;
|
||||
#define ACCONLY(z) s += XLAT("Accessible only from %the1.\n", z);
|
||||
#define ACCONLY2(z,x) s += XLAT("Accessible only from %the1 or %the2.\n", z, x);
|
||||
#define ACCONLY3(z,y,x) s += XLAT("Accessible only from %the1, %2, or %3.\n", z, y, x);
|
||||
|
@ -882,7 +924,6 @@ EX void describeMouseover() {
|
|||
if(shmup::on)
|
||||
out += " (" + its(c->landparam)+")";
|
||||
else {
|
||||
calcTidalPhase();
|
||||
bool b = c->landparam >= tide[turncount % tidalsize];
|
||||
int t = 1;
|
||||
for(; t < 1000 && b == (c->landparam >= tide[(turncount+t) % tidalsize]); t++) ;
|
||||
|
|
20
history.cpp
20
history.cpp
|
@ -756,19 +756,19 @@ EX namespace history {
|
|||
history::includeHistory = false;
|
||||
}) + addHook(hooks_configfile, 0, [] {
|
||||
|
||||
addsaver(autobandhistory, "include history"); // check!
|
||||
param_f(lvspeed, "lvspeed", "lineview speed");
|
||||
addsaver(extra_line_steps, "lineview extension");
|
||||
param_b(autobandhistory, "include history"); // check!
|
||||
param_f(lvspeed, parameter_names("lvspeed", "lineview speed"));
|
||||
param_f(extra_line_steps, "lineview extension");
|
||||
|
||||
addsaver(bandhalf, "band width");
|
||||
addsaver(bandsegment, "band segment");
|
||||
addsaver(autoband, "automatic band");
|
||||
addsaver(autobandhistory, "automatic band history");
|
||||
addsaver(dospiral, "do spiral");
|
||||
param_i(bandhalf, "band width");
|
||||
param_i(bandsegment, "band segment");
|
||||
param_b(autoband, "automatic band");
|
||||
param_b(autobandhistory, "automatic band history");
|
||||
param_b(dospiral, "do spiral");
|
||||
|
||||
#if CAP_SHOT && CAP_SDL
|
||||
addsaver(band_format_auto, "band_format_auto");
|
||||
addsaver(band_format_now, "band_format_now");
|
||||
param_str(band_format_auto, "band_format_auto");
|
||||
param_str(band_format_now, "band_format_now");
|
||||
#endif
|
||||
});
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ EX string s0;
|
|||
EX string its(int i) { return hr::format("%d", i); }
|
||||
|
||||
EX string itsh8(int i) { return hr::format("%08X", i); }
|
||||
EX string itsh6(int i) { return hr::format("%06X", i); }
|
||||
|
||||
EX string fts(ld x, int prec IS(6)) {
|
||||
std::stringstream ss;
|
||||
|
@ -566,4 +567,12 @@ EX void debug_view(string context, string s) {
|
|||
if(s != old) { old = s; println(hlog, s); }
|
||||
}
|
||||
|
||||
EX vector<string> split_string(const string& s, char sep) {
|
||||
vector<string> res;
|
||||
string next = "";
|
||||
for(char c: s) if(c == sep) { res.push_back(next); next = ""; } else next += c;
|
||||
res.push_back(next);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
6
hud.cpp
6
hud.cpp
|
@ -705,12 +705,12 @@ EX void drawStats() {
|
|||
if(peace::on) vers += " peace";
|
||||
if(racing::on) vers += " racing";
|
||||
if(daily::on) vers += " strange";
|
||||
if(bow::weapon && bow::style == bow::cbBull) vers += " b/bull";
|
||||
if(bow::weapon && bow::style == bow::cbGeodesic) vers += " b/geo";
|
||||
if(bow::crossbow_mode()) vers += " b/" + bow::bowName[bow::style];
|
||||
if(land_structure != default_land_structure())
|
||||
vers += land_structure_name(true);
|
||||
vers += " " + land_structure_name(true);
|
||||
if(princess::challenge) vers += " Princess";
|
||||
if(randomPatternsMode) vers += " RPM";
|
||||
if(use_custom_land_list) vers += " custom";
|
||||
|
||||
if(geometry != gNormal || !BITRUNCATED)
|
||||
vers = vers + " " + full_geometry_name();
|
||||
|
|
|
@ -132,9 +132,7 @@
|
|||
#include "rogueviz/rogueviz-all.cpp"
|
||||
#endif
|
||||
|
||||
#if CAP_DAILY
|
||||
#include "private/daily.cpp"
|
||||
#else
|
||||
#if !CAP_DAILY
|
||||
namespace hr { namespace daily { bool on; int historical; } }
|
||||
#endif
|
||||
|
||||
|
|
14
hyper.h
14
hyper.h
|
@ -13,8 +13,8 @@
|
|||
#define _HYPER_H_
|
||||
|
||||
// version numbers
|
||||
#define VER "13.0d"
|
||||
#define VERNUM_HEX 0xAA04
|
||||
#define VER "13.0m"
|
||||
#define VERNUM_HEX 0xAA0D
|
||||
|
||||
#include "sysconfig.h"
|
||||
|
||||
|
@ -221,15 +221,6 @@ void addMessage(string s, char spamtype = 0);
|
|||
|
||||
#define NUMWITCH 7
|
||||
|
||||
// achievements
|
||||
|
||||
#define LB_YENDOR_CHALLENGE 40
|
||||
#define LB_PURE_TACTICS 41
|
||||
#define NUMLEADER 90
|
||||
#define LB_PURE_TACTICS_SHMUP 49
|
||||
#define LB_PURE_TACTICS_COOP 50
|
||||
#define LB_RACING 81
|
||||
|
||||
#if ISMOBILE || ISWEB || ISPANDORA || 1
|
||||
typedef double ld;
|
||||
#define LDF "%lf"
|
||||
|
@ -780,6 +771,7 @@ enum orbAction { roMouse, roKeyboard, roCheck, roMouseForce, roMultiCheck, roMul
|
|||
#define pmodel (pconf.model)
|
||||
|
||||
static constexpr int DISTANCE_UNKNOWN = 127;
|
||||
static constexpr int DISTANCE_UNKNOWN_BIG = 99999999;
|
||||
|
||||
template<class T, class U> int addHook(hookset<T>& m, int prio, U&& hook) {
|
||||
return m.add(prio, static_cast<U&&>(hook));
|
||||
|
|
12
hypgraph.cpp
12
hypgraph.cpp
|
@ -559,7 +559,7 @@ ld ellFaux(ld cos_phi, ld sin_phi, ld k) {
|
|||
|
||||
ld sqrt_clamp(ld x) { if(x<0) return 0; return sqrt(x); }
|
||||
|
||||
hyperpoint to_square(hyperpoint H) {
|
||||
EX hyperpoint to_square(hyperpoint H) {
|
||||
|
||||
ld d = hypot_d(2, H);
|
||||
ld x = d / (H[2] + 1);
|
||||
|
@ -1467,7 +1467,10 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
|||
|
||||
case mdSpiral: {
|
||||
cld z;
|
||||
if(hyperbolic || sphere) makeband(H_orig, ret, band_conformal);
|
||||
if(hyperbolic || sphere) {
|
||||
makeband(H_orig, ret, band_conformal);
|
||||
models::scr_to_ori(ret);
|
||||
}
|
||||
else ret = H;
|
||||
z = cld(ret[0], ret[1]) * models::spiral_multiplier;
|
||||
|
||||
|
@ -1492,6 +1495,7 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
|||
if(pconf.skiprope)
|
||||
ret = mobius(ret, pconf.skiprope, 1);
|
||||
}
|
||||
models::ori_to_scr(ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2522,13 +2526,14 @@ void circle_around_center(ld radius, color_t linecol, color_t fillcol, PPR prio)
|
|||
#if CAP_QUEUE
|
||||
ld rad = 10;
|
||||
if(euclid) rad = 1000;
|
||||
for(int i=0; i<=360; i++) curvepoint(xspinpush0(i * degree, rad));
|
||||
for(int i=0; i<=36000; i+=10) curvepoint(xspinpush0(i * degree / 100., rad));
|
||||
auto& c = queuecurve(shiftless(Id), linecol, fillcol, prio);
|
||||
if(pmodel == mdDisk && hyperbolic && pconf.alpha <= -1)
|
||||
c.flags |= POLY_FORCE_INVERTED;
|
||||
if(pmodel == mdJoukowsky)
|
||||
c.flags |= POLY_FORCE_INVERTED;
|
||||
c.flags |= POLY_ALWAYS_IN;
|
||||
c.flags |= POLY_FORCEWIDE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3019,6 +3024,7 @@ EX void draw_boundary(int w) {
|
|||
hyperpoint ret = point2(real(z), imag(z));
|
||||
ret = mobius(ret, pconf.skiprope, 1);
|
||||
ret *= current_display->radius;
|
||||
models::ori_to_scr(ret);
|
||||
curvepoint(ret);
|
||||
}
|
||||
queuecurve(shiftless(Id), ringcolor, 0, p).flags |= POLY_ALWAYS_IN;
|
||||
|
|
|
@ -1181,7 +1181,7 @@ EX void add_options() {
|
|||
}
|
||||
|
||||
auto a = addHook(hooks_configfile, 100, [] {
|
||||
param_b(auto_eyelevel, "auto_eyelevel")
|
||||
param_b(auto_eyelevel, "intra_eyelevel")
|
||||
-> editable("keep eye level when walking enabled", 'L');
|
||||
param_f(eye_level, "walk_eye_level")
|
||||
-> editable(0, 5, .1, "walking eye level",
|
||||
|
|
|
@ -402,10 +402,7 @@ bool step(int delta) {
|
|||
if(notfound) { status[4] = XLAT("cells badly paired: %1", its(notfound)); runlevel = 0; break; }
|
||||
|
||||
int heptas = 0;
|
||||
for(auto p: cells_of_heptagon) {
|
||||
printf("%p: %d\n", hr::voidp(p.first), isize(p.second));
|
||||
heptas++;
|
||||
}
|
||||
for(auto p: cells_of_heptagon) heptas++;
|
||||
|
||||
if(heptas != isize(all)) {
|
||||
status[4] = XLAT("cells not covered: %1", its(isize(all) - heptas));
|
||||
|
@ -807,6 +804,8 @@ bool save_map(const string& fname) {
|
|||
return true;
|
||||
}
|
||||
|
||||
vector<ld> float_order;
|
||||
|
||||
EX void save_map_bin(hstream& f) {
|
||||
if(!base) { f.write<short>(-1); return; }
|
||||
auto& all = base->allcells();
|
||||
|
@ -817,6 +816,19 @@ EX void save_map_bin(hstream& f) {
|
|||
f.write<short> (base_geometry);
|
||||
f.write<short> (isize(all));
|
||||
f.write<short> (origcells);
|
||||
int foi = 0;
|
||||
|
||||
auto check_float_order = [&] (ld x) {
|
||||
if(foi >= isize(float_order)) {
|
||||
float_order.push_back(x);
|
||||
f.write<ld>(x);
|
||||
}
|
||||
else if(abs(float_order[foi] - x) > 1e-6) {
|
||||
println(hlog, float_order[foi], " vs ", x, " : abs difference is ", abs(float_order[foi] - x));
|
||||
float_order[foi] = x;
|
||||
}
|
||||
f.write<ld>(float_order[foi++]);
|
||||
};
|
||||
|
||||
for(auto h: all) {
|
||||
origcells = 0;
|
||||
|
@ -826,9 +838,9 @@ EX void save_map_bin(hstream& f) {
|
|||
f.write<short> (origcells);
|
||||
for(auto i: cells_of_heptagon[h->master]) if(cells[i].generation == 0) {
|
||||
auto &ci = cells[i];
|
||||
f.write<ld>(ci.p[0]);
|
||||
f.write<ld>(ci.p[1]);
|
||||
f.write<ld>(ci.p[LDIM]);
|
||||
check_float_order(ci.p[0]);
|
||||
check_float_order(ci.p[1]);
|
||||
check_float_order(ci.p[LDIM]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -877,6 +889,7 @@ EX void load_map_bin(hstream& f) {
|
|||
density = cellcount * 1. / isize(all);
|
||||
|
||||
cells.clear();
|
||||
float_order.clear();
|
||||
|
||||
for(auto h: all) {
|
||||
int q = f.get<short>();
|
||||
|
@ -889,6 +902,9 @@ EX void load_map_bin(hstream& f) {
|
|||
a = f.get<ld>();
|
||||
b = f.get<ld>();
|
||||
c = f.get<ld>();
|
||||
float_order.push_back(a);
|
||||
float_order.push_back(b);
|
||||
float_order.push_back(c);
|
||||
s.p = hpxyz(a, b, c);
|
||||
s.p = normalize(s.p);
|
||||
for(auto c0: all) s.relmatrices[c0] = calc_relative_matrix(c0, h, s.p);
|
||||
|
|
|
@ -16,8 +16,13 @@ EX array<int, ittypes> items;
|
|||
|
||||
EX map<modecode_t, array<int, ittypes> > hiitems;
|
||||
|
||||
EX bool pickable_from_water(eItem it) {
|
||||
return among(it, itOrbFish, itOrbAether);
|
||||
}
|
||||
|
||||
EX bool cannotPickupItem(cell *c, bool telekinesis) {
|
||||
return itemHidden(c) && !telekinesis && !(isWatery(c) && markOrb(itOrbFish));
|
||||
if(pickable_from_water(c->item) && isWatery(c)) return false;
|
||||
return itemHidden(c) && !telekinesis && !(isWatery(c) && (markOrb(itOrbFish) || markOrb(itOrbAether)));
|
||||
}
|
||||
|
||||
EX bool canPickupItemWithMagnetism(cell *c, cell *from) {
|
||||
|
@ -737,7 +742,7 @@ EX void collectMessage(cell *c2, eItem which) {
|
|||
|
||||
EX bool itemHiddenFromSight(cell *c) {
|
||||
return isWatery(c) && !items[itOrbInvis] && !(items[itOrbFish] && playerInWater())
|
||||
&& !(shmup::on && shmup::boatAt(c));
|
||||
&& !(shmup::on && shmup::boatAt(c)) && !(c->cpdist <= 1 && playerInWater());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
52
landgen.cpp
52
landgen.cpp
|
@ -288,9 +288,20 @@ EX void gen_baby_tortoise(cell *c) {
|
|||
EX int rebalance_treasure(int x, int y, eLand l) {
|
||||
int res = ((tactic::on || quotient == 2 || daily::on) ? (y) : inv::on ? min(2*(y),x) : (x));
|
||||
if(use_custom_land_list) res = (res * custom_land_treasure[l] + 50) / 100;
|
||||
res *= ls::ls_mul();
|
||||
return res;
|
||||
}
|
||||
|
||||
EX eItem random_curse() {
|
||||
return pick(itCurseWeakness, itCurseDraining, itCurseWater, itCurseFatigue, itCurseRepulsion, itCurseGluttony);
|
||||
}
|
||||
|
||||
EX void clear_item(cell *c) {
|
||||
if(c->item == itOrbWater && c->wall == waStrandedBoat)
|
||||
c->wall = waNone;
|
||||
c->item = itNone;
|
||||
}
|
||||
|
||||
EX void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
bool fargen = d == 9;
|
||||
switch(c->land) {
|
||||
|
@ -547,7 +558,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
// no Plates or Trapdoors in the Princess cell
|
||||
if(d < 3 && (c->wall == waClosePlate || c->wall == waOpenPlate || c->wall == waTrapdoor))
|
||||
c->wall = waNone;
|
||||
if(d > 1) c->item = itNone;
|
||||
if(d > 1) clear_item(c);
|
||||
// the Princess herself
|
||||
if(d == 0) {
|
||||
c->monst = moPrincess;
|
||||
|
@ -754,7 +765,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
}
|
||||
}
|
||||
// seal entrances to the Land of Power.
|
||||
if(d == 7 && ctof(c)) {
|
||||
if(d == 7 && ctof(c) && land_structure != lsLandscape) {
|
||||
bool onwall = false;
|
||||
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->land == laBarrier)
|
||||
onwall = true;
|
||||
|
@ -764,13 +775,16 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
cell *c3 = c2->modmove(c->c.spin(i) + 3);
|
||||
if(!c3) continue;
|
||||
if(c3->land != laPower && c3->land != laBarrier)
|
||||
if(c2->wall != waFire && c2->wall != waGlass) {
|
||||
if(c2->wall != waEternalFire && c2->wall != waGlass) {
|
||||
if(isFire(c)) c->monst = moWitchWinter;
|
||||
else if(c->wall == waGlass) c->monst = moWitchGhost;
|
||||
else c->monst = moEvilGolem;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d == 7 && land_structure == lsLandscape) {
|
||||
forCellEx(c2, c) if(c2->land != laPower) c->wall = waEternalFire;
|
||||
}
|
||||
ONEMPTY {
|
||||
if(hrand(5000+50*items[itPower]) < 1200) {
|
||||
eItem powerorbs[6] = {
|
||||
|
@ -936,7 +950,13 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
|
||||
case laTrollheim:
|
||||
if(fargen) {
|
||||
if(hrand(50000) < (ls::tame_chaos() ? 1000: ls::any_chaos() ?50:5) && c->wall != waBarrier && celldist(c) >= 7 && !safety && !peace::on) {
|
||||
int freq =
|
||||
land_structure == lsVineWalls ? 10000 :
|
||||
ls::wall_chaos() ? 2500 :
|
||||
ls::tame_chaos() ? 1000 :
|
||||
ls::any_chaos() ? 50 :
|
||||
5;
|
||||
if(hrand(50000) < freq && c->wall != waBarrier && celldist(c) >= 7 && !safety && !peace::on) {
|
||||
bool okay = true;
|
||||
forCellCM(c2, c) forCellCM(c3, c2) forCellCM(c4, c3) forCellCM(c5, c4) {
|
||||
cell *cx = ls::any_chaos() ? c3 : c5;
|
||||
|
@ -1280,7 +1300,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
if(d == 8) {
|
||||
bool ok = c->landparam == 0;
|
||||
forCellEx(c2, c) if(c2->landparam) ok = false;
|
||||
if(ok && hrand(doCross ?450:15000) < 20 + (2 * items[itMutant] + yendor::hardness()) && !safety) {
|
||||
if(ok && hrand(doCross ?450:15000) < (20 + (2 * items[itMutant] + yendor::hardness())) * ls::ls_mul_big() && !safety) {
|
||||
if(!peace::on) c->item = itMutant;
|
||||
c->landparam = items[itMutant] + 5 + hrand(11);
|
||||
c->wall = waNone;
|
||||
|
@ -2065,7 +2085,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
|
||||
case laHunting:
|
||||
if(d == 7 && c->land == laHunting && !racing::on && !safety && !reptilecheat) {
|
||||
if(hrand(1000) < 20) {
|
||||
if(hrand(1000) < 20 * ls::ls_mul_big()) {
|
||||
if(openplains(c)) {
|
||||
if(hrand(2) == 0) {
|
||||
if(!items[itHunting]) {
|
||||
|
@ -2273,11 +2293,11 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
c->monst = moMonkey;
|
||||
else if(hrand_monster(80000) < 5 + items[itRuby] + yendor::hardness())
|
||||
c->monst = moEagle;
|
||||
else if(pseudohept_r(c) && c != currentmap->gamestart() && hrand_monster(4000) < 300 + items[itRuby] && !c->monst) {
|
||||
else if(pseudohept_r(c) && c != currentmap->gamestart() && hrand_monster(4000) < (300 + items[itRuby]) * ls::ls_mul_big() && !c->monst) {
|
||||
int hardchance = items[itRuby] + yendor::hardness();
|
||||
if(hardchance > 25) hardchance = 25;
|
||||
bool hardivy = hrand(100) < hardchance;
|
||||
if((cgflags & qFRACTAL) ? buildIvy(c, 0, 2) : hat::in() ? buildIvy(c, 0, 4) : (hardivy ? buildIvy(c, 1, 9) : buildIvy(c, 0, c->type)) && !peace::on)
|
||||
if(land_structure == lsVineWalls ? buildIvy(c, 0, 2) : (cgflags & qFRACTAL) ? buildIvy(c, 0, 2) : hat::in() ? buildIvy(c, 0, 4) : (hardivy ? buildIvy(c, 1, 9) : buildIvy(c, 0, c->type)) && !peace::on)
|
||||
c->item = itRuby;
|
||||
}
|
||||
}
|
||||
|
@ -2396,7 +2416,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
if(hrand(1500) < PT(30 + kills[moHexDemon] + kills[moAltDemon] + kills[moMonk] + kills[moPair] + kills[moCrusher], 100) && notDippingFor(itRuins)) {
|
||||
c->item = itRuins;
|
||||
forCellEx(c2, c) if(c2->monst == moMonk)
|
||||
c->item = itNone;
|
||||
clear_item(c);
|
||||
}
|
||||
if(hrand_monster(7000) < kf && !c->monst) {
|
||||
c->monst = genRuinMonster(c);
|
||||
|
@ -2534,7 +2554,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
if(d == 7) {
|
||||
c->wall = waNone;
|
||||
|
||||
c->item = itNone; c->monst = moNone;
|
||||
clear_item(c); c->monst = moNone;
|
||||
|
||||
if(hrand(100) < 25)
|
||||
c->wall = hrand(2) ? waBigTree : waSmallTree;
|
||||
|
@ -2575,7 +2595,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
treasure_rate += variant::features[i].rate_change;
|
||||
variant::features[i].build(c);
|
||||
}
|
||||
if(hrand(2000 - PT(kills[moVariantWarrior] * 5, 250)) < treasure_rate && !c->wall && !c->monst)
|
||||
if(hrand(max(100, 2000 - PT(kills[moVariantWarrior] * 5, 250))) < treasure_rate && !c->wall && !c->monst)
|
||||
c->item = itVarTreasure;
|
||||
}
|
||||
if(d == 7 && c->wall == waTrapdoor) {
|
||||
|
@ -2646,7 +2666,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
}
|
||||
|
||||
case laCursed: {
|
||||
if(fargen) {
|
||||
if(fargen && c->wall != waRubble) {
|
||||
c->wall = waStone;
|
||||
for(int i=0; i<3; i++) {
|
||||
auto ew = [i] (cell *c1) {
|
||||
|
@ -2682,7 +2702,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||
c->wall = waStone;
|
||||
else {
|
||||
c->monst = moHexer;
|
||||
c->item = pick(itCurseWeakness, itCurseDraining, itCurseWater, itCurseFatigue, itCurseRepulsion, itCurseGluttony);
|
||||
c->item = random_curse();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2910,7 +2930,7 @@ EX void set_land_for_geometry(cell *c) {
|
|||
return;
|
||||
}
|
||||
if(land_structure == lsLandscape) {
|
||||
if(landscape_div < 0) landscape_div = 1;
|
||||
if(landscape_div <= 0) landscape_div = 1;
|
||||
array<int, 3> a;
|
||||
for(int i=0; i<3; i++) a[i] = getCdata(c, i);
|
||||
auto& ld = landscape_div;
|
||||
|
@ -3055,10 +3075,10 @@ EX void setdist(cell *c, int d, cell *from) {
|
|||
}
|
||||
|
||||
if(d == BARLEV && c->land == laCanvas) {
|
||||
color_t col = patterns::generateCanvas(c);
|
||||
color_t col = ccolor::generateCanvas(c);
|
||||
c->landparam = col;
|
||||
c->wall = canvas_default_wall;
|
||||
if((GDIM == 3 || geom3::flipped) && (col & 0x1000000)) c->wall = waWaxWall;
|
||||
if(col & 0x1000000) c->wall = waWaxWall;
|
||||
}
|
||||
|
||||
#if CAP_FIELD
|
||||
|
|
77
landlock.cpp
77
landlock.cpp
|
@ -81,7 +81,7 @@ EX eLand firstland = laIce;
|
|||
EX eLand specialland = laIce;
|
||||
|
||||
#if HDR
|
||||
enum eLandStructure { lsNiceWalls, lsChaos, lsPatchedChaos, lsTotalChaos, lsChaosRW, lsWallChaos, lsSingle, lsNoWalls, lsHorodisks, lsVoronoi, lsLandscape, lsGUARD };
|
||||
enum eLandStructure { lsNiceWalls, lsChaos, lsPatchedChaos, lsTotalChaos, lsChaosRW, lsWallChaos, lsSingle, lsNoWalls, lsHorodisks, lsVoronoi, lsLandscape, lsCrossWalls, lsVineWalls, lsCursedWalls, lsGUARD };
|
||||
#endif
|
||||
|
||||
EX eLandStructure land_structure;
|
||||
|
@ -90,9 +90,9 @@ EX namespace ls {
|
|||
|
||||
EX bool single() { return land_structure == lsSingle; }
|
||||
|
||||
EX bool any_chaos() { return among(land_structure, lsChaos, lsPatchedChaos, lsWallChaos, lsTotalChaos, lsChaosRW, lsLandscape); }
|
||||
EX bool any_chaos() { return among(land_structure, lsChaos, lsPatchedChaos, lsWallChaos, lsTotalChaos, lsChaosRW, lsCrossWalls, lsVineWalls, lsCursedWalls, lsLandscape); }
|
||||
EX bool std_chaos() { return land_structure == lsChaos; }
|
||||
EX bool wall_chaos() { return land_structure == lsWallChaos; }
|
||||
EX bool wall_chaos() { return among(land_structure, lsWallChaos, lsCrossWalls, lsVineWalls, lsCursedWalls); }
|
||||
EX bool patched_chaos() { return land_structure == lsPatchedChaos; }
|
||||
|
||||
EX bool any_order() { return among(land_structure, lsNiceWalls, lsNoWalls, lsHorodisks, lsVoronoi); }
|
||||
|
@ -112,11 +112,31 @@ EX int chaoticity() {
|
|||
if(land_structure == lsChaos) return 40;
|
||||
if(land_structure == lsLandscape) return 35;
|
||||
if(land_structure == lsWallChaos) return 30;
|
||||
if(land_structure == lsCrossWalls) return 32;
|
||||
if(land_structure == lsCursedWalls) return 34;
|
||||
if(land_structure == lsVoronoi) return 20;
|
||||
if(land_structure == lsSingle) return 0;
|
||||
return 10;
|
||||
}
|
||||
|
||||
/** a multiplier to make stuff more frequent in Wall Chaos and Cross Wall Chaos: treasure */
|
||||
EX int ls_mul() {
|
||||
if(land_structure == lsWallChaos) return 2;
|
||||
if(land_structure == lsCrossWalls) return 3;
|
||||
if(land_structure == lsVineWalls) return 3;
|
||||
if(land_structure == lsCursedWalls) return 3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** a multiplier to make stuff more frequent in Wall Chaos and Cross Wall Chaos: even bigger */
|
||||
EX int ls_mul_big() {
|
||||
if(land_structure == lsWallChaos) return 5;
|
||||
if(land_structure == lsCrossWalls) return 10;
|
||||
if(land_structure == lsVineWalls) return 10;
|
||||
if(land_structure == lsCursedWalls) return 10;
|
||||
return 1;
|
||||
}
|
||||
|
||||
EX bool tame_chaos() { return any_chaos() && chaoticity() < 35; }
|
||||
EX }
|
||||
|
||||
|
@ -144,6 +164,12 @@ EX string land_structure_name(bool which) {
|
|||
return XLAT("landscape");
|
||||
case lsNoWalls:
|
||||
return XLAT("wall-less");
|
||||
case lsCrossWalls:
|
||||
return XLAT("excessive crossing walls");
|
||||
case lsVineWalls:
|
||||
return XLAT("regular walls");
|
||||
case lsCursedWalls:
|
||||
return XLAT("cursed walls");
|
||||
default:
|
||||
return "error structure";
|
||||
}
|
||||
|
@ -164,6 +190,12 @@ EX void fix_land_structure_choice() {
|
|||
land_structure = lsNoWalls;
|
||||
if(!nice_walls_available() && land_structure == lsWallChaos)
|
||||
land_structure = lsChaos;
|
||||
if(!nice_walls_available() && land_structure == lsCrossWalls)
|
||||
land_structure = lsChaos;
|
||||
if(land_structure == lsVineWalls && (geometry != gNormal || !BITRUNCATED))
|
||||
land_structure = lsNiceWalls;
|
||||
if(land_structure == lsCursedWalls && (geometry != gNormal || !BITRUNCATED))
|
||||
land_structure = lsNiceWalls;
|
||||
if(ls::hv_structure() && (!hyperbolic || bt::in() || quotient))
|
||||
land_structure = lsSingle;
|
||||
if(walls_not_implemented() && among(land_structure, lsChaos, lsNoWalls))
|
||||
|
@ -230,6 +262,7 @@ EX bool landUnlocked(eLand l) {
|
|||
#define ACCONLY3(x,y,z)
|
||||
#define ACCONLYF(x)
|
||||
#define IFINGAME(land, ok, fallback) if(isLandIngame(land)) { ok } else { fallback }
|
||||
#define INMODE(x) if(x) return true;
|
||||
#include "content.cpp"
|
||||
|
||||
case landtypes: return false;
|
||||
|
@ -251,7 +284,10 @@ EX void countHyperstoneQuest(int& i1, int& i2) {
|
|||
i1 = 0; i2 = 0;
|
||||
generateLandList(isLandIngame);
|
||||
for(eLand l: landlist) {
|
||||
// no treasure
|
||||
if(l == laCA) continue;
|
||||
// same treasure, so count only once
|
||||
if(l == laMirrorOld && isLandIngame(laMirror)) continue;
|
||||
eItem ttype = treasureType(l);
|
||||
if(!required_for_hyperstones(ttype)) continue;
|
||||
i2++; if(items[ttype] >= R10) i1++;
|
||||
|
@ -383,7 +419,7 @@ EX eLand pickluck(eLand l1, eLand l2) {
|
|||
} */
|
||||
|
||||
EX eLand getNewSealand(eLand old) {
|
||||
while(true) {
|
||||
for(int it=0; it<100; it++) {
|
||||
eLand p = pick(laOcean, pick(laCaribbean, laLivefjord, laWarpSea, laKraken, laDocks));
|
||||
if(p == laKraken && !landUnlocked(p)) continue;
|
||||
if(p == laKraken && peace::on) continue;
|
||||
|
@ -392,6 +428,7 @@ EX eLand getNewSealand(eLand old) {
|
|||
if(!isLandIngame(p)) continue;
|
||||
return p;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
EX bool createOnSea(eLand old) {
|
||||
|
@ -638,14 +675,23 @@ EX eLand getNewLand(eLand old) {
|
|||
|
||||
if(ls::horodisk_structure() && tortoise::seek()) LIKELY tab[cnt++] = laTortoise;
|
||||
|
||||
int attempts = 0;
|
||||
eLand n = old;
|
||||
while(incompatible(n, old) || !isLandIngame(n)) {
|
||||
n = tab[hrand(cnt)];
|
||||
int idx = 0;
|
||||
while (idx < cnt) {
|
||||
eLand n = tab[idx];
|
||||
if (incompatible(n, old) || !isLandIngame(n))
|
||||
tab[idx] = tab[--cnt];
|
||||
else
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (!cnt) {
|
||||
addMessage("No eligible land candidates!");
|
||||
return old;
|
||||
}
|
||||
|
||||
eLand n = tab[hrand(cnt)];
|
||||
if (weirdhyperbolic && specialland == laCrossroads4 && isCrossroads(n))
|
||||
n = laCrossroads4;
|
||||
attempts++; if(attempts == 2000) break;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -741,6 +787,11 @@ EX bool isLandIngame(eLand l) {
|
|||
return land_validity(l).flags & lv::appears_in_full;
|
||||
}
|
||||
|
||||
EX bool landUnlockedIngame(eLand l) {
|
||||
if(!peace::on && !landUnlocked(l)) return false;
|
||||
return isLandIngame(l);
|
||||
}
|
||||
|
||||
namespace lv {
|
||||
|
||||
flagtype q0 = lv::display_error_message | lv::display_in_help | lv::appears_in_geom_exp;
|
||||
|
@ -766,6 +817,7 @@ namespace lv {
|
|||
land_validity_t out_of_theme = { 3, qm2 &~ lv::appears_in_full, "Out of theme for the full game."};
|
||||
land_validity_t no_game = { 2, q2 &~ lv::appears_in_full, "No game here."};
|
||||
land_validity_t not_in_chaos = { 0, q0, "Does not work in chaos mode."};
|
||||
land_validity_t not_in_landscape = { 0, q0, "Does not work in landscape mode."};
|
||||
land_validity_t not_in_full_game = {2, qm2 &~ lv::appears_in_full, "Not in the full game."};
|
||||
land_validity_t not_in_full_game3 = {3, qm2 &~ lv::appears_in_full, "Not in the full game."};
|
||||
land_validity_t special_chaos = { 2, qm2, "Special construction in the Chaos mode." };
|
||||
|
@ -1142,7 +1194,7 @@ EX land_validity_t& land_validity(eLand l) {
|
|||
if(l == laWhirlwind && hyperbolic_not37)
|
||||
return pattern_incompatibility;
|
||||
|
||||
bool better_mirror = !geometry && STDVAR && !ls::hv_structure() && !among(land_structure, lsTotalChaos, lsPatchedChaos, lsLandscape);
|
||||
bool better_mirror = !geometry && STDVAR && !ls::hv_structure() && !among(land_structure, lsTotalChaos, lsPatchedChaos, lsLandscape, lsVineWalls);
|
||||
|
||||
// available only in non-standard geometries
|
||||
if(l == laMirrorOld && better_mirror)
|
||||
|
@ -1163,6 +1215,9 @@ EX land_validity_t& land_validity(eLand l) {
|
|||
if(l == laHaunted && ls::std_chaos())
|
||||
return not_in_chaos;
|
||||
|
||||
if(among(l, laHaunted, laElementalWall) && land_structure == lsLandscape)
|
||||
return not_in_landscape;
|
||||
|
||||
// standard, non-PTM specific
|
||||
if(l == laCrossroads5 && old_daily_id < 999 && tactic::on)
|
||||
return not_in_ptm;
|
||||
|
|
|
@ -9037,19 +9037,20 @@ S("display only chessboard white", "zobrazit pouze bílá políčka šachovnice"
|
|||
S("display only chessboard black", "zobrazit pouze černá políčka šachovnice")
|
||||
|
||||
S(
|
||||
"This lets you specify the color pattern as a function of the cell. "
|
||||
"This lets you specify the color pattern as a function of the cell.\n",
|
||||
|
||||
"Zde můžeš specifikovat barevný vzor jako funkci políčka.\n")
|
||||
|
||||
S(
|
||||
"Available parameters:\n\n"
|
||||
"x, y, z (hyperboloid/sphere/plane coordinates in non-crystal geometries)\n"
|
||||
"ex, ey, ez (in Euclidean geometries)\n"
|
||||
"x0, x1, x2... (crystal geometry only)\n"
|
||||
"0 is black, 1 is white, rgb(1,0,0) is red, ifp(p-2,1,0) is blue (p=1 for red, 2 for green, 3 for blue).",
|
||||
"x0, x1, x2... (crystal geometry only)\n",
|
||||
|
||||
"Zde můžeš specifikovat barevný vzor jako funkci políčka. "
|
||||
"Dostupné parametry:\n\n"
|
||||
"x, y, z (souřadnice hyperboloidu/koule/roviny v nekrystalových geometriích)\n"
|
||||
"ex, ey, ez (v eukleidovských geometriích)\n"
|
||||
"x0, x1, x2... (pouze v krystalové geometrii)\n"
|
||||
"0 je černá, 1 bílá, rbg(1,0,0) červená, ifp(p-2,1,0) modrá (p=1 pro červenou, 2 pro zelenou, 3 pro modrou)."
|
||||
)
|
||||
|
||||
S(
|
||||
|
|
|
@ -8652,19 +8652,20 @@ S("display only chessboard white", "afficher seulement le plateau d'échec blanc
|
|||
S("display only chessboard black", "afficher seulement le plateau d'échec noir")
|
||||
|
||||
S(
|
||||
"This lets you specify the color pattern as a function of the cell. "
|
||||
"This lets you specify the color pattern as a function of the cell.\n",
|
||||
|
||||
"Vous laisse choisir le motif de couleur comme fonction de la case.\n")
|
||||
|
||||
S(
|
||||
"Available parameters:\n\n"
|
||||
"x, y, z (hyperboloid/sphere/plane coordinates in non-crystal geometries)\n"
|
||||
"ex, ey, ez (in Euclidean geometries)\n"
|
||||
"x0, x1, x2... (crystal geometry only)\n"
|
||||
"0 is black, 1 is white, rgb(1,0,0) is red, ifp(p-2,1,0) is blue (p=1 for red, 2 for green, 3 for blue).",
|
||||
"x0, x1, x2... (crystal geometry only)\n",
|
||||
|
||||
"Vous laisse choisir le motif de couleur comme fonction de la case. "
|
||||
"Paramètres disponibles : \n\n"
|
||||
"x, y, z (coordonnées hyperboloïde/sphère/plan dans des géométries non-cristallines)\n"
|
||||
"ex, ey, ez (dans une géométrie euclidienne)\n"
|
||||
"x0, x1, x2... (dans les géométries cristallines seulement)\n"
|
||||
"0 est noir, 1 est blanc, rgb(1,0,0) est rouge, ifp(p-2,1,0) est bleu (p=1 pour rouge, 2 pour vert, 3 pour bleu)."
|
||||
)
|
||||
|
||||
S(
|
||||
|
|
|
@ -8756,18 +8756,19 @@ S("display only chessboard white", "tylko białe pola szachownicy")
|
|||
S("display only chessboard black", "tylko czarne pola szachownicy")
|
||||
|
||||
S(
|
||||
"This lets you specify the color pattern as a function of the cell. "
|
||||
"This lets you specify the color pattern as a function of the cell.\n",
|
||||
"Tu możesz określić wzór jako funkcję komórki.\n")
|
||||
|
||||
S(
|
||||
"Available parameters:\n\n"
|
||||
"x, y, z (hyperboloid/sphere/plane coordinates in non-crystal geometries)\n"
|
||||
"ex, ey, ez (in Euclidean geometries)\n"
|
||||
"x0, x1, x2... (crystal geometry only)\n"
|
||||
"0 is black, 1 is white, rgb(1,0,0) is red, ifp(p-2,1,0) is blue (p=1 for red, 2 for green, 3 for blue).",
|
||||
"x0, x1, x2... (crystal geometry only)\n",
|
||||
|
||||
"Tu możesz określić wzór jako funkcję komórki. Dostępne parametry:\n\n"
|
||||
"Dostępne parametry:\n\n"
|
||||
"x, y, z (współrzędne hiperboloidy/sfery/powierczni, poza kryształami)\n"
|
||||
"ex, ey, ez (w geometriach euklidesowych)\n"
|
||||
"x0, x1, x2... (w kryształach)\n"
|
||||
"0 to czarny, 1 to biały, rgb(1,0,0) to czerwony, ifp(p-2,1,0) to niebieski (p=1 to czerwony, 2 to zielony, 3 to niebieski)."
|
||||
)
|
||||
|
||||
S(
|
||||
|
|
|
@ -427,6 +427,14 @@ int read_legacy_args_anim() {
|
|||
shift_arg_formula(normal_angle);
|
||||
}
|
||||
}
|
||||
else if(argis("-innerwall")) {
|
||||
PHASEFROM(2);
|
||||
patterns::innerwalls = true;
|
||||
}
|
||||
else if(argis("-noinnerwall")) {
|
||||
PHASEFROM(2);
|
||||
patterns::innerwalls = false;
|
||||
}
|
||||
else if(argis("-animrotd")) {
|
||||
start_game();
|
||||
ma = maRotation;
|
||||
|
|
|
@ -213,7 +213,7 @@ template<class T> struct walker {
|
|||
int spin;
|
||||
/** \brief are we mirrored */
|
||||
bool mirrored;
|
||||
walker<T> (T *at = NULL, int s = 0, bool m = false) : at(at), spin(s), mirrored(m) { if(at) s = at->c.fix(s); }
|
||||
walker(T *at = NULL, int s = 0, bool m = false) : at(at), spin(s), mirrored(m) { if(at) s = at->c.fix(s); }
|
||||
/** \brief spin by i to the left (or right, when mirrored */
|
||||
walker<T>& operator += (int i) {
|
||||
spin = at->c.fix(spin+(mirrored?-i:i));
|
||||
|
|
|
@ -746,14 +746,16 @@ EX namespace mapstream {
|
|||
f.write(gen_wandering);
|
||||
f.write(reptilecheat);
|
||||
f.write(timerghost);
|
||||
f.write(patterns::canvasback);
|
||||
f.write(ccolor::plain.ctab[0]);
|
||||
f.write(patterns::whichShape);
|
||||
f.write(patterns::subpattern_flags);
|
||||
f.write(patterns::whichCanvas);
|
||||
char wc = '*';
|
||||
f.write(wc);
|
||||
f.write(ccolor::which->name);
|
||||
f.write(patterns::displaycodes);
|
||||
f.write(canvas_default_wall);
|
||||
f.write(mapeditor::drawplayer);
|
||||
if(patterns::whichCanvas == 'f') f.write(patterns::color_formula);
|
||||
if(ccolor::which == &ccolor::formula) f.write(ccolor::color_formula);
|
||||
f.write(canvasfloor);
|
||||
f.write(canvasdark);
|
||||
|
||||
|
@ -946,15 +948,21 @@ EX namespace mapstream {
|
|||
f.read(gen_wandering);
|
||||
f.read(reptilecheat);
|
||||
f.read(timerghost);
|
||||
f.read(patterns::canvasback);
|
||||
f.read(ccolor::plain.ctab[0]);
|
||||
f.read(patterns::whichShape);
|
||||
f.read(patterns::subpattern_flags);
|
||||
f.read(patterns::whichCanvas);
|
||||
char wc;
|
||||
f.read(wc);
|
||||
if(wc == '*') {
|
||||
string name;
|
||||
f.read(name);
|
||||
for(auto& p: ccolor::all) if(p->name == name) ccolor::which = p;
|
||||
}
|
||||
f.read(patterns::displaycodes);
|
||||
if(f.vernum >= 0xA816)
|
||||
f.read(canvas_default_wall);
|
||||
f.read(mapeditor::drawplayer);
|
||||
if(patterns::whichCanvas == 'f') f.read(patterns::color_formula);
|
||||
if(wc == 'f') f.read(ccolor::color_formula);
|
||||
if(f.vernum >= 0xA90D) {
|
||||
f.read(canvasfloor);
|
||||
f.read(canvasdark);
|
||||
|
@ -2594,16 +2602,16 @@ EX namespace mapeditor {
|
|||
bool onelayeronly;
|
||||
|
||||
bool loadPicFile(const string& s) {
|
||||
fhstream f(picfile, "rt");
|
||||
fhstream f(s, "rt");
|
||||
if(!f.f) {
|
||||
addMessage(XLAT("Failed to load pictures from %1", picfile));
|
||||
addMessage(XLAT("Failed to load pictures from %1", s));
|
||||
return false;
|
||||
}
|
||||
scanline(f);
|
||||
scan(f, f.vernum);
|
||||
printf("vernum = %x\n", f.vernum);
|
||||
if(f.vernum == 0) {
|
||||
addMessage(XLAT("Failed to load pictures from %1", picfile));
|
||||
addMessage(XLAT("Failed to load pictures from %1", s));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2631,6 +2639,7 @@ EX namespace mapeditor {
|
|||
}
|
||||
|
||||
initShape(i, j);
|
||||
println(hlog, "shape ", tie(i, j), " layer ", l);
|
||||
usershapelayer& ds(usershapes[i][j]->d[l]);
|
||||
if(f.vernum >= 0xA608) scan(f, ds.zlevel);
|
||||
ds.shift = readHyperpoint(f);
|
||||
|
@ -2744,8 +2753,7 @@ EX namespace mapeditor {
|
|||
stop_game();
|
||||
enable_canvas();
|
||||
canvas_default_wall = waInvisibleFloor;
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = 0xFFFFFF;
|
||||
ccolor::set_plain(0xFFFFFF);
|
||||
dtcolor = (forecolor << 8) | 255;
|
||||
drawplayer = false;
|
||||
vid.use_smart_range = 2;
|
||||
|
|
|
@ -575,6 +575,7 @@ EX bool destroyHalfvine(cell *c, eWall newwall IS(waNone), int tval IS(6)) {
|
|||
}
|
||||
|
||||
EX int coastvalEdge(cell *c) { return coastval(c, laIvoryTower); }
|
||||
EX int coastvalWest(cell *c) { return coastval(c, laWestWall); }
|
||||
|
||||
EX int gravityLevel(cell *c) {
|
||||
if(c->land == laIvoryTower && ls::hv_structure())
|
||||
|
@ -601,10 +602,10 @@ EX int gravityLevelDiff(cell *c, cell *d) {
|
|||
if(shmup::on) return 0;
|
||||
|
||||
int nid = neighborId(c, d);
|
||||
int id1 = parent_id(c, 1, coastvalEdge) + 1;
|
||||
int id1 = parent_id(c, 1, coastvalWest) + 1;
|
||||
int di1 = angledist(c->type, id1, nid);
|
||||
|
||||
int id2 = parent_id(c, -1, coastvalEdge) - 1;
|
||||
int id2 = parent_id(c, -1, coastvalWest) - 1;
|
||||
int di2 = angledist(c->type, id2, nid);
|
||||
|
||||
if(di1 < di2) return 1;
|
||||
|
@ -708,8 +709,8 @@ EX void checkTide(cell *c) {
|
|||
if(!c2) continue;
|
||||
if(c2->land == laBarrier || c2->land == laOceanWall) ;
|
||||
else if(c2->land == laOcean)
|
||||
seadist = min(seadist, c2->SEADIST ? c2->SEADIST+1 : 7),
|
||||
landdist = min(landdist, c2->LANDDIST ? c2->LANDDIST+1 : 7);
|
||||
seadist = min(seadist, c2->SEADIST >= 1 ? c2->SEADIST+1 : 7),
|
||||
landdist = min(landdist, c2->LANDDIST >= 1 ? c2->LANDDIST+1 : 7);
|
||||
else if(isSealand(c2->land)) seadist = 1;
|
||||
else landdist = 1;
|
||||
}
|
||||
|
@ -743,20 +744,35 @@ EX void checkTide(cell *c) {
|
|||
else if(c->wall == waMagma) c->wall = waNone;
|
||||
}
|
||||
#endif
|
||||
if(c->land == laCanvas && ccolor::live_canvas) {
|
||||
color_t col = ccolor::generateCanvas(c);
|
||||
c->landparam = col;
|
||||
c->wall = canvas_default_wall;
|
||||
if(col & 0x1000000) c->wall = waWaxWall;
|
||||
}
|
||||
}
|
||||
|
||||
EX bool makeEmpty(cell *c) {
|
||||
|
||||
if(c->monst != moPrincess) {
|
||||
EX bool makeNoMonster(cell *c) {
|
||||
changes.ccell(c);
|
||||
if(isAnyIvy(c->monst)) killMonster(c, moPlayer, 0);
|
||||
else if(c->monst == moPair) {
|
||||
changes.ccell(c->move(c->mondir));
|
||||
if(c->move(c->mondir)->monst == moPair)
|
||||
c->move(c->mondir)->monst = moNone;
|
||||
}
|
||||
else if(isWorm(c->monst)) {
|
||||
if(!items[itOrbDomination]) return false;
|
||||
}
|
||||
else if(isMultitile(c->monst)) {
|
||||
return false;
|
||||
}
|
||||
else c->monst = moNone;
|
||||
return true;
|
||||
}
|
||||
|
||||
EX bool makeEmpty(cell *c) {
|
||||
if(c->monst != moPrincess) {
|
||||
if(!makeNoMonster(c)) return false;
|
||||
}
|
||||
|
||||
if(c->land == laCanvas) ;
|
||||
|
|
17
menus.cpp
17
menus.cpp
|
@ -276,13 +276,17 @@ EX void enable_cheat() {
|
|||
|
||||
// -- game modes --
|
||||
|
||||
EX void switchHardcore() {
|
||||
EX void switchHardcore_quiet() {
|
||||
if(hardcore && !canmove) {
|
||||
restart_game();
|
||||
if(delayed_start) stop_game(); else restart_game();
|
||||
hardcore = false;
|
||||
}
|
||||
else if(hardcore && canmove) { hardcore = false; }
|
||||
else { hardcore = true; canmove = true; hardcoreAt = turncount; }
|
||||
}
|
||||
|
||||
EX void switchHardcore() {
|
||||
switchHardcore_quiet();
|
||||
if(hardcore)
|
||||
addMessage(XLAT("One wrong move and it is game over!"));
|
||||
else
|
||||
|
@ -374,6 +378,9 @@ EX void showCreative() {
|
|||
}
|
||||
#endif
|
||||
|
||||
dialog::addItem(XLAT("line patterns"), 'l');
|
||||
dialog::add_action_push(linepatterns::showMenu);
|
||||
|
||||
// dialog::addBoolItem(XLAT("expansion"), viewdists, 'x');
|
||||
|
||||
dialog::addBreak(50);
|
||||
|
@ -466,6 +473,8 @@ EX void show_chaos() {
|
|||
add_edit(randomwalk_size);
|
||||
else if(land_structure == lsLandscape)
|
||||
add_edit(landscape_div);
|
||||
else if(land_structure == lsCursedWalls)
|
||||
add_edit(curse_percentage);
|
||||
else
|
||||
dialog::addBreak(100);
|
||||
dialog::addBack();
|
||||
|
@ -780,7 +789,7 @@ EX void showChangeMode() {
|
|||
#endif
|
||||
dialog::addBoolItem(XLAT("%1 Challenge", moPrincess), (princess::challenge), 'P');
|
||||
dialog::add_action_confirmed([] {
|
||||
if(!princess::everSaved)
|
||||
if(!princess::everSaved && !autocheat)
|
||||
addMessage(XLAT("Save %the1 first to unlock this challenge!", moPrincess));
|
||||
else restart_game(rg::princess);
|
||||
});
|
||||
|
@ -1007,7 +1016,7 @@ EX void showStartMenu() {
|
|||
stop_game();
|
||||
enable_canvas();
|
||||
cheater = true;
|
||||
patterns::canvasback = 0xFFFFFF;
|
||||
ccolor::set_plain(0xFFFFFF);
|
||||
mapeditor::drawplayer = false;
|
||||
start_game();
|
||||
clearMessages();
|
||||
|
|
63
models.cpp
63
models.cpp
|
@ -919,14 +919,14 @@ EX namespace models {
|
|||
#endif
|
||||
|
||||
void add_model_config() {
|
||||
addsaver(polygonal::SI, "polygon sides");
|
||||
param_f(polygonal::STAR, "star", "polygon star factor");
|
||||
addsaver(polygonal::deg, "polygonal degree");
|
||||
param_i(polygonal::SI, "polygon sides");
|
||||
param_f(polygonal::STAR, parameter_names("star", "polygon star factor"));
|
||||
param_i(polygonal::deg, "polygonal degree");
|
||||
|
||||
addsaver(polygonal::maxcoef, "polynomial degree");
|
||||
param_i(polygonal::maxcoef, "polynomial degree");
|
||||
for(int i=0; i<polygonal::MSI; i++) {
|
||||
addsaver(polygonal::coefr[i], "polynomial "+its(i)+".real");
|
||||
addsaver(polygonal::coefi[i], "polynomial "+its(i)+".imag");
|
||||
param_f(polygonal::coefr[i], "polynomial "+its(i)+".real");
|
||||
param_f(polygonal::coefi[i], "polynomial "+its(i)+".imag");
|
||||
}
|
||||
|
||||
auto setrot = [] {
|
||||
|
@ -941,7 +941,7 @@ EX namespace models {
|
|||
param_matrix(models::rotation.v3, "rotation3", 3)->editable("auto rotation in 3D", "", 'r')->set_extra(setrot);
|
||||
param_i(models::do_rotate, "auto_rotation_mode", 1);
|
||||
|
||||
param_f(pconf.halfplane_scale, "hp", "halfplane scale", 1);
|
||||
param_f(pconf.halfplane_scale, parameter_names("hp", "halfplane scale"), 1);
|
||||
|
||||
auto add_all = [&] (projection_configuration& p, string pp, string sp) {
|
||||
|
||||
|
@ -949,8 +949,11 @@ EX namespace models {
|
|||
dynamicval<function<bool()>> ds(auto_restrict);
|
||||
auto_restrict = [&p] { return &vpconf == &p; };
|
||||
|
||||
addsaverenum(p.model, pp+"used model", mdDisk);
|
||||
if(&p.model == &pmodel) param_custom(pmodel, "projection|Poincare|Klein|half-plane|perspective", menuitem_projection, '1');
|
||||
if(&p.model == &pmodel) {
|
||||
auto par = param_custom_int(pmodel, parameter_names(pp+"used_model", "used model"), menuitem_projection, '1');
|
||||
par->help_text = "projection|Poincare|Klein|half-plane|perspective";
|
||||
}
|
||||
else param_enum(p.model, parameter_names(pp+"used_model", sp+"used model"), mdDisk);
|
||||
|
||||
param_matrix(p.mori().v2, pp+"mori", 2)
|
||||
-> editable("model orientation", "", 'o');
|
||||
|
@ -960,32 +963,32 @@ EX namespace models {
|
|||
param_f(p.top_z, sp+"topz", 5)
|
||||
-> editable(1, 20, .25, "maximum z coordinate to show", "maximum z coordinate to show", 'l');
|
||||
|
||||
param_f(p.model_transition, pp+"mtrans", sp+"model transition", 1)
|
||||
param_f(p.model_transition, parameter_names(pp+"mtrans", sp+"model transition"), 1)
|
||||
-> editable(0, 1, .1, "model transition",
|
||||
"You can change this parameter for a transition from another model to this one.", 't');
|
||||
|
||||
param_f(p.rotational_nil, sp+"rotnil", 1);
|
||||
|
||||
param_f(p.clip_min, pp+"clipmin", sp+"clip-min", rug ? -100 : -1);
|
||||
param_f(p.clip_max, pp+"clipmax", sp+"clip-max", rug ? +10 : +1);
|
||||
param_f(p.clip_min, parameter_names(pp+"clipmin", sp+"clip-min"), rug ? -100 : -1);
|
||||
param_f(p.clip_max, parameter_names(pp+"clipmax", sp+"clip-max"), rug ? +10 : +1);
|
||||
|
||||
param_f(p.euclid_to_sphere, pp+"ets", sp+"euclid to sphere projection", 1.5)
|
||||
param_f(p.euclid_to_sphere, parameter_names(pp+"ets", sp+"euclid to sphere projection"), 1.5)
|
||||
-> editable(1e-1, 10, .1, "ETS parameter", "Stereographic projection to a sphere. Choose the radius of the sphere.", 'l')
|
||||
-> set_sets(dialog::scaleLog);
|
||||
|
||||
param_f(p.twopoint_param, pp+"twopoint", sp+"twopoint parameter", 1)
|
||||
param_f(p.twopoint_param, parameter_names(pp+"twopoint", sp+"twopoint parameter"), 1)
|
||||
-> editable(1e-3, 10, .1, "two-point parameter", "In two-point-based models, this parameter gives the distance from each of the two points to the center.", 'b')
|
||||
-> set_sets(dialog::scaleLog);
|
||||
|
||||
param_f(p.axial_angle, pp+"axial", sp+"axial angle", 90)
|
||||
param_f(p.axial_angle, parameter_names(pp+"axial", sp+"axial angle"), 90)
|
||||
-> editable(1e-3, 10, .1, "angle between the axes", "In two-axe-based models, this parameter gives the angle between the two axes.", 'x')
|
||||
-> set_sets(dialog::scaleLog);
|
||||
|
||||
param_f(p.fisheye_param, pp+"fisheye", sp+"fisheye parameter", 1)
|
||||
param_f(p.fisheye_param, parameter_names(pp+"fisheye", sp+"fisheye parameter"), 1)
|
||||
-> editable(1e-3, 10, .1, "fisheye parameter", "Size of the fish eye.", 'b')
|
||||
-> set_sets(dialog::scaleLog);
|
||||
|
||||
param_f(p.fisheye_alpha, pp+"fishalpha", sp+"off-center parameter", 0)
|
||||
param_f(p.fisheye_alpha, parameter_names(pp+"fishalpha", sp+"off-center parameter"), 0)
|
||||
-> editable(1e-1, 10, .1, "off-center parameter",
|
||||
"This projection is obtained by composing gnomonic projection and inverse stereographic projection. "
|
||||
"This parameter changes the center of the first projection (0 = gnomonic, 1 = stereographic). Use a value closer to 1 "
|
||||
|
@ -999,9 +1002,9 @@ EX namespace models {
|
|||
param_f(p.product_z_scale, pp+"zstretch")
|
||||
-> editable(0.1, 10, 0.1, "product Z stretch", "", 'Z');
|
||||
|
||||
param_f(p.collignon_parameter, pp+"collignon", sp+"collignon-parameter", 1)
|
||||
param_f(p.collignon_parameter, parameter_names(pp+"collignon", sp+"collignon-parameter"), 1)
|
||||
-> editable(-1, 1, .1, "Collignon parameter", "", 'b')
|
||||
-> modif([] (float_setting* f) {
|
||||
-> modif([] (float_parameter* f) {
|
||||
f->unit = vpconf.collignon_reflected ? " (r)" : "";
|
||||
})
|
||||
-> set_extra([&p] {
|
||||
|
@ -1044,9 +1047,9 @@ EX namespace models {
|
|||
param_b(p.dualfocus_autoscale, sp+"dualfocus_autoscale", 0)
|
||||
-> editable("autoscale dual focus", 'A');
|
||||
|
||||
addsaver(p.formula, sp+"formula");
|
||||
addsaverenum(p.basic_model, sp+"basic model");
|
||||
addsaver(p.use_atan, sp+"use_atan");
|
||||
param_str(p.formula, sp+"formula");
|
||||
param_enum(p.basic_model, sp+"basic model");
|
||||
param_b(p.use_atan, sp+"use_atan");
|
||||
|
||||
param_f(p.spiral_angle, sp+"sang")
|
||||
-> editable(0, 360, 15, "spiral angle", "set to 90° for the ring projection", 'x')
|
||||
|
@ -1062,11 +1065,13 @@ EX namespace models {
|
|||
|
||||
param_i(p.back_and_front, sp+"backandfront", 0);
|
||||
|
||||
auto projsaver = addsaver(p.alpha, sp+"projection", 1);
|
||||
if(&p.model == &pmodel) {
|
||||
auto proj = param_custom(p.alpha, sp+"projection", menuitem_projection_distance, 'p');
|
||||
p.alpha = 1;
|
||||
auto proj = param_custom_ld(p.alpha, sp+"projection", menuitem_projection_distance, 'p');
|
||||
proj->help_text = "projection distance|Gans Klein Poincare orthographic stereographic";
|
||||
proj->saver = projsaver;
|
||||
}
|
||||
else {
|
||||
param_f(p.alpha, sp+"projection", 1);
|
||||
}
|
||||
|
||||
param_matrix(p.cam(), pp+"cameraangle", 3)
|
||||
|
@ -1093,16 +1098,16 @@ EX namespace models {
|
|||
"(2) in hyperbolic geometry, with spiral angle being +90° or -90°\n"
|
||||
"(3) in hyperbolic geometry, with other spiral angles (1 makes the bands fit exactly)";
|
||||
|
||||
param_f(p.sphere_spiral_multiplier, "sphere_spiral_multiplier")
|
||||
param_f(p.sphere_spiral_multiplier, pp+"sphere_spiral_multiplier")
|
||||
-> editable(0, 10, .1, "sphere spiral multiplier", help, 'M')->unit = "°";
|
||||
|
||||
param_f(p.right_spiral_multiplier, "right_spiral_multiplier")
|
||||
param_f(p.right_spiral_multiplier, pp+"right_spiral_multiplier")
|
||||
-> editable(0, 10, .1, "right spiral multiplier", help, 'M')->unit = "°";
|
||||
|
||||
param_f(p.any_spiral_multiplier, "any_spiral_multiplier")
|
||||
param_f(p.any_spiral_multiplier, pp+"any_spiral_multiplier")
|
||||
-> editable(0, 10, .1, "any spiral multiplier", help, 'M')->unit = "°";
|
||||
|
||||
param_f(p.spiral_cone, "spiral_cone")
|
||||
param_f(p.spiral_cone, pp+"spiral_cone")
|
||||
-> editable(0, 360, -45, "spiral cone", "", 'C')->unit = "°";
|
||||
};
|
||||
|
||||
|
|
53
multi.cpp
53
multi.cpp
|
@ -11,16 +11,17 @@ namespace hr {
|
|||
EX namespace multi {
|
||||
|
||||
#if HDR
|
||||
static constexpr int SCANCODES = 512;
|
||||
static constexpr int MAXJOY = 8;
|
||||
static constexpr int MAXBUTTON = 64;
|
||||
static constexpr int MAXAXE = 16;
|
||||
static constexpr int MAXHAT = 4;
|
||||
|
||||
struct config {
|
||||
char keyaction[512];
|
||||
char joyaction[MAXJOY][MAXBUTTON];
|
||||
char axeaction[MAXJOY][MAXAXE];
|
||||
char hataction[MAXJOY][MAXHAT][4];
|
||||
int keyaction[SCANCODES];
|
||||
int joyaction[MAXJOY][MAXBUTTON];
|
||||
int axeaction[MAXJOY][MAXAXE];
|
||||
int hataction[MAXJOY][MAXHAT][4];
|
||||
int deadzoneval[MAXJOY][MAXAXE];
|
||||
};
|
||||
#endif
|
||||
|
@ -165,13 +166,13 @@ EX const char* axemodes3[4] = {
|
|||
|
||||
EX int centerplayer = -1;
|
||||
|
||||
char* axeconfigs[24]; int numaxeconfigs;
|
||||
int* axeconfigs[24]; int numaxeconfigs;
|
||||
int* dzconfigs[24];
|
||||
|
||||
string listkeys(config& scfg, int id) {
|
||||
#if CAP_SDL
|
||||
string lk = "";
|
||||
for(int i=0; i<512; i++)
|
||||
for(int i=0; i<SCANCODES; i++)
|
||||
if(scfg.keyaction[i] == id)
|
||||
#if CAP_SDL2
|
||||
lk = lk + " " + SDL_GetScancodeName(SDL_Scancode(i));
|
||||
|
@ -265,7 +266,8 @@ struct key_configurer {
|
|||
if(!setwhat) dialog::handleNavigation(sym, uni);
|
||||
if(sym) {
|
||||
if(setwhat) {
|
||||
which_config->keyaction[sym] = setwhat;
|
||||
int scan = key_to_scan(sym);
|
||||
if(scan >= 0 && scan < SCANCODES) which_config->keyaction[scan] = setwhat;
|
||||
setwhat = 0;
|
||||
}
|
||||
else if(uni >= 'a' && uni < 'a' + isize(shmupcmdtable) && shmupcmdtable[uni-'a'][0])
|
||||
|
@ -584,9 +586,19 @@ void pressaction(int id) {
|
|||
actionspressed[id]++;
|
||||
}
|
||||
|
||||
EX int key_to_scan(int sym) {
|
||||
#if CAP_SDL2
|
||||
return SDL_GetScancodeFromKey(sym);
|
||||
#else
|
||||
return sym;
|
||||
#endif
|
||||
}
|
||||
|
||||
EX bool notremapped(int sym) {
|
||||
auto& scfg = scfg_default;
|
||||
int k = scfg.keyaction[sym];
|
||||
int sc = key_to_scan(sym);
|
||||
if(sc < 0 || sc >= SCANCODES) return true;
|
||||
int k = scfg.keyaction[sc];
|
||||
if(k == 0) return true;
|
||||
k /= 16;
|
||||
if(k > 3) k--; else if(k==3) k = 0;
|
||||
|
@ -595,31 +607,31 @@ EX bool notremapped(int sym) {
|
|||
|
||||
EX void sconfig_savers(config& scfg, string prefix) {
|
||||
// unfortunately we cannot use key names here because SDL is not yet initialized
|
||||
for(int i=0; i<512; i++)
|
||||
addsaver(scfg.keyaction[i], prefix + string("key:")+its(i));
|
||||
for(int i=0; i<SCANCODES; i++)
|
||||
param_i(scfg.keyaction[i], prefix + string("key:")+its(i));
|
||||
|
||||
for(int i=0; i<MAXJOY; i++) {
|
||||
string pre = prefix + "joystick "+cts('A'+i);
|
||||
for(int j=0; j<MAXBUTTON; j++)
|
||||
addsaver(scfg.joyaction[i][j], pre+"-B"+its(j));
|
||||
param_i(scfg.joyaction[i][j], pre+"-B"+its(j));
|
||||
for(int j=0; j<MAXAXE; j++) {
|
||||
addsaver(scfg.axeaction[i][j], pre+" axis "+its(j));
|
||||
addsaver(scfg.deadzoneval[i][j], pre+" deadzone "+its(j));
|
||||
param_i(scfg.axeaction[i][j], pre+" axis "+its(j));
|
||||
param_i(scfg.deadzoneval[i][j], pre+" deadzone "+its(j));
|
||||
}
|
||||
for(int j=0; j<MAXHAT; j++) for(int k=0; k<4; k++) {
|
||||
addsaver(scfg.hataction[i][j][k], pre+" hat "+its(j)+" "+"URDL"[k]);
|
||||
param_i(scfg.hataction[i][j][k], pre+" hat "+its(j)+" "+"URDL"[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EX void clear_config(config& scfg) {
|
||||
for(int i=0; i<512; i++) scfg.keyaction[i] = 0;
|
||||
for(int i=0; i<SCANCODES; i++) scfg.keyaction[i] = 0;
|
||||
}
|
||||
|
||||
EX void initConfig() {
|
||||
auto& scfg = scfg_default;
|
||||
|
||||
char* t = scfg.keyaction;
|
||||
int* t = scfg.keyaction;
|
||||
|
||||
#if CAP_SDL2
|
||||
|
||||
|
@ -754,7 +766,7 @@ EX void initConfig() {
|
|||
multi::scs[6].uicolor = 0xC0C0C0FF;
|
||||
|
||||
#if CAP_CONFIG
|
||||
addsaver(multi::players, "mode-number of players");
|
||||
param_i(multi::players, "mode-number of players")->be_non_editable();
|
||||
param_b(multi::split_screen, "splitscreen", false)
|
||||
->editable("split screen mode", 's');
|
||||
param_b(multi::pvp_mode, "pvp_mode", false)
|
||||
|
@ -765,9 +777,9 @@ EX void initConfig() {
|
|||
->editable("self hits", 'h');
|
||||
param_b(multi::two_focus, "two_focus", false)
|
||||
->editable("auto-adjust dual-focus projections", 'f');
|
||||
addsaver(alwaysuse, "use configured keys");
|
||||
param_b(alwaysuse, "use configured keys");
|
||||
|
||||
for(int i=0; i<7; i++) addsaver(multi::scs[i], "player"+its(i));
|
||||
for(int i=0; i<7; i++) paramset(multi::scs[i], "player"+its(i));
|
||||
|
||||
sconfig_savers(scfg, "");
|
||||
#endif
|
||||
|
@ -821,7 +833,8 @@ EX void handleInput(int delta, config &scfg) {
|
|||
get_actions(scfg);
|
||||
|
||||
const Uint8 *keystate = SDL12_GetKeyState(NULL);
|
||||
if(keystate[SDLK_LCTRL] || keystate[SDLK_RCTRL]) d /= 5;
|
||||
|
||||
if(keystate[SDL12(SDLK_LCTRL, SDL_SCANCODE_LCTRL)] || keystate[SDL12(SDLK_RCTRL, SDL_SCANCODE_RCTRL)]) d /= 5;
|
||||
|
||||
double panx =
|
||||
actionspressed[49] - actionspressed[51] + axespressed[2] / 32000.0;
|
||||
|
|
|
@ -29,7 +29,7 @@ struct gamedata {
|
|||
::new (&record[index]) T(std::move(x));
|
||||
}
|
||||
else {
|
||||
T& at = (T&) record[index];
|
||||
T& at = *((T*) (void*) &(record[index]));
|
||||
x = std::move(at);
|
||||
at.~T();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void gamedata_all(gamedata& gd) {
|
|||
gd.store(genrange_bonus);
|
||||
gd.store(gamerange_bonus);
|
||||
gd.store(targets);
|
||||
gd.store(patterns::rwalls);
|
||||
gd.store(ccolor::rwalls);
|
||||
if(GOLDBERG) gd.store(gp::param);
|
||||
callhooks(hooks_gamedata, &gd);
|
||||
}
|
||||
|
|
|
@ -1360,6 +1360,7 @@ EX namespace hybrid {
|
|||
cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); }
|
||||
|
||||
hrmap_hybrid() {
|
||||
underlying_map = nullptr;
|
||||
twisted = false;
|
||||
disc_quotient = 0;
|
||||
in_underlying([this] { initcells(); underlying_map = currentmap; });
|
||||
|
|
16
orbs.cpp
16
orbs.cpp
|
@ -664,7 +664,7 @@ EX void teleportTo(cell *dest) {
|
|||
}
|
||||
|
||||
/* calls changes.rollback or changes.commit */
|
||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone), cell *phasecell IS(nullptr)) {
|
||||
if(byWhat != itStrongWind) playSound(dest, "orb-frog");
|
||||
cell *from = cwt.at;
|
||||
changes.value_keep(cwt);
|
||||
|
@ -683,7 +683,10 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||
|
||||
if(byWhat == itOrbPhasing) {
|
||||
useupOrb(itOrbPhasing, 5);
|
||||
addMessage(XLAT("You jump!"));
|
||||
if(phasecell->monst)
|
||||
addMessage(XLAT("You phase through %the1!", phasecell->monst));
|
||||
else
|
||||
addMessage(XLAT("You phase through %the1!", phasecell->wall));
|
||||
}
|
||||
|
||||
movecost(from, dest, 1);
|
||||
|
@ -823,10 +826,11 @@ void telekinesis(cell *dest) {
|
|||
|
||||
moveItem(dest, cwt.at, true);
|
||||
eItem it = cwt.at->item;
|
||||
bool saf = it == itOrbSafety;
|
||||
collectItem(cwt.at, cwt.at, true);
|
||||
if(cwt.at->item == it)
|
||||
animateMovement(match(dest, cwt.at), LAYER_BOAT);
|
||||
else
|
||||
else if(!saf)
|
||||
animate_item_throw(dest, cwt.at, it);
|
||||
|
||||
useupOrb(itOrbSpace, cost.first);
|
||||
|
@ -880,6 +884,10 @@ EX eMonster summonedAt(cell *dest) {
|
|||
dest->land == laWarpCoast ? moRatling :
|
||||
dest->land == laDocks ? moWaterElemental :
|
||||
moPirate;
|
||||
if(among(dest->wall, waDeepWater, waShallow))
|
||||
return moRusalka;
|
||||
if(dest->wall == waCamelotMoat)
|
||||
return moWaterElemental;
|
||||
if(isReptile(dest->wall))
|
||||
return moReptile;
|
||||
if(dest->wall == waChasm)
|
||||
|
@ -1523,7 +1531,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||
}
|
||||
|
||||
if(phasestate == 3) {
|
||||
if(jumpTo(a, c, itOrbPhasing)) phasestate = 4;
|
||||
if(jumpTo(a, c, itOrbPhasing, 0, moNone, jumpthru)) phasestate = 4;
|
||||
else wouldkill_there = true;
|
||||
}
|
||||
else changes.rollback();
|
||||
|
|
|
@ -169,6 +169,7 @@ EX bool passable(cell *w, cell *from, flagtype flags) {
|
|||
if(airdist(w) < 3) return false;
|
||||
if(againstWind(w,from)) return false;
|
||||
if(isGravityLand(w)) return false;
|
||||
if(w->wall == waChasm && w->land == laDual) return false;
|
||||
}
|
||||
|
||||
if(from && strictlyAgainstGravity(w, from, vrevdir, flags)
|
||||
|
@ -258,7 +259,8 @@ EX bool passable(cell *w, cell *from, flagtype flags) {
|
|||
}
|
||||
|
||||
if(isWatery(w)) {
|
||||
if(in_gravity_zone(w)) ;
|
||||
if((flags & P_ISPLAYER) && from && isWatery(from) && pickable_from_water(w->item)) ;
|
||||
else if(in_gravity_zone(w)) ;
|
||||
else if(from && from->wall == waBoat && F(P_USEBOAT) &&
|
||||
(!againstCurrent(w, from) || F(P_MARKWATER)) && !(from->item == itOrbYendor)) ;
|
||||
else if(from && isWatery(from) && F(P_CHAIN) && F(P_USEBOAT) && !againstCurrent(w, from)) ;
|
||||
|
@ -419,6 +421,8 @@ EX bool canPushStatueOn(cell *c, flagtype flags) {
|
|||
}
|
||||
|
||||
EX void moveBoat(const movei& mi) {
|
||||
changes.ccell(mi.t);
|
||||
changes.ccell(mi.s);
|
||||
eWall x = mi.t->wall; mi.t->wall = mi.s->wall; mi.s->wall = x;
|
||||
mi.t->mondir = mi.rev_dir_or(NODIR);
|
||||
moveItem(mi.s, mi.t, false);
|
||||
|
|
946
pattern2.cpp
946
pattern2.cpp
File diff suppressed because it is too large
Load Diff
39
pcmove.cpp
39
pcmove.cpp
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace hr {
|
||||
|
||||
EX int illegal_moves;
|
||||
|
||||
EX bool keepLightning = false;
|
||||
|
||||
EX bool seenSevenMines = false;
|
||||
|
@ -198,6 +200,7 @@ bool pcmove::checkNeedMove(bool checkonly, bool attacking) {
|
|||
yasc_message = XLAT("did not leave %the1", cwt.at->wall);
|
||||
killHardcorePlayer(multi::cpid, flags);
|
||||
}
|
||||
if(!checkonly) illegal_moves++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -214,6 +217,7 @@ struct pcmove {
|
|||
bool fmsMove, fmsAttack, fmsActivate;
|
||||
int d;
|
||||
int subdir;
|
||||
/** used to tell perform_actual_move() that this is a boat move and thus we should not pick up items */
|
||||
bool boatmove;
|
||||
bool good_tortoise;
|
||||
flagtype attackflags;
|
||||
|
@ -443,6 +447,8 @@ bool pcmove::movepcto() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(checked_move_issue.type == miTHREAT && !checkonly) illegal_moves++;
|
||||
}
|
||||
|
||||
return b;
|
||||
|
@ -802,6 +808,16 @@ bool pcmove::actual_move() {
|
|||
c2->monst = moNone;
|
||||
c2->wall = waRichDie;
|
||||
}
|
||||
else {
|
||||
if(vmsg(miWALL, siWALL, c2, c2->monst))
|
||||
addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(mip.d == NO_SPACE) {
|
||||
if(vmsg(miWALL, siWALL, c2, c2->monst))
|
||||
addMessage(XLAT("No room to push %the1.", c2->monst));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -834,13 +850,10 @@ bool pcmove::actual_move() {
|
|||
return boat_move();
|
||||
|
||||
if(!c2->monst && cwt.at->wall == waBoat && cwt.at->item != itOrbYendor && boatGoesThrough(c2) && markOrb(itOrbWater) && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
|
||||
|
||||
if(c2->item && !cwt.at->item) moveItem(c2, cwt.at, false), boatmove = true;
|
||||
placeWater(c2, cwt.at);
|
||||
moveBoat(mi);
|
||||
if(c2->item && collectItem(c2, cwt.at)) return true;
|
||||
changes.ccell(c2);
|
||||
c2->mondir = revhint(cwt.at, d);
|
||||
if(c2->item) boatmove = !boatmove;
|
||||
placeWater(c2, cwt.at);
|
||||
moveBoat(mi); boatmove = true;
|
||||
return perform_actual_move();
|
||||
}
|
||||
|
||||
|
@ -921,8 +934,6 @@ void pcmove::tell_why_cannot_attack() {
|
|||
addMessage(XLAT("You cannot attack Raiders directly!"));
|
||||
else if(isSwitch(c2->monst))
|
||||
addMessage(XLAT("You cannot attack Jellies in their wall form!"));
|
||||
else if(c2->monst == moAnimatedDie)
|
||||
addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
|
||||
else if(c2->monst == moAngryDie)
|
||||
addMessage(XLAT("This die is really angry at you!"));
|
||||
else if((attackflags & AF_WEAK) && isIvy(c2))
|
||||
|
@ -1285,21 +1296,15 @@ bool pcmove::perform_actual_move() {
|
|||
handle_friendly_ivy();
|
||||
|
||||
if(items[itOrbDigging]) {
|
||||
if(earthMove(mi)) {
|
||||
invismove = false;
|
||||
if(earthMove(mi)) markOrb(itOrbDigging);
|
||||
markOrb(itOrbDigging);
|
||||
}
|
||||
}
|
||||
|
||||
movecost(cwt.at, c2, 1);
|
||||
|
||||
if(!boatmove && collectItem(c2, cwt.at)) return true;
|
||||
if(boatmove && c2->item && cwt.at->item) {
|
||||
eItem it = c2->item;
|
||||
c2->item = cwt.at->item;
|
||||
if(collectItem(c2, cwt.at)) return true;
|
||||
eItem it2 = c2->item;
|
||||
c2->item = it;
|
||||
cwt.at->item = it2;
|
||||
}
|
||||
if(doPickupItemsWithMagnetism(c2)) return true;
|
||||
|
||||
if(isIcyLand(cwt.at) && cwt.at->wall == waNone && markOrb(itOrbWinter)) {
|
||||
|
|
6
quit.cpp
6
quit.cpp
|
@ -26,6 +26,10 @@ EX int getgametime() {
|
|||
return (int) (savetime + (timerstopped ? 0 : (time(NULL) - timerstart)));
|
||||
}
|
||||
|
||||
EX ld getgametime_precise() {
|
||||
return savetime + (timerstopped ? 0 : (ticks - tickstart) / 1000.);
|
||||
}
|
||||
|
||||
EX string getgametime_s(int timespent IS(getgametime())) {
|
||||
return hr::format("%d:%02d", timespent/60, timespent % 60);
|
||||
}
|
||||
|
@ -445,7 +449,7 @@ EX void showGameMenu() {
|
|||
if(cheater && !autocheat) {
|
||||
dialog::addInfo(XLAT("you have cheated %1 times", its(cheater)), 0xFF2020);
|
||||
}
|
||||
else if(!racing::on) {
|
||||
if(!racing::on) {
|
||||
dialog::addInfo(timeline(), dialog::dialogcolor);
|
||||
}
|
||||
|
||||
|
|
11
racing.cpp
11
racing.cpp
|
@ -1039,10 +1039,15 @@ void race_projection() {
|
|||
if(GDIM == 2) {
|
||||
dialog::addMatrixItem(XLAT("race angle"), race_angle.get(), 'a');
|
||||
dialog::add_action([] () {
|
||||
dialog::editMatrix(race_angle.get(), XLAT("model orientation"), "", GDIM);
|
||||
dialog::editMatrix(race_angle.get(), XLAT("race angle"), "", GDIM);
|
||||
auto& d = dialog::get_di();
|
||||
auto q = rot_inverse(race_angle) * pconf.mori();
|
||||
auto last = dialog::get_ne().reaction;
|
||||
dialog::get_ne().reaction = [q, last] () { last(); pconf.mori() = race_angle * q; };
|
||||
auto last = d.reaction;
|
||||
d.reaction = [q, last] () {
|
||||
if(last) last();
|
||||
pconf.mori() = race_angle * q;
|
||||
if(racing::on) set_view();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
15
radar.cpp
15
radar.cpp
|
@ -2,7 +2,7 @@
|
|||
namespace hr {
|
||||
|
||||
#if MAXMDIM >= 4
|
||||
pair<bool, hyperpoint> makeradar(shiftpoint h) {
|
||||
pair<bool, hyperpoint> makeradar(shiftpoint h, bool distant) {
|
||||
|
||||
hyperpoint h1;
|
||||
|
||||
|
@ -23,9 +23,14 @@ pair<bool, hyperpoint> makeradar(shiftpoint h) {
|
|||
|
||||
if(WDIM == 3) {
|
||||
ld d = hdist0(h);
|
||||
if(distant) {
|
||||
h1 = h1 / hypot_d(3, h1);
|
||||
}
|
||||
else {
|
||||
if(d >= vid.radarrange) return {false, h1};
|
||||
if(d) h1 = h1 * (d / vid.radarrange / hypot_d(3, h1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
h1 = cgi.emb->actual_to_base(h1);
|
||||
h1 = current_display->radar_transform_post * h1;
|
||||
|
@ -45,16 +50,16 @@ pair<bool, hyperpoint> makeradar(shiftpoint h) {
|
|||
return {true, h1};
|
||||
}
|
||||
|
||||
EX void addradar(const shiftmatrix& V, char ch, color_t col, color_t outline) {
|
||||
EX void addradar(const shiftmatrix& V, char ch, color_t col, color_t outline, bool distant IS(false)) {
|
||||
shiftpoint h = V * tile_center();
|
||||
auto hp = makeradar(h);
|
||||
auto hp = makeradar(h, distant);
|
||||
if(hp.first)
|
||||
current_display->radarpoints.emplace_back(radarpoint{hp.second, ch, col, outline});
|
||||
}
|
||||
|
||||
EX void addradar(const shiftpoint h1, const shiftpoint h2, color_t col) {
|
||||
auto hp1 = makeradar(h1);
|
||||
auto hp2 = makeradar(h2);
|
||||
auto hp1 = makeradar(h1, false);
|
||||
auto hp2 = makeradar(h2, false);
|
||||
if(hp1.first && hp2.first)
|
||||
current_display->radarlines.emplace_back(radarline{hp1.second, hp2.second, col});
|
||||
}
|
||||
|
|
|
@ -3164,10 +3164,10 @@ void addconfig() {
|
|||
param_f(hard_limit, "ray_hard_limit");
|
||||
param_i(want_use, "ray_want_use");
|
||||
param_f(exp_decay_poly, "ray_exp_decay_poly");
|
||||
addsaver(max_iter_iso, "ray_max_iter_iso");
|
||||
addsaver(max_iter_sol, "ray_max_iter_sol");
|
||||
param_i(max_iter_iso, "ray_max_iter_iso");
|
||||
param_i(max_iter_sol, "ray_max_iter_sol");
|
||||
param_i(max_cells, "ray_max_cells");
|
||||
addsaver(rays_generate, "ray_generate");
|
||||
param_b(rays_generate, "ray_generate");
|
||||
param_b(fixed_map, "ray_fixed_map");
|
||||
param_i(max_wall_offset, "max_wall_offset");
|
||||
param_i(max_celltype, "max_celltype");
|
||||
|
|
5
reg3.cpp
5
reg3.cpp
|
@ -2585,13 +2585,13 @@ int celldistance_534(cell *c1, cell *c2) {
|
|||
|
||||
vector<cell*> s1 = {c1};
|
||||
vector<cell*> s2 = {c2};
|
||||
int best = 99999999;
|
||||
int best = DISTANCE_UNKNOWN_BIG;
|
||||
int d0 = 0;
|
||||
|
||||
auto go_nearer = [&] (vector<cell*>& v, int& d) {
|
||||
vector<cell*> w;
|
||||
for(cell *c: v)
|
||||
forCellEx(c1, c)
|
||||
forCellCM(c1, c)
|
||||
if(celldist(c1) < d)
|
||||
w.push_back(c1);
|
||||
sort(w.begin(), w.end());
|
||||
|
@ -2612,6 +2612,7 @@ int celldistance_534(cell *c1, cell *c2) {
|
|||
if(d1 >= d2) go_nearer(s1, d1);
|
||||
if(d1 < d2) go_nearer(s2, d2);
|
||||
}
|
||||
if(best == DISTANCE_UNKNOWN_BIG) best = DISTANCE_UNKNOWN; /* just in case */
|
||||
|
||||
return best;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace hr {
|
|||
namespace ads_game {
|
||||
|
||||
void change_default_key(int key, int val) {
|
||||
char* t = scfg_ads.keyaction;
|
||||
int* t = scfg_ads.keyaction;
|
||||
t[key] = val;
|
||||
}
|
||||
|
||||
|
@ -154,8 +154,8 @@ void default_settings() {
|
|||
lps_add(lps_relhell, vid.drawmousecircle, false);
|
||||
lps_add(lps_relhell, draw_centerover, false);
|
||||
lps_add(lps_relhell, vid.axes3, false);
|
||||
lps_add(lps_relhell, patterns::whichCanvas, 'r');
|
||||
lps_add(lps_relhell, patterns::rwalls, 0);
|
||||
lps_add(lps_relhell, ccolor::which, &ccolor::random);
|
||||
lps_add(lps_relhell, ccolor::rwalls, 0);
|
||||
lps_add(lps_relhell, vid.fov, 150.);
|
||||
|
||||
lps_add(lps_relhell_ds_spacetime_klein, pmodel, mdDisk);
|
||||
|
@ -213,7 +213,7 @@ auto shot_hooks =
|
|||
+ addHook(hooks_configfile, 100, [] {
|
||||
param_f(ads_how_much_invincibility, "ads_invinc")
|
||||
-> editable(0, TAU, TAU/4, "AdS invincibility time", "How long does the period of invincibility after crashing last, in absolute units.", 'i');
|
||||
param_f(ds_how_much_invincibility, "ads_invinc")
|
||||
param_f(ds_how_much_invincibility, "ds_invinc")
|
||||
-> editable(0, TAU, TAU/4, "dS invincibility time", "How long does the period of invincibility after crashing last, in absolute units.", 'i');
|
||||
param_b(auto_angle, "ads_auto_angle")
|
||||
-> editable("automatically rotate the projection", 'a');
|
||||
|
@ -287,7 +287,7 @@ auto shot_hooks =
|
|||
param_i(spacetime_qty, "ads_spacetime_qty")
|
||||
-> editable(0, 100, 5, "step quantity in the spacetime display", "", 'q');
|
||||
|
||||
addsaver(ghost_color, "color:ghost");
|
||||
param_color(ghost_color, "color:ghost", true);
|
||||
|
||||
rsrc_config();
|
||||
});
|
||||
|
|
|
@ -82,7 +82,7 @@ void fire() {
|
|||
|
||||
bool handleKey(int sym, int uni) {
|
||||
if(cmode & sm::NORMAL) {
|
||||
char* t = scfg_ads.keyaction;
|
||||
int* t = scfg_ads.keyaction;
|
||||
if(t[sym] >= 16 && t[sym] < 32) return true;
|
||||
if(sym == 'v') pushScreen(game_menu);
|
||||
if(sym == SDLK_ESCAPE) pushScreen(game_menu);
|
||||
|
@ -159,7 +159,7 @@ bool ads_turn(int idelta) {
|
|||
if(a[16+7] && !la[16+7]) auto_rotate = !auto_rotate;
|
||||
if(a[16+8] && !la[16+8]) pushScreen(game_menu);
|
||||
|
||||
if(auto_angle) pconf.model_orientation += ang;
|
||||
if(auto_angle) pconf.mori().get() = spin(ang) * pconf.mori().get();
|
||||
|
||||
if(true) {
|
||||
|
||||
|
@ -219,7 +219,7 @@ bool ads_turn(int idelta) {
|
|||
else view_pt += tc;
|
||||
}
|
||||
|
||||
if(auto_angle) pconf.model_orientation -= ang;
|
||||
if(auto_angle) pconf.mori().get() = spin(-ang) * pconf.mori().get();
|
||||
|
||||
fixmatrix_ads(current.T);
|
||||
fixmatrix_ads(new_vctrV.T);
|
||||
|
|
|
@ -643,7 +643,7 @@ bool view_ads_ca() {
|
|||
flatresult center;
|
||||
vector<flatresult> hlist;
|
||||
|
||||
color_t statecolor;
|
||||
color_t statecolor = 0;
|
||||
if(1) {
|
||||
dynamicval<eGeometry> b(geometry, gRotSpace);
|
||||
shiftmatrix S = where_matrix[c];
|
||||
|
@ -750,7 +750,7 @@ bool view_ads_ca() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
addaura(shiftless(center.h), statecolor, 0);
|
||||
addaura(shiftless(center.h), statecolor, 0); // todo statecolor not changed
|
||||
}
|
||||
if(acc) {
|
||||
poly_outline = 0xFF;
|
||||
|
|
|
@ -1296,14 +1296,14 @@ void visual_menu() {
|
|||
|
||||
dialog::addSelItem(XLAT("iterations in raycasting"), its(ray::max_iter_current()), 's');
|
||||
dialog::add_action([&] {
|
||||
dialog::editNumber(ray::max_iter_current(), 0, 600, 1, 60, XLAT("iterations in raycasting"), "");
|
||||
dialog::reaction = ray::reset_raycaster;
|
||||
auto& di = dialog::editNumber(ray::max_iter_current(), 0, 600, 1, 60, XLAT("iterations in raycasting"), "");
|
||||
di.reaction = ray::reset_raycaster;
|
||||
});
|
||||
|
||||
dialog::addSelItem(XLAT("reflective walls in raycasting"), fts(ray::reflect_val), 'R');
|
||||
dialog::add_action([&] {
|
||||
dialog::editNumber(ray::reflect_val, 0, 1, 0.1, 0, XLAT("reflective walls"), "");
|
||||
dialog::reaction = ray::reset_raycaster;
|
||||
auto& di = dialog::editNumber(ray::reflect_val, 0, 1, 0.1, 0, XLAT("reflective walls"), "");
|
||||
di.reaction = ray::reset_raycaster;
|
||||
});
|
||||
|
||||
dialog::addSelItem(XLAT("cells to draw per level"), its(draw_per_level), 'R');
|
||||
|
@ -2032,7 +2032,7 @@ int args() {
|
|||
}
|
||||
|
||||
void change_default_key(int key, int val) {
|
||||
char* t = scfg_bringris.keyaction;
|
||||
int* t = scfg_bringris.keyaction;
|
||||
t[key] = val;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,7 @@ void run_sb() {
|
|||
crystal::set_crystal(6);
|
||||
set_variation(eVariation::pure);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = 0x101010;
|
||||
ccolor::set_plain(0x101010);
|
||||
check_cgi();
|
||||
start_game();
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@ void compute_betweenness(bool verify) {
|
|||
auto b = betweenness3(c1);
|
||||
// add_to_set(c1, 1, 0);
|
||||
auto b4 = betweenness4(c1);
|
||||
print(hlog, hr::format("B;%10Ld;%10Ld;%20.10Lf;%3d;%-40s", b.first, b.second, b4, vertices[i]->lev, rogueviz::vdata[i].name.c_str()));
|
||||
print(hlog, hr::format("B;%10lld;%10lld;%20.10f;%3d;%-40s", b.first, b.second, (double) b4, vertices[i]->lev, rogueviz::vdata[i].name.c_str()));
|
||||
if(verify) {
|
||||
/*
|
||||
betweenness_type a = b.first;
|
||||
|
|
|
@ -86,7 +86,8 @@ int movearound() {
|
|||
int move_restart() {
|
||||
indenter_finish im("move_restart");
|
||||
ld llo = loglik_chosen();
|
||||
array<array<int, 128>, 2> distances_map = {0};
|
||||
array<array<int, 128>, 2> distances_map;
|
||||
for(int a=0; a<2; a++) for(int b=0; b<128; b++) distances_map[a][b] = 0;
|
||||
int moves = 0;
|
||||
// int im = 0;
|
||||
|
||||
|
@ -319,7 +320,7 @@ void load_embedded(const string s) {
|
|||
while(true) {
|
||||
char who[500], where[500];
|
||||
who[0] = 0;
|
||||
fscanf(f, "%s%s", who, where);
|
||||
if(fscanf(f, "%s%s", who, where) < 0) throw hstream_exception("error loading embedding");
|
||||
if(who[0] == 0) break;
|
||||
if(!ids.count(who)) printf("unknown vertex: %s\n", who);
|
||||
string wh = where;
|
||||
|
|
|
@ -139,8 +139,7 @@ void cellcoords() {
|
|||
// needs cellcoords/rvcoords/origcoords
|
||||
void build_disttable() {
|
||||
indenter_finish im("build_disttable");
|
||||
int tab[N];
|
||||
for(int i=0; i<N; i++) tab[i] = N;
|
||||
vector<int> tab(N, N);
|
||||
disttable0.clear();
|
||||
disttable1.clear();
|
||||
|
||||
|
@ -269,7 +268,7 @@ void writestats() {
|
|||
ld placement_loglik = loglik_placement();
|
||||
|
||||
for(int u=0; u<MAXDIST; u++) if(tally[u]) {
|
||||
println(hlog, hr::format("* %4d: %8d / %12Ld = %lf %.10" PLDF " %.10" PLDF,
|
||||
println(hlog, hr::format("* %4d: %8d / %12lld = %lf %.10" PLDF " %.10" PLDF,
|
||||
u, edgetally[u], tally[u], double(edgetally[u]) / tally[u],
|
||||
saved_logistic.yes(u), current_logistic.yes(u)));
|
||||
}
|
||||
|
@ -338,8 +337,7 @@ void build_disttable_approx() {
|
|||
for(int k=0; k<threads; k++)
|
||||
v.emplace_back([&,k] () {
|
||||
auto& dt = results[k];
|
||||
int tab[N];
|
||||
for(int i=0; i<N; i++) tab[i] = N;
|
||||
vector<int> tab(N, N);
|
||||
auto p = k ? nullptr : new progressbar(N/threads, "build_disttable_approx");
|
||||
for(int i=k; i<N; i+=threads) {
|
||||
if(p) (*p)++;
|
||||
|
|
|
@ -53,7 +53,7 @@ void test_paths(int radius) {
|
|||
add_to_tally(mc2, 1, 0);
|
||||
// int v = 0;
|
||||
if(tally[quickdist(mc1, mc2)] != 1) {
|
||||
printf("[%p] [%p]\n", mc1, mc2);
|
||||
printf("[%p] [%p]\n", (void*) mc1, (void*) mc2);
|
||||
printf("quickdist = %d\n", quickdist(mc1, mc2));
|
||||
for(int i=0; i<MAXDIST; i++) if(tally[i]) printf("in tally = %d\n", i);
|
||||
mc1->ascell()->item = itDiamond;
|
||||
|
|
|
@ -35,6 +35,9 @@ struct embset {
|
|||
string name;
|
||||
geom3::eSpatialEmbedding se;
|
||||
ld walls, scale, depth, eye, sun, sky, star;
|
||||
embset(const string& n, geom3::eSpatialEmbedding se, ld walls, ld scale, ld depth, ld eye, ld sun, ld sky, ld star) :
|
||||
name(n), se(se), walls(walls), scale(scale), depth(depth), eye(eye), sun(sun), sky(sky), star(star) {}
|
||||
embset() {}
|
||||
};
|
||||
|
||||
embset current() {
|
||||
|
@ -94,30 +97,30 @@ void print(hstream& hs, const embset& e) {
|
|||
print(hlog, "embset{.name=\"", e.name, "\", .se=eEmbeddingMethod(", int(e.se), "), .walls=", e.walls, ", .scale=", e.scale, ", .depth=", e.depth, ", .eye=", e.eye, ", .sun=", e.sun, ", .sky=", e.sky, ", .star=", e.star, "}");
|
||||
}
|
||||
|
||||
embset edefault = embset{.name="default", .se=geom3::seDefault, .walls=1.2, .scale=0, .depth=0, .eye=1.5, .sun=0.333333, .sky=10, .star=9};
|
||||
embset edefaulti = embset{.name="default", .se=geom3::seDefault, .walls=-1.2, .scale=0, .depth=0, .eye=-1.5, .sun=0.333333, .sky=10, .star=9};
|
||||
embset edefault = embset("default", geom3::seDefault, 1.2, 0, 0, 1.5, 0.333333, 10, 9);
|
||||
embset edefaulti = embset("default", geom3::seDefault, -1.2, 0, 0, 1.5, 0.333333, 10, 9);
|
||||
// embset eincyl = embset{.name="in cylinder", .se=geom3::seCylinderE, .walls=0.75, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=4, .star=3.6};
|
||||
embset eincyl = embset{.name="in cylinder E", .se=geom3::seCylinderE, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eoutcyl = embset{.name="out cylinder E", .se=geom3::seCylinderE, .walls=-1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.3, .sky=10, .star=9};
|
||||
embset eouthoro = embset{.name="out horosphere", .se=geom3::seLowerCurvature, .walls=1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=8, .star=7.5};
|
||||
embset einhoro = embset{.name="in horosphere", .se=geom3::seLowerCurvature, .walls=-1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=12, .star=11};
|
||||
embset einhoro_small = embset{.name="in horosphere (small sky)", .se=geom3::seLowerCurvature, .walls=-1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=18, .star=17};
|
||||
embset esolv = embset{.name="solv", .se=geom3::seSol, .walls=1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=12, .star=11};
|
||||
embset einnih = embset{.name="in NIH", .se=geom3::seNIH, .walls=-1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=12, .star=11};
|
||||
embset eoutnih = embset{.name="out NIH", .se=geom3::seNIH, .walls=1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=8, .star=7.5};
|
||||
embset eclifford = embset{.name="Clifford", .se=geom3::seCliffordTorus, .walls=1.2, .scale=M_PI/10, .depth=-0.0561826, .eye=1.5, .sun=0.25, .sky=2.55, .star=2.3};
|
||||
embset enil = embset{.name="Nil flat", .se=geom3::seNil, .walls=1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=12, .star=11};
|
||||
embset esl2 = embset{.name="SL(2,R) flat", .se=geom3::seSL2, .walls=1.2, .scale=0.1, .depth=0, .eye=1.5, .sun=0.25, .sky=12, .star=11};
|
||||
embset eincylh = embset{.name="in cylinderH", .se=geom3::seCylinderH, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eincylhe = embset{.name="in cylinderHE", .se=geom3::seCylinderHE, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eincylnil = embset{.name="in cylinder Nil", .se=geom3::seCylinderNil, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eincylsl = embset{.name="in cylinder SL(2,R)", .se=geom3::seCylinderSL2, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset einhorocyl = embset{.name="in horocylinder", .se=geom3::seCylinderHoro, .walls=-1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=8, .star=7.5};
|
||||
embset eouthorocyl = embset{.name="out horocylinder", .se=geom3::seCylinderHoro, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=4, .star=3.5};
|
||||
embset eprodh_flat = embset{.name="hyperbolic product (flat)", .se=geom3::seProductH, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eprodh_concave = embset{.name="hyperbolic product (concave)", .se=geom3::seProductH, .walls=1.2, .scale=M_PI/10, .depth=1, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eprods_flat = embset{.name="spherical product (flat)", .se=geom3::seProductS, .walls=1.2, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eprods_concave = embset{.name="spherical product (concave)", .se=geom3::seProductS, .walls=1.2, .scale=M_PI/10, .depth=0.8333, .eye=1.5, .sun=0.10472, .sky=2.6, .star=2.4};
|
||||
embset eincyl = embset("in cylinder E", geom3::seCylinderE, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eoutcyl = embset("out cylinder E", geom3::seCylinderE, -1.2, M_PI/10, 0, 1.5, 0.3, 10, 9);
|
||||
embset eouthoro = embset("out horosphere", geom3::seLowerCurvature, 1.2, 0.1, 0, 1.5, 0.25, 8, 7.5);
|
||||
embset einhoro = embset("in horosphere", geom3::seLowerCurvature, -1.2, 0.1, 0, 1.5, 0.25, 12, 11);
|
||||
embset einhoro_small = embset("in horosphere (small sky)", geom3::seLowerCurvature, -1.2, 0.1, 0, 1.5, 0.25, 18, 17);
|
||||
embset esolv = embset("solv", geom3::seSol, 1.2, 0.1, 0, 1.5, 0.25, 12, 11);
|
||||
embset einnih = embset("in NIH", geom3::seNIH, -1.2, 0.1, 0, 1.5, 0.25, 12, 11);
|
||||
embset eoutnih = embset("out NIH", geom3::seNIH, 1.2, 0.1, 0, 1.5, 0.25, 8, 7.5);
|
||||
embset eclifford = embset("Clifford", geom3::seCliffordTorus, 1.2, M_PI/10, -0.0561826, 1.5, 0.25, 2.55, 2.3);
|
||||
embset enil = embset("Nil flat", geom3::seNil, 1.2, 0.1, 0, 1.5, 0.25, 12, 11);
|
||||
embset esl2 = embset("SL(2,R) flat", geom3::seSL2, 1.2, 0.1, 0, 1.5, 0.25, 12, 11);
|
||||
embset eincylh = embset("in cylinderH", geom3::seCylinderH, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eincylhe = embset("in cylinderHE", geom3::seCylinderHE, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eincylnil = embset("in cylinder Nil", geom3::seCylinderNil, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eincylsl = embset("in cylinder SL(2,R)", geom3::seCylinderSL2, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset einhorocyl = embset("in horocylinder", geom3::seCylinderHoro, -1.2, M_PI/10, 0, 1.5, 0.10472, 8, 7.5);
|
||||
embset eouthorocyl = embset("out horocylinder", geom3::seCylinderHoro, 1.2, M_PI/10, 0, 1.5, 0.10472, 4, 3.5);
|
||||
embset eprodh_flat = embset("hyperbolic product (flat)", geom3::seProductH, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eprodh_concave = embset("hyperbolic product (concave)", geom3::seProductH, 1.2, M_PI/10, 1, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eprods_flat = embset("spherical product (flat)", geom3::seProductS, 1.2, M_PI/10, 0, 1.5, 0.10472, 2.6, 2.4);
|
||||
embset eprods_concave = embset("spherical product (concave)", geom3::seProductS, 1.2, M_PI/10, 0.8333, 1.5, 0.10472, 2.6, 2.4);
|
||||
|
||||
embset& edok() { return vid.wall_height > 0 ? edefault : edefaulti; }
|
||||
|
||||
|
|
|
@ -325,6 +325,8 @@ bool view_labels = true, view_lines = true;
|
|||
|
||||
namespace hr {
|
||||
|
||||
extern ccolor::data grigorchuk_coloring;
|
||||
|
||||
struct hrmap_grigorchuk : hrmap_standard {
|
||||
|
||||
heptagon *origin;
|
||||
|
@ -411,8 +413,8 @@ struct hrmap_grigorchuk : hrmap_standard {
|
|||
|
||||
if(grigorchuk::view_labels) queuestr(V, 0.3, grigorchuk::deform(dec[c->master]), 0xFFFFFF);
|
||||
|
||||
if(patterns::whichCanvas == 'G' && c->landparam == 0)
|
||||
c->landparam = 0x102008 * (1 + ((hrmap_grigorchuk*)currentmap)->dec[c->master]->len);
|
||||
if(ccolor::which == &grigorchuk_coloring && c->landparam == 0)
|
||||
c->landparam = grigorchuk_coloring(c);
|
||||
|
||||
drawcell(c, V * currentmap->master_relative(c, false));
|
||||
|
||||
|
@ -436,6 +438,10 @@ struct hrmap_grigorchuk : hrmap_standard {
|
|||
|
||||
eGeometry gGrigorchuk(eGeometry(-1));
|
||||
|
||||
ccolor::data grigorchuk_coloring = ccolor::data("Grigorchuk", [] { return geometry == gGrigorchuk; }, [] (cell *c, ccolor::data& cco) {
|
||||
return 0x102008 * (1 + ((hrmap_grigorchuk*)currentmap)->dec[c->master]->len);
|
||||
}, {});
|
||||
|
||||
void create_grigorchuk_geometry() {
|
||||
if(gGrigorchuk != eGeometry(-1)) return;
|
||||
ginf.push_back(ginf[gNormal]);
|
||||
|
@ -449,6 +455,7 @@ void create_grigorchuk_geometry() {
|
|||
gi.menu_displayed_name = "Grigorchuk group";
|
||||
gi.shortname = "Grig";
|
||||
gi.default_variation = eVariation::pure;
|
||||
ccolor::all.push_back(&grigorchuk_coloring);
|
||||
}
|
||||
|
||||
int readArgsG() {
|
||||
|
@ -483,11 +490,6 @@ int readArgsG() {
|
|||
|
||||
auto hook = addHook(hooks_args, 100, readArgsG)
|
||||
+ addHook(hooks_newmap, 100, [] { return geometry == gGrigorchuk ? new hrmap_grigorchuk : nullptr; })
|
||||
+ addHook(patterns::hooks_generate_canvas, 100, [] (cell* c) {
|
||||
if(patterns::whichCanvas == 'G' && geometry == gGrigorchuk)
|
||||
return 0x102008 * (1 + ((hrmap_grigorchuk*)currentmap)->dec[c->master]->len);
|
||||
return -1;
|
||||
})
|
||||
+ addHook(dialog::hooks_display_dialog, 100, [] () {
|
||||
if(current_screen_cfunction() == showEuclideanMenu && geometry == gGrigorchuk) {
|
||||
dialog::addBoolItem_action(XLAT("Grigorchuk lines"), grigorchuk::view_lines, 'L');
|
||||
|
@ -516,7 +518,7 @@ auto hook = addHook(hooks_args, 100, readArgsG)
|
|||
if(mode == pmStart) {
|
||||
grigorchuk::grig_limit = 10000;
|
||||
gamestack::push();
|
||||
slide_backup(patterns::whichCanvas, 'G');
|
||||
slide_backup(ccolor::which, &grigorchuk_coloring);
|
||||
slide_backup(firstland, laCanvas);
|
||||
slide_backup(specialland, laCanvas);
|
||||
set_geometry(gGrigorchuk);
|
||||
|
|
|
@ -74,8 +74,7 @@ void run_cpick() {
|
|||
crystal::set_crystal(6);
|
||||
set_variation(eVariation::pure);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = 0;
|
||||
ccolor::set_plain(0);
|
||||
check_cgi();
|
||||
start_game();
|
||||
current_center = currentmap->gamestart();
|
||||
|
@ -208,8 +207,7 @@ void run_sb() {
|
|||
crystal::set_crystal(6);
|
||||
set_variation(eVariation::pure);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = 0;
|
||||
ccolor::set_plain(0);
|
||||
check_cgi();
|
||||
rv_hook(hooks_drawcell, 100, sokomap);
|
||||
start_game();
|
||||
|
@ -394,7 +392,7 @@ int mycanvas(cell *c) {
|
|||
}
|
||||
|
||||
void enable() {
|
||||
rv_hook(patterns::hooks_generate_canvas, 100, mycanvas);
|
||||
rv_hook(ccolor::hooks_generate_canvas, 100, mycanvas);
|
||||
}
|
||||
|
||||
auto explore_structure(int _shapeid) {
|
||||
|
@ -407,7 +405,7 @@ auto explore_structure(int _shapeid) {
|
|||
stop_game();
|
||||
set_geometry(geometry == gCrystal534 ? gCrystal534 : gCrystal344);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = ' ';
|
||||
ccolor::which = &ccolor::plain;
|
||||
shapeid = _shapeid;
|
||||
enable();
|
||||
crystal::crystal_period = 4;
|
||||
|
@ -444,7 +442,7 @@ void house(int sides, int shape = 10) {
|
|||
crystal::set_crystal(sides);
|
||||
set_variation(eVariation::pure);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = ' ';
|
||||
ccolor::which = &ccolor::plain;
|
||||
shapeid = shape;
|
||||
check_cgi();
|
||||
enable();
|
||||
|
@ -466,7 +464,7 @@ tour::slide *gen_high_demo() {
|
|||
sync(mode, VC);
|
||||
if(mode == pmStart) {
|
||||
crystal::set_crystal(6);
|
||||
patterns::whichCanvas = 'K';
|
||||
ccolor::which = &ccolor::crystal_colors;
|
||||
start_game();
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +477,7 @@ tour::slide *gen_high_demo() {
|
|||
sync(mode, VC);
|
||||
if(mode == pmStart) {
|
||||
crystal::set_crystal(8);
|
||||
patterns::whichCanvas = 'K';
|
||||
ccolor::which = &ccolor::crystal_colors;
|
||||
start_game();
|
||||
}
|
||||
}
|
||||
|
@ -563,10 +561,7 @@ tour::slide *gen_high_demo() {
|
|||
sync(mode, NO_VC | PLAYER);
|
||||
if(mode == pmStart) {
|
||||
crystal::set_crystal(6);
|
||||
patterns::whichCanvas = 'c';
|
||||
colortables['c'][0] = 0x208020;
|
||||
colortables['c'][1] = 0x105010;
|
||||
patterns::canvasback = 0x101010;
|
||||
ccolor::set_colors(ccolor::chessboard, {0x208020, 0x105010});
|
||||
start_game();
|
||||
auto & us = vid.cs;
|
||||
us.charid = 4;
|
||||
|
|
|
@ -374,10 +374,8 @@ void enable() {
|
|||
|
||||
vid.linequality = 4;
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'F';
|
||||
|
||||
colortables['F'][0] = 0x80C080;
|
||||
colortables['F'][1] = 0x80A080;
|
||||
ccolor::set_colors(ccolor::football, {0x80C080, 0x80A080});
|
||||
pconf.scale = .3;
|
||||
|
||||
vid.use_smart_range = 2;
|
||||
|
|
|
@ -246,7 +246,7 @@ vector<cell*> current_list;
|
|||
|
||||
void mine_slide(tour::presmode mode, reaction_t set_geom, function<vector<cell*>()> celllister, function<void(cell*)> assigner) {
|
||||
using namespace tour;
|
||||
patterns::canvasback = 0;
|
||||
ccolor::plain.ctab = {0};
|
||||
setCanvas(mode, '0');
|
||||
if(mode == pmStart) {
|
||||
slide_backup(mapeditor::drawplayer, false);
|
||||
|
@ -334,7 +334,7 @@ void enable_earth() {
|
|||
stop_game();
|
||||
set_geometry(gSphere);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'F';
|
||||
ccolor::which = &ccolor::football;
|
||||
start_game();
|
||||
texture::config.configname = "textures/earth.txc";
|
||||
texture::config.load();
|
||||
|
@ -543,8 +543,8 @@ slide sweeper_slides[] = {
|
|||
stop_game();
|
||||
set_geometry(g45);
|
||||
set_variation(eVariation::pure);
|
||||
tour::slide_backup(colortables['c'][0], 0x104010);
|
||||
tour::slide_backup(colortables['c'][1], 0x10F010);
|
||||
tour::slide_backup(ccolor::chessboard.ctab[0], 0x104010);
|
||||
tour::slide_backup(ccolor::chessboard.ctab[1], 0x10F010);
|
||||
tour::slide_backup(vid.use_smart_range, 2);
|
||||
tour::slide_backup(vid.smart_range_detail, 1);
|
||||
start_game();
|
||||
|
@ -562,7 +562,7 @@ slide sweeper_slides[] = {
|
|||
setCanvas(mode, 'g');
|
||||
non_game_slide_scroll(mode);
|
||||
if(mode == pmStart) {
|
||||
tour::slide_backup(patterns::canvasback, 0x10A010);
|
||||
tour::slide_backup(ccolor::plain.ctab[0], 0x10A010);
|
||||
stop_game();
|
||||
set_geometry(gBinary4);
|
||||
set_variation(eVariation::pure);
|
||||
|
@ -840,7 +840,7 @@ slide sweeper_slides[] = {
|
|||
setCanvas(mode, 'g');
|
||||
non_game_slide_scroll(mode);
|
||||
if(mode == pmStart) {
|
||||
tour::slide_backup(patterns::canvasback, 0x10A010);
|
||||
tour::slide_backup(ccolor::plain.ctab[0], 0x10A010);
|
||||
stop_game();
|
||||
set_geometry(gBinary4);
|
||||
set_variation(eVariation::pure);
|
||||
|
|
|
@ -217,8 +217,7 @@ void create_intra_solv() {
|
|||
}
|
||||
|
||||
void create_intra_120() {
|
||||
patterns::whichCanvas = 'r';
|
||||
patterns::rwalls = 0;
|
||||
ccolor::set_random(0);
|
||||
if(intra::in) intra::become();
|
||||
else stop_game();
|
||||
arcm::current.parse("8,4,6");
|
||||
|
@ -261,8 +260,7 @@ void create_intra_120() {
|
|||
}
|
||||
|
||||
void create_intra_1440() {
|
||||
patterns::whichCanvas = 'r';
|
||||
patterns::rwalls = 0;
|
||||
ccolor::set_random(0);
|
||||
if(intra::in) intra::become();
|
||||
else stop_game();
|
||||
set_geometry(gCell8);
|
||||
|
@ -330,8 +328,7 @@ vector<reaction_t> portals;
|
|||
|
||||
void create_intra_bxe() {
|
||||
println(hlog, "called create_intra_bxe");
|
||||
patterns::whichCanvas = 'r';
|
||||
patterns::rwalls = 100;
|
||||
ccolor::set_random(100);
|
||||
if(intra::in) intra::become();
|
||||
else stop_game();
|
||||
hybrid::csteps = 0;
|
||||
|
@ -404,8 +401,7 @@ void recurse_portal_solv2(int r, cell *cl, cell *cr) {
|
|||
|
||||
void create_intra_sol() {
|
||||
println(hlog, "called create_intra_sol");
|
||||
patterns::whichCanvas = 'r';
|
||||
patterns::rwalls = 100;
|
||||
ccolor::set_random(100);
|
||||
if(intra::in) intra::become();
|
||||
else stop_game();
|
||||
|
||||
|
@ -534,6 +530,12 @@ bool vr_keys(int sym, int uni) {
|
|||
|
||||
// all generators will add to the current scene
|
||||
|
||||
#if CAP_VR
|
||||
#define IF_VR(x) x
|
||||
#else
|
||||
#define IF_VR(x)
|
||||
#endif
|
||||
|
||||
auto hooks =
|
||||
// generate scene with H3, H2xE, E3, S2xE (8x6), S3 (16-cell) with floors; runs automatically
|
||||
arg::add3("-intra-floors", create_intra_floors)
|
||||
|
@ -574,11 +576,11 @@ auto hooks =
|
|||
mapstream::loadMap(s);
|
||||
slide_backup(ray::fixed_map, true);
|
||||
slide_backup(ray::max_iter_intra, y);
|
||||
#if CAP_VR
|
||||
IF_VR(
|
||||
slide_backup(vrhr::hsm, vrhr::eHeadset::holonomy);
|
||||
slide_backup(vrhr::eyes, vrhr::eEyes::truesim);
|
||||
slide_backup(vrhr::cscr, vrhr::eCompScreen::eyes);
|
||||
#endif
|
||||
)
|
||||
starter.clear();
|
||||
rogueviz::rv_hook(hooks_handleKey, 101, vr_keys);
|
||||
popScreenAll();
|
||||
|
@ -630,5 +632,6 @@ auto hooks =
|
|||
{loader{"run this visualization", 'r', load("solv-h3-scene.lev", 0.05, 3000)}});
|
||||
}));
|
||||
}
|
||||
#undef IF_VR
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -144,8 +144,7 @@ void magic(int sides) {
|
|||
crystal::set_crystal(sides);
|
||||
set_variation(eVariation::pure);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'g';
|
||||
patterns::canvasback = back;
|
||||
ccolor::set_plain(back);
|
||||
check_cgi();
|
||||
start_game();
|
||||
|
||||
|
|
|
@ -559,7 +559,7 @@ void pick_pattern() {
|
|||
dialog::add_action([] {
|
||||
chg_pattern([] {
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'B';
|
||||
ccolor::which = &ccolor::sides;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -570,7 +570,7 @@ void pick_pattern() {
|
|||
gp::param.second = 0;
|
||||
set_variation(eVariation::goldberg);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'F';
|
||||
ccolor::which = &ccolor::football;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -579,7 +579,7 @@ void pick_pattern() {
|
|||
chg_pattern([] {
|
||||
set_geometry(gOctagon);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'T';
|
||||
ccolor::which = &ccolor::zebra_stripes;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -612,7 +612,7 @@ void pick_pattern() {
|
|||
arcm::current.parse("4^5");
|
||||
set_geometry(gArchimedean);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'A';
|
||||
ccolor::which = &ccolor::shape;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ void run() {
|
|||
dialog::add_key_action(PSEUDOKEY_SIM, toggle_replay);
|
||||
dialog::display();
|
||||
|
||||
char* t = scfg_nilrider.keyaction;
|
||||
int* t = scfg_nilrider.keyaction;
|
||||
for(int i=1; i<512; i++) {
|
||||
auto& ka = dialog::key_actions;
|
||||
if(t[i] == 16+5) ka[i] = ka[PSEUDOKEY_PAUSE];
|
||||
|
@ -544,7 +544,7 @@ void main_menu() {
|
|||
bool on;
|
||||
|
||||
void change_default_key(int key, int val) {
|
||||
char* t = scfg_nilrider.keyaction;
|
||||
int* t = scfg_nilrider.keyaction;
|
||||
t[key] = val;
|
||||
}
|
||||
|
||||
|
@ -585,12 +585,13 @@ local_parameter_set lps_nilrider("nilrider:");
|
|||
|
||||
void default_settings() {
|
||||
lps_add(lps_nilrider, vid.cells_drawn_limit, 1);
|
||||
lps_add(lps_nilrider, (color_t&) patterns::canvasback, 0);
|
||||
lps_add(lps_nilrider, ccolor::plain.ctab, colortable{0});
|
||||
lps_add(lps_nilrider, smooth_scrolling, true);
|
||||
lps_add(lps_nilrider, mapeditor::drawplayer, false);
|
||||
lps_add(lps_nilrider, backcolor, 0xC0C0FFFF);
|
||||
lps_add(lps_nilrider, logfog, 1);
|
||||
lps_add(lps_nilrider, patterns::whichCanvas, 0);
|
||||
lps_add(lps_nilrider, ccolor::which, &ccolor::plain);
|
||||
lps_add(lps_nilrider, ccolor::rwalls, 0);
|
||||
|
||||
#if CAP_VR
|
||||
lps_add(lps_nilrider, vrhr::hsm, vrhr::eHeadset::reference);
|
||||
|
@ -611,10 +612,10 @@ void initialize() {
|
|||
|
||||
curlev->init();
|
||||
|
||||
param_enum(planning_mode, "nil_planning", "nil_planning", false)
|
||||
param_enum(planning_mode, "nil_planning", false)
|
||||
-> editable({{"manual", "control the unicycle manually"}, {"planning", "try to plan the optimal route!"}}, "game mode", 'p');
|
||||
|
||||
param_enum(stepped_display, "stepped_display", "stepped_display", false)
|
||||
param_enum(stepped_display, "stepped_display", false)
|
||||
-> editable({{"smooth", "ride on a smooth surface"}, {"blocky", "makes slopes more visible -- actual physics are not affected"}}, "game mode", 's');
|
||||
|
||||
param_i(nilrider_tempo, "nilrider_tempo");
|
||||
|
|
|
@ -26,10 +26,10 @@ auto geoslide(eGeometry g, char canvas, int jhole, int jblock) {
|
|||
tour::slide_backup<ld>(sightranges[gSol], 7);
|
||||
tour::slide_backup<ld>(sightranges[gSpace435], 7);
|
||||
vid.texture_step = 4;
|
||||
tour::slide_backup(patterns::jhole, jhole);
|
||||
tour::slide_backup(patterns::rwalls, jhole);
|
||||
tour::slide_backup(patterns::jblock, jblock);
|
||||
tour::slide_backup(patterns::whichCanvas, canvas);
|
||||
tour::slide_backup(ccolor::jhole, jhole);
|
||||
tour::slide_backup(ccolor::rwalls, jhole);
|
||||
tour::slide_backup(ccolor::jblock, jblock);
|
||||
tour::slide_backup(ccolor::which, ccolor::legacy(canvas));
|
||||
tour::slide_backup(vid.linewidth, vid.linewidth / 10);
|
||||
start_game();
|
||||
if(jblock < 0) {
|
||||
|
@ -45,7 +45,7 @@ auto geoslide(eGeometry g, char canvas, int jhole, int jblock) {
|
|||
if(in_special && among(mode, pmGeometrySpecial, pmStop)) {
|
||||
in_special = false;
|
||||
gamestack::pop();
|
||||
patterns::whichCanvas = canvas;
|
||||
ccolor::which = ccolor::legacy(canvas);
|
||||
vid.grid = false;
|
||||
fat_edges = false;
|
||||
sightranges[gSpace435] = 7;
|
||||
|
@ -54,7 +54,7 @@ auto geoslide(eGeometry g, char canvas, int jhole, int jblock) {
|
|||
else if(mode == pmGeometrySpecial && !in_special) {
|
||||
in_special = true;
|
||||
gamestack::push();
|
||||
patterns::whichCanvas = 'g';
|
||||
ccolor::set_plain(0);
|
||||
vid.grid = true;
|
||||
stdgridcolor = 0xFFFF00FF;
|
||||
fat_edges = true;
|
||||
|
|
|
@ -114,7 +114,7 @@ void run_snub(int v, int w) {
|
|||
check_cgi();
|
||||
cgi.require_basics();
|
||||
specialland = laCanvas;
|
||||
patterns::whichCanvas = 'A';
|
||||
ccolor::which = &ccolor::shape;
|
||||
// vid.wallmode = 1;
|
||||
printf("start game\n");
|
||||
printf("distlimit = %d\n", cgi.base_distlimit);
|
||||
|
|
|
@ -591,7 +591,7 @@ void enable_earth() {
|
|||
stop_game();
|
||||
set_geometry(gSphere);
|
||||
enable_canvas();
|
||||
patterns::whichCanvas = 'F';
|
||||
ccolor::which = &ccolor::football;
|
||||
start_game();
|
||||
texture::config.configname = "textures/earth.txc";
|
||||
texture::config.load();
|
||||
|
@ -635,8 +635,8 @@ slide dmv_slides[] = {
|
|||
set_geometry(gArchimedean); arcm::current.parse("3^6");
|
||||
set_variation(eVariation::pure);
|
||||
|
||||
slide_backup(colortables['F'][0], 0xC0FFC0);
|
||||
slide_backup(colortables['F'][1], 0x80FF80);
|
||||
slide_backup(ccolor::football.ctab[0], 0xC0FFC0);
|
||||
slide_backup(ccolor::football.ctab[1], 0x80FF80);
|
||||
slide_backup(pconf.alpha, 1);
|
||||
slide_backup(pconf.scale, 1);
|
||||
start_game();
|
||||
|
@ -708,8 +708,8 @@ slide dmv_slides[] = {
|
|||
slide_backup(specialland, laCanvas);
|
||||
set_geometry(gNormal);
|
||||
set_variation(eVariation::bitruncated);
|
||||
slide_backup(colortables['F'][0], 0xC0FFC0);
|
||||
slide_backup(colortables['F'][1], 0x80FF80);
|
||||
slide_backup(ccolor::football.ctab[0], 0xC0FFC0);
|
||||
slide_backup(ccolor::football.ctab[1], 0x80FF80);
|
||||
slide_backup(pconf.alpha, 1);
|
||||
slide_backup(pconf.scale, 1);
|
||||
slide_backup(rug::mouse_control_rug, true);
|
||||
|
@ -755,7 +755,7 @@ slide dmv_slides[] = {
|
|||
|
||||
[] (presmode mode) {
|
||||
if(mode == pmStart) {
|
||||
slide_backup(patterns::rwalls, 10);
|
||||
slide_backup(ccolor::rwalls, 10);
|
||||
slide_backup(vid.fov, 120);
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,12 @@ int args() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if CAP_RAY
|
||||
#define IF_RAY(x) x
|
||||
#else
|
||||
#define IF_RAY(x)
|
||||
#endif
|
||||
|
||||
auto hooks =
|
||||
addHook(hooks_args, 100, args)
|
||||
+ addHook_rvslides(180, [] (string s, vector<tour::slide>& v) {
|
||||
|
@ -214,10 +220,10 @@ auto hooks =
|
|||
set_geometry(gRotSpace);
|
||||
slide_backup(rots::underlying_scale, .25);
|
||||
slide_backup(qmode, m);
|
||||
#if CAP_RAY
|
||||
IF_RAY(
|
||||
slide_backup(ray::max_cells, 32768);
|
||||
slide_backup(ray::fixed_map, true);
|
||||
#endif
|
||||
)
|
||||
slide_backup(camera_speed, .1);
|
||||
enable();
|
||||
start_game();
|
||||
|
@ -240,11 +246,11 @@ auto hooks =
|
|||
set_geometry(gRotSpace);
|
||||
slide_backup(rots::underlying_scale, .25);
|
||||
slide_backup(qmode, m);
|
||||
#if CAP_RAY
|
||||
IF_RAY(
|
||||
slide_backup(ray::max_cells, 32768);
|
||||
slide_backup(ray::fixed_map, true);
|
||||
slide_backup(ray::want_use, 2);
|
||||
#endif
|
||||
)
|
||||
slide_backup(camera_speed, .1);
|
||||
enable();
|
||||
start_game();
|
||||
|
@ -256,6 +262,7 @@ auto hooks =
|
|||
}
|
||||
});
|
||||
|
||||
#undef IF_RAY
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ bool labeller(cell* c, const shiftmatrix& V) {
|
|||
if(m) {
|
||||
string s = m->asg[c->master].second;
|
||||
cgi.scalefactor = 1;
|
||||
queuestr(V, 0.5, s, colortables['j'][c->master->distance+1]);
|
||||
queuestr(V, 0.5, s, ccolor::jmap.ctab[c->master->distance+1]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace rogueviz {
|
|||
template<class T, class U> function<void(presmode)> roguevizslide(char c, const T& t, const U& f) {
|
||||
return [c,t,f] (presmode mode) {
|
||||
f(mode);
|
||||
patterns::canvasback = 0x101010;
|
||||
ccolor::plain.ctab = {0x101010};
|
||||
setCanvas(mode, c);
|
||||
if(mode == 1 || mode == pmGeometryStart) t();
|
||||
|
||||
|
@ -201,7 +201,7 @@ template<class T> function<void(presmode)> roguevizslide(char c, const T& t) { r
|
|||
template<class T, class U>
|
||||
function<void(presmode)> roguevizslide_action(char c, const T& t, const U& act) {
|
||||
return [c,t,act] (presmode mode) {
|
||||
patterns::canvasback = 0x101010;
|
||||
ccolor::plain.ctab = {0x101010};
|
||||
setCanvas(mode, c);
|
||||
if(mode == pmStart || mode == pmGeometryStart) t();
|
||||
|
||||
|
@ -342,6 +342,8 @@ namespace objmodels {
|
|||
virtual void process_triangle(vector<hyperpoint>& hys, vector<hyperpoint>& tot, bool textured, object *co);
|
||||
|
||||
bool available();
|
||||
|
||||
virtual ~model() {}
|
||||
};
|
||||
|
||||
void add_model_settings();
|
||||
|
|
|
@ -431,7 +431,7 @@ namespace sag {
|
|||
|
||||
if(t2 - tl > 980) {
|
||||
tl = t2;
|
||||
println(hlog, hr::format("it %12Ld temp %6.4f [1/e at %13.6f] cost = %f ",
|
||||
println(hlog, hr::format("it %12lld temp %6.4f [1/e at %13.6f] cost = %f ",
|
||||
numiter, double(sag::temperature), (double) exp(sag::temperature),
|
||||
double(sag::cost)));
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ namespace sag {
|
|||
auto t2 = SDL_GetTicks();
|
||||
if(t2 - t1 > 1000) {
|
||||
t1 = t2;
|
||||
println(hlog, hr::format("it %12Ld temp %6.4f [1/e at %13.6f] cost = %f ",
|
||||
println(hlog, hr::format("it %12lld temp %6.4f [1/e at %13.6f] cost = %f ",
|
||||
numiter, double(sag::temperature), (double) exp(sag::temperature),
|
||||
double(sag::cost)));
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ namespace sag {
|
|||
if(t < (sag_ittime+1) / 2) ipturn *= 2;
|
||||
else if(t > sag_ittime * 2) ipturn /= 2;
|
||||
else ipturn = ipturn * sag_ittime / t;
|
||||
print(hlog, hr::format("it %12Ld temp %6.4f [2:%8.6f,10:%8.6f,50:%8.6f] cost = %f\n",
|
||||
print(hlog, hr::format("it %12lld temp %6.4f [2:%8.6f,10:%8.6f,50:%8.6f] cost = %f\n",
|
||||
numiter, double(sag::temperature),
|
||||
(double) exp(-2 * exp(-sag::temperature)),
|
||||
(double) exp(-10 * exp(-sag::temperature)),
|
||||
|
@ -734,7 +734,7 @@ namespace sag {
|
|||
|
||||
hyperpoint np = rgpushxto0(placement[i]) * h;
|
||||
|
||||
ld change;
|
||||
ld change = 0;
|
||||
for(auto e: edges_yes[i]) change -= lgemb.lyes(pdist(placement[i], placement[e]));
|
||||
for(auto e: edges_no[i]) change -= lgemb.lno(pdist(placement[i], placement[e]));
|
||||
for(auto e: edges_yes[i]) change += lgemb.lyes(pdist(np, placement[e]));
|
||||
|
@ -1097,7 +1097,7 @@ namespace sag {
|
|||
create_viz();
|
||||
|
||||
for(int i=0; i<DN; i++) {
|
||||
color_t col = patterns::compute_cell_color(sagcells[sagid[i]]);
|
||||
color_t col = ccolor::formula.f(sagcells[sagid[i]], ccolor::formula);
|
||||
col <<= 8;
|
||||
col |= 0xFF;
|
||||
vdata[i].cp.color1 = vdata[i].cp.color2 = col;
|
||||
|
|
|
@ -314,6 +314,12 @@ auto hchook = addHook(hooks_drawcell, 100, draw_snow)
|
|||
param_b(snow_not_player, "snow_not_player");
|
||||
})
|
||||
|
||||
#if CAP_SOLV
|
||||
#define IF_SOLV(x) x
|
||||
#else
|
||||
#define IF_SOLV(x)
|
||||
#endif
|
||||
|
||||
#if CAP_RVSLIDES
|
||||
+ addHook_rvslides(161, [] (string s, vector<tour::slide>& v) {
|
||||
if(s != "noniso") return;
|
||||
|
@ -381,16 +387,16 @@ auto hchook = addHook(hooks_drawcell, 100, draw_snow)
|
|||
set_geometry(gRotSpace);
|
||||
snow_lambda = 5;
|
||||
});
|
||||
#if CAP_SOLV
|
||||
snow_slide(v, "Solv", "Solv geometry. Like the non-isotropic hyperbolic geometry but where the horizontal and vertical curvatures work in the other way.", [] {
|
||||
IF_SOLV(snow_slide(v, "Solv", "Solv geometry. Like the non-isotropic hyperbolic geometry but where the horizontal and vertical curvatures work in the other way.", [] {
|
||||
set_geometry(gSol);
|
||||
// tour::slide_backup(snow_shape, 2);
|
||||
snow_lambda = 3;
|
||||
});
|
||||
#endif
|
||||
});)
|
||||
})
|
||||
#endif
|
||||
+ 0;
|
||||
|
||||
#undef IF_SOLV
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ ld evaluate_measure(manidata& emb, manidata& orig, vector<int>& mapp, vector<pai
|
|||
|
||||
}
|
||||
|
||||
static constexpr string som_test_dir = "results/";
|
||||
static const string som_test_dir = "results/";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2596,12 +2596,19 @@ EX void show() {
|
|||
dialog::addBoolItem(XLAT("in tes internal format"), arb::in(), 't');
|
||||
dialog::add_action([] {
|
||||
if(!arb::in()) {
|
||||
try {
|
||||
arb::convert::convert();
|
||||
arb::convert::activate();
|
||||
start_game();
|
||||
rule_status = XLAT("converted successfully -- %1 cell types", its(isize(arb::current.shapes)));
|
||||
rules_known_for = "unknown";
|
||||
}
|
||||
catch(hr_parse_exception& ex) {
|
||||
println(hlog, "failed: ", ex.s);
|
||||
rule_status = XLAT("failed to convert: ") + ex.s;
|
||||
rules_known_for = "unknown";
|
||||
}
|
||||
}
|
||||
else if(arb::convert::in()) {
|
||||
stop_game();
|
||||
geometry = arb::convert::base_geometry;
|
||||
|
|
|
@ -108,7 +108,11 @@ string displayfor(int scoredisplay, score* S, bool shorten = false) {
|
|||
return buf;
|
||||
}
|
||||
if(scoredisplay == POSSCORE) return modedesc(S);
|
||||
if(scoredisplay == 68) return S->yasc_message + XLAT(" in %the1", eLand(S->box[68]));
|
||||
if(scoredisplay == 68) {
|
||||
eLand which = eLand(S->box[68]);
|
||||
if(which >= landtypes || which < 0) return "fail";
|
||||
return S->yasc_message + XLAT(" in %the1", which);
|
||||
}
|
||||
if(scoredisplay == 1) {
|
||||
time_t tim = S->box[1];
|
||||
char buf[128]; strftime(buf, 128, "%c", localtime(&tim));
|
||||
|
|
|
@ -245,12 +245,12 @@ auto ah = addHook(hooks_args, 0, read_args);
|
|||
#endif
|
||||
auto ah2 = addHook(hooks_configfile, 100, [] {
|
||||
#if CAP_CONFIG
|
||||
addsaver(shot::shotx, "shotx");
|
||||
addsaver(shot::shoty, "shoty");
|
||||
addsaverenum(shot::format, "shotsvg");
|
||||
addsaver(shot::transparent, "shottransparent");
|
||||
param_i(shot::shotx, "shotx");
|
||||
param_i(shot::shoty, "shoty");
|
||||
param_enum(shot::format, "shotsvg", shot::png);
|
||||
param_b(shot::transparent, "shottransparent");
|
||||
param_f(shot::gamma, "shotgamma");
|
||||
addsaver(shot::caption, "shotcaption");
|
||||
param_str(shot::caption, "shotcaption");
|
||||
param_f(shot::fade, "shotfade");
|
||||
#endif
|
||||
});
|
||||
|
@ -1181,27 +1181,27 @@ EX void moved() {
|
|||
|
||||
#if HDR
|
||||
struct animated_parameter {
|
||||
setting *par;
|
||||
parameter *par;
|
||||
string formula;
|
||||
};
|
||||
#endif
|
||||
|
||||
EX vector<animated_parameter> aps;
|
||||
|
||||
EX setting *find_param(void *x) {
|
||||
EX parameter *find_param(void *x) {
|
||||
for(auto& fs: params)
|
||||
if(fs.second->affects(x))
|
||||
return &*fs.second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EX void deanimate(setting *p) {
|
||||
EX void deanimate(parameter *p) {
|
||||
for(int i=0; i<isize(aps); i++)
|
||||
if(aps[i].par == p)
|
||||
aps.erase(aps.begin() + (i--));
|
||||
}
|
||||
|
||||
EX void get_parameter_animation(setting *p, string &s) {
|
||||
EX void get_parameter_animation(parameter *p, string &s) {
|
||||
for(auto &ap: aps)
|
||||
if(ap.par == p && ap.par->anim_unchanged())
|
||||
s = ap.formula;
|
||||
|
@ -1214,7 +1214,7 @@ EX void animate_parameter(ld &x, string f) {
|
|||
aps.emplace_back(animated_parameter{par, f});
|
||||
}
|
||||
|
||||
EX void animate_setting(setting *par, string f) {
|
||||
EX void animate_parameter(parameter *par, string f) {
|
||||
if(!par) { println(hlog, "parameter not animatable"); return; }
|
||||
deanimate(par);
|
||||
aps.emplace_back(animated_parameter{par, f});
|
||||
|
@ -1368,6 +1368,7 @@ EX void apply() {
|
|||
#endif
|
||||
|
||||
apply_animated_parameters();
|
||||
last_anim_vars = anim_vars;
|
||||
calcparam();
|
||||
}
|
||||
|
||||
|
@ -1514,7 +1515,7 @@ void animator(string caption, ld& param, char key) {
|
|||
});
|
||||
}
|
||||
|
||||
EX ld a, b;
|
||||
EX array<ld, 10> anim_vars, last_anim_vars;
|
||||
|
||||
ld animation_period;
|
||||
|
||||
|
@ -1670,14 +1671,14 @@ EX void show() {
|
|||
}
|
||||
#endif
|
||||
|
||||
dialog::addSelItem(XLAT("animate parameters"), fts(a), 'a');
|
||||
dialog::addSelItem(XLAT("animate parameters"), fts(anim_vars[0]), 'a');
|
||||
dialog::add_action([] () {
|
||||
dialog::editNumber(a, -100, 100, 1, 0, XLAT("animate parameters"), "");
|
||||
dialog::editNumber(anim_vars[0], -100, 100, 1, 0, XLAT("animate parameters"), "");
|
||||
});
|
||||
|
||||
dialog::addSelItem(XLAT("animate parameters"), fts(b), 'b');
|
||||
dialog::addSelItem(XLAT("animate parameters"), fts(anim_vars[1]), 'b');
|
||||
dialog::add_action([] () {
|
||||
dialog::editNumber(b, -100, 100, 1, 0, XLAT("animate parameters"), "");
|
||||
dialog::editNumber(anim_vars[1], -100, 100, 1, 0, XLAT("animate parameters"), "");
|
||||
});
|
||||
|
||||
dialog::addBoolItem(XLAT("history mode"), (history::on || history::includeHistory), 'h');
|
||||
|
@ -1759,15 +1760,15 @@ auto animhook = addHook(hooks_frame, 100, display_animation)
|
|||
#endif
|
||||
+ addHook(hooks_configfile, 100, [] {
|
||||
#if CAP_CONFIG
|
||||
param_f(anims::period, "aperiod", "animation period");
|
||||
addsaver(anims::noframes, "animation frames");
|
||||
param_f(anims::cycle_length, "acycle", "animation cycle length");
|
||||
param_f(anims::parabolic_length, "aparabolic", "animation parabolic length")
|
||||
param_f(anims::period, parameter_names("aperiod", "animation period"));
|
||||
param_i(anims::noframes, "animation frames");
|
||||
param_f(anims::cycle_length, parameter_names("acycle", "animation cycle length"));
|
||||
param_f(anims::parabolic_length, parameter_names("aparabolic", "animation parabolic length"))
|
||||
->editable(0, 10, 1, "cells to go", "", 'c');
|
||||
param_matrix(anims::rug_angle, "arugangle", 3)
|
||||
->editable("animation rug angle", "", 'C');
|
||||
param_f(anims::circle_radius, "acradius", "animation circle radius");
|
||||
param_f(anims::circle_spins, "acspins", "animation circle spins");
|
||||
param_f(anims::circle_radius, parameter_names("acradius", "animation circle radius"));
|
||||
param_f(anims::circle_spins, parameter_names("acspins", "animation circle spins"));
|
||||
param_matrix(anims::rug_movement_angle, "rug forward movement angle", 3)
|
||||
->editable("rug forward movement angle", "", 'b');
|
||||
param_matrix(anims::movement_angle.v2, "movement_angle", 2)->editable("movement angle", "", 'm');
|
||||
|
@ -1781,12 +1782,14 @@ auto animhook = addHook(hooks_frame, 100, display_animation)
|
|||
param_b(wallopt, "wallopt");
|
||||
param_b(clearup, "anim_clearup");
|
||||
param_color(circle_display_color, "circle_display_color", true);
|
||||
param_enum(anims::ma, "ma", "movement_animation", maNone)
|
||||
param_enum(anims::ma, parameter_names("ma", "movement_animation"), maNone)
|
||||
-> editable({{"none", ""}, {"translation", ""}, {"rotation", ""}, {"circle", ""}, {"parabolic", ""}, {"translation+rotation", ""}}, "movement animation", 'a')
|
||||
-> set_reaction(ma_reaction);
|
||||
|
||||
param_f(anims::a, "a", 0);
|
||||
param_f(anims::b, "b", 0);
|
||||
param_f(anims::anim_vars[0], "a", 0);
|
||||
param_f(anims::anim_vars[1], "b", 0);
|
||||
param_f(anims::anim_vars[2], "c", 0);
|
||||
param_f(anims::anim_vars[3], "d", 0);
|
||||
#endif
|
||||
});
|
||||
|
||||
|
|
|
@ -2590,7 +2590,7 @@ EX void turn(int delta) {
|
|||
lmousetarget = mousetarget;
|
||||
|
||||
if(!shmup::on) return;
|
||||
if(!(cmode & sm::NORMAL)) {
|
||||
if(!(cmode & sm::NORMAL) || outoffocus) {
|
||||
#if CAP_RACING
|
||||
if(!in_pause) {
|
||||
in_pause = true;
|
||||
|
|
|
@ -178,6 +178,7 @@ struct hrmap_spherical : hrmap_standard {
|
|||
}
|
||||
|
||||
transmatrix relative_matrixc(cell *c2, cell *c1, const hyperpoint& hint) override {
|
||||
if(IRREGULAR) return relative_matrix_via_masters(c2, c1, hint);
|
||||
transmatrix T = iso_inverse(get_where(c1)) * get_where(c2);
|
||||
if(elliptic) fixelliptic(T);
|
||||
return T;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue