73 Commits
Author SHA1 Message Date
Marco Antonio J. Costaandmajcosta 3d3e1bbfc6 refactor Translate()
it returns true but no consumers use it. its return type is void, then
2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 738225d2a2 move ImportStrings to i18n 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 4be9b106f4 give more local functions internal linkage 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta af4eeb09f4 make local-only functions static 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 15821498a3 text declarations go into text.h 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 54bdce6c46 cleanup: dead code removal 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 433de0e67b use exhaustive switch instead of if statements 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 30e5d8f91c i18n: we already have one Language enum, no need for two 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 506ea842b8 i18n: pull some TUs that do not belong in Utils 2026-07-21 18:39:50 -03:00
Marco Antonio J. Costaandmajcosta 9adc1ad998 node20 is deprecated, clear the warnings
bump action versions and change the MSVC action to a composite one that doesn't use node at all

also remove msbuild which we don't need
2026-07-21 14:45:04 -03:00
Marco Antonio J. Costaandmajcosta 8d1877d26d read language from Language.ini file
to avoid having to ship a whole ja2.ini for languages that
currently don't

command-line /language:german still works, but INI file is
prioritized

format:

```
[Language]
LANGUAGE = ITALIAN
```
2026-07-21 14:42:52 -03:00
Marco Antonio J. Costaandmajcosta d03989051a remove Languages from CI
no need anymore
2026-07-21 11:23:08 -03:00
Marco Antonio J. Costaandmajcosta 5da2ee8bf6 better initialization of language defaults 2026-07-21 09:46:41 -03:00
Marco Antonio J. Costaandmajcosta aa0aac2bfe remove unused includes 2026-07-21 09:46:41 -03:00
ee098125e6 Strip dead per-language .slf entries from gGameLibaries
InitializeFileDatabase, the only reader of gGameLibaries[], is called
nowhere in the tree — VFS replaced this legacy loader. Delete the
7 #ifdef GERMAN/POLISH/DUTCH/ITALIAN/RUSSIAN/FRENCH/CHINESE entries
outright rather than runtime-selecting them.

NPC.h: two commented-out #if defined(CRIPPLED_VERSION)||defined(RUSSIAN)
triplets. AimMembers.cpp: two commented-out #ifdef POLISH character-remap
switch blocks. All already-dead. Verify grep for language macros outside
i18n/ now returns only unrelated hits (filename literal, dev-tool CLI flag,
stray comment, historical prose) — no #ifdef guards left.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 09:46:41 -03:00
Marco Antonio J. Costaandmajcosta bada3ef31a cleanup: remove last remnants of language preprocessor definitions
good riddance
2026-07-21 09:46:41 -03:00
Marco Antonio J. Costaandmajcosta 00a805cc39 remove lying, outdated or superfluous comments
no more guards, no more cpp files included
2026-07-21 09:46:41 -03:00
fd2c74727e Make LANGUAGE switchable in runtime (#653)
squashed into a single commit because doing it in steps that all
compiled involved a lot of boilerplate that is pointless to commit to
the repository. GH still has the PR for reference.

g_lang, MAX_MESSAGES_ON_MAP_BOTTOM, and GetLanguagePrefix() were
compile-time constants selected by the ENGLISH/GERMAN/... build
define. They're now runtime, defaulting to the same per-exe value the
define used to pick, and overridable at startup from [Ja2 Settings]
LANGUAGE in Ja2.ini.

-

XMLTacticalMessages is filled at runtime from NewTacticalMessages.xml,
never from compiled-in per-language data: all 8 per-language definitions
were the identical all-zero { L"" }. Delete them and define one shared
buffer in Utils/XML_Language.cpp (the loader) instead of pointer-rebinding
it like the static tables — this drops 9 dead 800KB zero-buffers (8
namespaced copies in LanguageStrings.cpp plus the standalone one) and
leaves no bind-ordering hazard for the XML load path.

-

ExportStrings.cpp privately recompiled one language's full text table
by #including the raw _<LANG>Text.cpp inside namespace Loc, keyed off
the exe-level ENGLISH/GERMAN/... compile macro (whichever the build
happened to select). That's redundant with the pointer globals every
other subsystem already uses (Text.h / LanguageStrings.cpp).

Drop the private copy; the unqualified table names in Loc::ExportStrings
now resolve to the global pointer externs, which BindLanguageStrings has
already rebound to the runtime g_lang by the time this runs (EXPORT_STRINGS
ini flag, checked after GetRuntimeSettings in sgp.cpp). gs_Lang (used only
by Loc::Translate for the Polish/Russian byte remap on raw .edt exports) is
now derived from g_lang via ToLocLanguage, so the export always matches
whatever language is actually active instead of a compile-time pick.

-

Editor/popupmenu.cpp and Strategic/Scheduling.cpp kept their own
call-site extern of gszScheduleActions as CHAR16[NUM_SCHEDULE_ACTIONS][20]
after the real definition changed into a rebindable pointer
(CHAR16 (*)[20], LanguageStrings.cpp). MSVC decays the outer array
dimension when mangling globals, so both declarations produce the same
symbol (?gszScheduleActions@@3PAY0BE@_WA) and the mismatch linked
silently -- but the array-typed TUs then indexed the 4-byte pointer
slot itself as string data, so the editor schedule popup and the map
schedule message text read garbage.

-

add text.def to be single-source of truth on symbol names and use it
 .much simpler, less error prone if adding more strings

-

add pseudo interface for language state. MAX_SAGES_ON_BOTTOM must always
 change in lockstep with g_lang. this isn't foolproof but better

---------

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-07-21 05:33:03 -03:00
steph-pgandAsdow ba64ed53c6 Items can now be taken from non colapsed POWs 2026-07-02 19:16:55 +03:00
Asdow c61f57bd9b Whitespace adjustment 2026-06-22 00:21:31 +03:00
Asdow 4d5593ebcb Fix render misalignment at 960x540 resolution
Should also work for any custom resolution that suffers from the same issue
2026-06-22 00:21:31 +03:00
Asdow 601fabf401 Fix tile rendering misalignment at 1440x900 and 1600x900 resolutions
Shamelessly stolen from Stracciatella code
2026-06-22 00:21:31 +03:00
steph-pgandAsdow eb8ecb31f0 fix POWs in LOS keeps you in turnbased mode 2026-06-20 20:03:16 +03:00
Asdow 2801af552e Set moved item old entry to not existing 2026-06-20 17:11:37 +03:00
Asdow ef30192b29 Leave merc equipment to current sector in UB 2026-06-20 08:49:56 +03:00
Asdow 392ba66df3 Enable dismissing mercs in UB before game start
Jerry Melo complains about too many mercs if player has hired over 6 mercs and refuses to fly. This allows player to dismiss mercs until the pilot is happy.
2026-06-20 08:49:56 +03:00
Asdow d4dd5f07df Disable contract renewal in UB 2026-06-20 08:49:56 +03:00
db29feed11 Don't strip robot's installed components on mapscreen drop-all
The mapscreen "drop everything" hotkey (Shift+W) looped over every
inventory slot from HELMETPOS to NUM_INV_SLOTS and dumped each one.
Madlab's robot stores its installed gear in those same slots - ammo (14),
targeting (15), chassis/armour (16) and utility (17). Dropping these left
the robot defenceless, and the player cannot re-install the components
through normal inventory, so the loss was permanent.

Skip the robot's component slots in the drop loop; only its general cargo
slot (ROBOT_INVENTORY_SLOT) may still be emptied. Regular mercs are
unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 23:06:33 +03:00
Asdow 1fc5f939bf Use new RandomGridNoUnloadedSector() for autoresolve
* Load required mapinfo for checking suitable gridnos
* Modify SOLDIERTYPE::DropSectorEquipment( ) to take an external gridno when placing items into an unloaded sector
2026-06-15 22:01:07 +03:00
Asdow 9e0105caec Add function for choosing random gridno in an unloaded sector 2026-06-15 22:01:07 +03:00
Asdow 0cc7fb4e39 Add function for loading world height data 2026-06-15 22:01:07 +03:00
Asdow db15679ec1 Add missing Iter->Exists() checks 2026-06-12 15:52:24 +03:00
Asdow 6a8a22aba2 Move iter->exists() check to first 2026-06-12 15:52:24 +03:00
Asdow 9b654ff3f1 Fix typo 2026-06-12 15:51:03 +03:00
Asdow a67f4b8a8f Formatting 2026-06-12 15:51:03 +03:00
Asdow 673dea01af Use correct sector for Chitzena 2026-06-12 15:51:03 +03:00
Marco Antonio J. Costaandmajcosta b44b6cebb8 Revert PR544
"Corpses are not properly shown even if within mercs' vision due to the check only
running intermittently since we're not constantly running the reveal roofs and items
function. In addition, mercs such as Raven who have the quoteexpheadshotonly set to true,
will NEVER reveal any corpses"

Revert "Remove extra line"

This reverts commit 1e1eb88864.

Revert "Move visibility check after already included pCorpse check"

This reverts commit 72e586a378.

Revert "Make 3rd party corpses invisible till they in fov"

This reverts commit 07dbf9c848.
2026-06-02 19:17:31 -03:00
Asdow 8bc3dbd0aa Prevent RebelCommand::DailyUpdate() from running twice when loading autosave 2026-06-02 23:59:30 +03:00
Marco Antonio J. Costaandmajcosta b4176bb2d9 Fix/drag unconscious softlock
Same logic but cleaned up version of https://github.com/1dot13/source/pull/602 which Tais contributed with Claude Code's help

Most calls to SOLDIERTYPE::IsDragging() aren't supposed to have a side effect of cancelling a drag, being simple queries.
Changing the default to reflect that is right move.

Assisted-by: Claude:
2026-06-01 21:45:55 -03:00
Asdow 8b3e417872 Guard against illegal array access
Hovering mouse over an option long enough that the popup text appears and scrolling to last page with mouse wheel would run into assertion error in gprintfdirty()  Assert(pFontString!=NULL); if the option was one of the last ones that didn't have a text box in the last option page.
2026-05-28 17:44:21 +03:00
AsdowandClaude Opus 4.7 b949189881 Fix palette resolution
The LayerProp palette lookup was gated on the *filter* attribute instead
of the *palette* attribute -- the filter checks from the line above were
copy-pasted verbatim. As a result, any LayerProp with an empty filter but
a real palette never resolved its palette table: paletteTable stayed NULL
and the layer fell back to the merc's shade table.

The most visible victim is the heli fast-rope arrival layer
(filter="" palette="hats"): rendered with the merc palette, the rope's
pixel indices (45-81, 166-172) hit the merc's unreplaced orange/red glow
ramp instead of the rope's own tan/green, painting orange specks along the
rope. Testing the palette attribute restores the intended "hats" palette
and the correct rope colours; it also fixes any other empty-filter layers.

Co-Authored-By: Claude Opus 4.7
2026-05-28 16:33:48 +03:00
JuqiandAsdow cc19490898 update Chinese translations 2026-05-25 08:37:30 +03:00
GreysaandAsdow 9fac0a8ecd Tidy up code 2026-05-23 21:22:28 +03:00
GreysaandAsdow 346e5c6293 fix for issue #580 2026-05-23 21:22:28 +03:00
GreysaandAsdow 0bea84374e fixed some screenmsg strings not changed 2026-05-23 21:22:28 +03:00
GreysaandAsdow 3d589bd78e A little code cleanup and moved debug reload to shift + alt + r 2026-05-23 21:22:28 +03:00
GreysaandAsdow e1c8bee1d1 Message strings added to language files. 2026-05-23 21:22:28 +03:00
GreysaandAsdow ead2932316 Added dual wielding unjamming, tidied up reload and unjam code a little 2026-05-23 21:22:28 +03:00
GreysaandAsdow bb55299ff6 Basic implementaion of unjamming on reload hotkey.
TODO:
text strings
check dual wielding
2026-05-23 21:22:28 +03:00
JuqiandAsdow 2d4f62a5b6 Correct two errors in the Chinese translation 2026-05-13 16:02:28 +03:00
Asdow 03a7b017b6 Change mouse cursor if attachment attempt fails 2026-05-06 23:23:07 +03:00
Asdow edf8f2f086 Fix crash when failing an attachment via item desc popup callback 2026-05-06 23:23:07 +03:00
Asdow 78ed49c73d Remove corpse structure from world when removing corpse
Fixes not being able to take all corpses from one tile, if multiple corpses were stacked on top of each other. With the structure not deleted, the  GetCorpseAtGridNo would not find an existing corpse anymore.
2026-05-06 11:28:11 +03:00
Asdow 5697acabb3 Take most recent corpse from tile
Fixes crash when taking a corpse on roof when multiple corpses are stacked on one tile.
2026-05-06 11:28:11 +03:00
Asdow 09197e421c Add a function for finding last matching structure 2026-05-06 11:28:11 +03:00
JuqiandAsdow 46afd90fdc Add Chinese translation 2026-05-04 12:10:10 +03:00
JuqiandAsdow 80ba0a05d7 Revert "Add Chinese translation"
This reverts commit e7d436d9fa.
2026-05-04 12:10:10 +03:00
JuqiandAsdow aab34bff20 Add Chinese translation 2026-05-04 12:10:10 +03:00
JuqiandAsdow ef325c1cde (Chinese) Add support for line breaks in ITEMS.XML
Added detection of the NEWLINE_CHAR character "±" to enable line breaks not only when text exceeds display width, but also upon encountering NEWLINE_CHAR.
Note: This character has been conventionally adopted in the Chinese community as a line break marker within XML item descriptions. The modification affects Chinese text display only.
2026-05-02 09:39:03 +03:00
Asdow 99a4ff1527 Guard against invalid value 2026-05-02 09:31:09 +03:00
Marco Antonio J. Costaandmajcosta f2d1b09fc6 add comment to CMakeLists.txt
save people a trip to learn.microsoft.com
2026-04-08 15:25:48 -03:00
Marco Antonio J. CostaandAsdow 31970291bd make preprocessor definitions consistent in every single lib
SGP did not seem to make any use of compilationFlags or debugFlags when
translating from msbuild to cmake, but there could be a thrice removed
transitive include I've missed.

there's a small probability this fixes some obscure UB or one-definition rule
violation that's causing the mystery crashes people have reported
2026-04-08 21:06:34 +03:00
GreysaandGitHub 0a758179c2 Advanced repairs skill check (#581)
* Add technician level skill check for advanced repair

* changed readability
2026-03-17 10:35:29 +01:00
noooooo4499andAsdow 481e95d42d Avoid breaking compatibility with gamedirs with old HourlyUpdate scripts
They are mapped to the right variable now
2026-02-25 10:47:47 +02:00
Asdow 8f178a59ab Add filename to error text for pngloader 2026-02-23 18:23:08 +02:00
Asdow a6d96f5f31 Remove compiler warnings 2026-02-21 21:00:38 +02:00
Asdow 67f41d4de6 Remove superfluous variable 2026-02-21 21:00:38 +02:00
Asdow 1d53b92731 Add const keyword 2026-02-21 21:00:38 +02:00
Asdow 42b2cbc7f5 add const keyword 2026-02-21 21:00:38 +02:00
Asdow 04ace5df24 add const keyword 2026-02-21 21:00:38 +02:00
Asdow 323944757d Improve DisplayCover() performance
* Replaced gCoverViewArea[2000][2000][2] with std::vector that is adjusted to the actual viewport size. Size difference for example in 720p resolution is 8 000 000 vs 3969 elements
* FPS improved in merc view mode 6-8 frames and in enemy view mode 10-20 frames
2026-02-21 21:00:38 +02:00
noooooo4499andAsdow 7d5a1c2e9e Remove useless lua gameclock variables, add lua externalized function to heal boxers
- These gameclock variables were not updated properly so it created a discrepancy between it and the proper gameclock variables, and it was causing issues with the lua hourly update script

- Function that heals boxers after they finish resting
2026-02-12 10:24:47 +02:00
noooooo4499andAsdow dc107f5044 Fix Darren sometimes never giving fights if the boxers's IDs aren't assigned 2026-02-07 12:03:03 +02:00
112 changed files with 3546 additions and 3246 deletions
+166 -27
View File
@@ -9,11 +9,6 @@ on:
# allows to manually trigger a build
workflow_dispatch:
inputs:
build_all_languages:
description: build all languages
required: false
default: false
type: boolean
assemble_release:
description: create release
required: false
@@ -27,7 +22,6 @@ jobs:
workflow_setup:
runs-on: ubuntu-latest
outputs:
languages_json_array: ${{ steps.global_vars.outputs.languages_json_array }}
assemble_release: ${{ steps.global_vars.outputs.assemble_release }}
steps:
- id: global_vars
@@ -37,15 +31,6 @@ jobs:
full_release='${{ ( github.repository == '1dot13/source' && github.ref_name == 'master' ) || startsWith(github.ref, 'refs/tags/v') }}'
if [[ '${{ inputs.build_all_languages }}' == 'true' || ( '${{ inputs.build_all_languages }}' == '' && "$full_release" == 'true' ) ]]
then
languages_json_array='["Chinese", "German", "English", "French", "Polish", "Italian", "Dutch", "Russian"]';
else
# English + some other language for compilation testing
languages_json_array='["German", "English"]'
fi
echo "languages_json_array=$languages_json_array" >> $GITHUB_OUTPUT
if [[ '${{ inputs.assemble_release }}' == 'true' || ( '${{ inputs.assemble_release }}' == '' && "$full_release" == 'true' ) ]]
then
assemble_release='true'
@@ -154,39 +139,193 @@ jobs:
cat dist/versions.env
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: versions.env
path: dist/
build:
# every executable contains all languages and picks one at runtime, so one build serves every package
compile:
needs: [ workflow_setup ]
runs-on: windows-latest # required for the MSVC toolchain
strategy:
fail-fast: false
matrix:
language: ${{ fromJson(needs.workflow_setup.outputs.languages_json_array) }}
uses: ./.github/workflows/build_language.yml
with:
language: ${{ matrix.language }}
assemble: ${{ needs.workflow_setup.outputs.assemble_release == 'true' }}
# at least English and some other lang have to work
continue-on-error: ${{ matrix.language != 'English' && matrix.language != 'German' }}
application: [ja2, ja2mapeditor, ja2ub, ja2ubmapeditor]
steps:
- name: Checkout source
uses: actions/checkout@v7
- name: Download versions.env
uses: actions/download-artifact@v8
with:
name: versions.env
path: artifacts
- name: Restore versions.env
shell: bash
run: cat artifacts/versions.env >> $GITHUB_ENV
# TODO: Move this into CMake, just taking the GitHub Actions parameters as -D variables
- name: Update GameVersion.cpp
shell: bash
run: |
set -eux
GAME_VERSION=$(echo "$GAME_VERSION" | tr -cd '[:print:]' | tr -d '"\\')
GAME_BUILD=$(echo "$GAME_BUILD_INFORMATION" | tr -cd '[:print:]' | tr -d '"\\')
sed -i "s|@Version@|${GAME_VERSION:0:15}|" Ja2/GameVersion.cpp
sed -i "s|@Build@|${GAME_BUILD:0:255}|" Ja2/GameVersion.cpp
cat Ja2/GameVersion.cpp
- name: Prepare build properties
shell: bash
run: |
set -eux
touch CMakePresets.json
JA2Application=$(echo '${{ matrix.application }}' | tr '[:lower:]' '[:upper:]')
echo "
JA2Application=$JA2Application
" >> $GITHUB_ENV
- uses: egor-tensin/vs-shell@v2
with:
arch: x86
- name: Prepare build
run: |
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DApplications="$Env:JA2Application"
- name: Build
run: |
cmake --build build/ -- -v
- name: List build artifacts
shell: bash
run: |
find build/
- name: Upload
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.application }}
path: build/*.exe
# only the game data differs per language, every package gets the same executables
assemble:
needs: [ workflow_setup, compile ]
if: needs.workflow_setup.outputs.assemble_release == 'true'
runs-on: windows-latest # required for case-insensitive filesystem handling
# at least English has to work
continue-on-error: ${{ matrix.language != 'English' }}
strategy:
fail-fast: false
matrix:
language: [Chinese, German, English, French, Polish, Italian, Dutch, Russian]
steps:
- name: Download versions.env
uses: actions/download-artifact@v8
with:
name: versions.env
path: artifacts
- name: Restore versions.env
shell: bash
run: cat artifacts/versions.env >> $GITHUB_ENV
- name: Checkout gamedir
uses: actions/checkout@v7
with:
repository: ${{ env.GAMEDIR_REPOSITORY }}
ref: ${{ env.GAMEDIR_COMMIT_SHA }}
path: gamedir
- name: Checkout gamedir-languages
if: matrix.language != 'English'
uses: actions/checkout@v7
with:
repository: ${{ env.GAMEDIR_LANGUAGES_REPOSITORY }}
ref: ${{ env.GAMEDIR_LANGUAGES_COMMIT_SHA }}
path: gamedir-languages
- name: Copy gamedir-languages files to gamedir
if: matrix.language != 'English'
shell: bash
run: |
set -eux
cp -a gamedir-languages/${{ matrix.language }}_Version/* gamedir/
- name: Download applications
uses: actions/download-artifact@v8
with:
pattern: ja2*
path: artifacts
- name: Copy application files to gamedir
shell: bash
run: |
set -eux
for APP in ja2 ja2mapeditor ja2ub ja2ubmapeditor
do
mv artifacts/${APP}/*.exe gamedir/${APP}.exe
done
- name: Create version information file
shell: bash
run: |
set -eux
# "-" separates words, "_" combines words, see double-click behavior
DIST_PREFIX='JA2_113'
DIST_NAME="${DIST_PREFIX}-${GAME_VERSION}-G${GAMEDIR_COMMIT_SHA:0:4}L${GAMEDIR_LANGUAGES_COMMIT_SHA:0:4}-${{ matrix.language }}"
echo "DIST_NAME=$DIST_NAME" >> $GITHUB_ENV
echo "If you encounter problems during gameplay, please provide the following version information:
Distribution Name: $DIST_NAME
Game Version: $GAME_VERSION
Language: ${{ matrix.language }}
Build Information: $GAME_BUILD_INFORMATION
Source Repository: $GITHUB_REPOSITORY
Source Commit SHA: $GITHUB_SHA
Source Commit Date: $SOURCE_COMMIT_DATETIME
Gamedir Repository: $GAMEDIR_REPOSITORY
Gamedir Commit SHA: $GAMEDIR_COMMIT_SHA
Gamedir Commit Date: $GAMEDIR_COMMIT_DATETIME
Gamedir Languages Repository: $GAMEDIR_LANGUAGES_REPOSITORY
Gamedir Languages Commit SHA: $GAMEDIR_LANGUAGES_COMMIT_SHA
Gamedir Languages Commit Date: $GAMEDIR_LANGUAGES_COMMIT_DATETIME
" > "gamedir/${DIST_PREFIX}-Version.txt"
cat "gamedir/${DIST_PREFIX}-Version.txt"
- name: Create release archive
shell: bash
run: |
set -eux
mkdir dist/
cd gamedir/
7z a -bb -xr'!.*' "../dist/${DIST_NAME}.7z" .
- name: Upload
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.language }}_release
path: dist/
compression-level: 0
release:
needs: [ workflow_setup, build ]
needs: [ workflow_setup, assemble ]
if: needs.workflow_setup.outputs.assemble_release == 'true'
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: dist
pattern: '*_release'
merge-multiple: true
- name: Checkout Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
path: source
fetch-depth: 1
-206
View File
@@ -1,206 +0,0 @@
name: build language
on:
workflow_call:
inputs:
language:
description: 'any of Chinese German English French Polish Italian Dutch Russian'
required: true
default: 'English'
type: string
assemble:
description: 'assemble full package'
required: true
default: true
type: boolean
continue-on-error:
description: 'allows a language to fail, used when building all languages'
required: false
default: false
type: boolean
jobs:
compile:
runs-on: windows-latest # required for msbuild
continue-on-error: ${{ inputs.continue-on-error }}
strategy:
fail-fast: false
matrix:
application: [ja2, ja2mapeditor, ja2ub, ja2ubmapeditor]
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Download versions.env
uses: actions/download-artifact@v4
with:
name: versions.env
path: artifacts
- name: Restore versions.env
shell: bash
run: cat artifacts/versions.env >> $GITHUB_ENV
# TODO: Move this into CMake, just taking the GitHub Actions parameters as -D variables
- name: Update GameVersion.cpp
shell: bash
run: |
set -eux
INPUTS_LANGUAGE=${{ inputs.language }}
GAME_VERSION=$(echo "$GAME_VERSION" | tr -cd '[:print:]' | tr -d '"\\')
GAME_BUILD="${INPUTS_LANGUAGE:0:2} $GAME_BUILD_INFORMATION"
GAME_BUILD=$(echo "$GAME_BUILD" | tr -cd '[:print:]' | tr -d '"\\')
sed -i "s|@Version@|${GAME_VERSION:0:15}|" Ja2/GameVersion.cpp
sed -i "s|@Build@|${GAME_BUILD:0:255}|" Ja2/GameVersion.cpp
cat Ja2/GameVersion.cpp
- name: Prepare build properties
shell: bash
run: |
set -eux
touch CMakePresets.json
JA2Language=$(echo '${{ inputs.language }}' | tr '[:lower:]' '[:upper:]')
JA2Application=$(echo '${{ matrix.application }}' | tr '[:lower:]' '[:upper:]')
echo "
JA2Language=$JA2Language
JA2Application=$JA2Application
" >> $GITHUB_ENV
- uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: x86
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x86
- name: Prepare build
run: |
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLanguages="$Env:JA2Language" -DApplications="$Env:JA2Application"
- name: Build
run: |
cmake --build build/ -- -v
- name: List build artifacts
shell: bash
run: |
find build/
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.language }}_${{ matrix.application }}
path: build/*.exe
assemble:
needs: [ compile ]
if: inputs.assemble
runs-on: windows-latest # required for case-insensitive filesystem handling
continue-on-error: ${{ inputs.continue-on-error }}
steps:
- name: Download versions.env
uses: actions/download-artifact@v4
with:
name: versions.env
path: artifacts
- name: Restore versions.env
shell: bash
run: cat artifacts/versions.env >> $GITHUB_ENV
- name: Checkout gamedir
uses: actions/checkout@v4
with:
repository: ${{ env.GAMEDIR_REPOSITORY }}
ref: ${{ env.GAMEDIR_COMMIT_SHA }}
path: gamedir
- name: Checkout gamedir-languages
if: inputs.language != 'English'
uses: actions/checkout@v4
with:
repository: ${{ env.GAMEDIR_LANGUAGES_REPOSITORY }}
ref: ${{ env.GAMEDIR_LANGUAGES_COMMIT_SHA }}
path: gamedir-languages
- name: Copy gamedir-languages files to gamedir
if: inputs.language != 'English'
shell: bash
run: |
set -eux
cp -a gamedir-languages/${{ inputs.language }}_Version/* gamedir/
- name: Download ja2
uses: actions/download-artifact@v4
with:
name: ${{ inputs.language }}_ja2
path: artifacts/ja2
- name: Download ja2mapeditor
uses: actions/download-artifact@v4
with:
name: ${{ inputs.language }}_ja2mapeditor
path: artifacts/ja2mapeditor
- name: Download ja2ub
uses: actions/download-artifact@v4
with:
name: ${{ inputs.language }}_ja2ub
path: artifacts/ja2ub
- name: Download ja2ubmapeditor
uses: actions/download-artifact@v4
with:
name: ${{ inputs.language }}_ja2ubmapeditor
path: artifacts/ja2ubmapeditor
- name: Copy application files to gamedir
shell: bash
run: |
set -eux
for APP in ja2 ja2mapeditor ja2ub ja2ubmapeditor
do
mv artifacts/${APP}/*.exe gamedir/${APP}.exe
done
- name: Create version information file
shell: bash
run: |
set -eux
# "-" separates words, "_" combines words, see double-click behavior
DIST_PREFIX='JA2_113'
DIST_NAME="${DIST_PREFIX}-${GAME_VERSION}-G${GAMEDIR_COMMIT_SHA:0:4}L${GAMEDIR_LANGUAGES_COMMIT_SHA:0:4}-${{ inputs.language }}"
echo "DIST_NAME=$DIST_NAME" >> $GITHUB_ENV
echo "If you encounter problems during gameplay, please provide the following version information:
Distribution Name: $DIST_NAME
Game Version: $GAME_VERSION
Language: ${{ inputs.language }}
Build Information: $GAME_BUILD_INFORMATION
Source Repository: $GITHUB_REPOSITORY
Source Commit SHA: $GITHUB_SHA
Source Commit Date: $SOURCE_COMMIT_DATETIME
Gamedir Repository: $GAMEDIR_REPOSITORY
Gamedir Commit SHA: $GAMEDIR_COMMIT_SHA
Gamedir Commit Date: $GAMEDIR_COMMIT_DATETIME
Gamedir Languages Repository: $GAMEDIR_LANGUAGES_REPOSITORY
Gamedir Languages Commit SHA: $GAMEDIR_LANGUAGES_COMMIT_SHA
Gamedir Languages Commit Date: $GAMEDIR_LANGUAGES_COMMIT_DATETIME
" > "gamedir/${DIST_PREFIX}-Version.txt"
cat "gamedir/${DIST_PREFIX}-Version.txt"
- name: Create release archive
shell: bash
run: |
set -eux
mkdir dist/
cd gamedir/
7z a -bb -xr'!.*' "../dist/${DIST_NAME}.7z" .
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.language }}_release
path: dist/
compression-level: 0
+29 -27
View File
@@ -27,7 +27,11 @@ if(ADDRESS_SANITIZER)
endif()
if(MSVC)
add_compile_options("/wd4838")
# TODO: fix the warnings here and turn them on
# https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-c4000-through-c4199
add_compile_options("/wd4838") # silence implicit narrowing conversion warnings
# add_compile_options("/w14061")
# add_compile_options("/w14062")
endif()
# whether we are using MSBuild as a generator
@@ -102,15 +106,13 @@ foreach(lib IN LISTS Ja2_Libs)
add_subdirectory(${lib})
endforeach()
# language library relies on Application _and_ Language preprocessor definition. very bad.
# language library relies on Application preprocessor definition; compiled once per app
# with all 8 languages built in and selected at runtime (docs/plans/language-design.md).
add_subdirectory(i18n)
# simple function to validate Languages and Application choices
# simple function to validate the Application choice
include(cmake/ValidateOptions.cmake)
set(ValidLanguages CHINESE DUTCH ENGLISH FRENCH GERMAN ITALIAN POLISH RUSSIAN)
ValidateOptions("${ValidLanguages}" "Languages" "${Languages}" "LangTargets")
set(ValidApplications JA2 JA2MAPEDITOR JA2UB JA2UBMAPEDITOR)
ValidateOptions("${ValidApplications}" "Applications" "${Applications}" "ApplicationTargets")
@@ -136,32 +138,32 @@ foreach(app IN LISTS ApplicationTargets)
target_compile_definitions(${game_library} PRIVATE ${compilationFlags} ${debugFlags})
endforeach()
foreach(lang IN LISTS LangTargets)
# executable for an application/language combination, e.g. JA2_ENGLISH.exe
set(exe ${app}_${lang})
add_executable(${exe} WIN32
sgp/sgp.cpp
Ja2/Res/ja2.rc
)
target_link_libraries(${exe} PRIVATE ${Ja2_Libraries} $<IF:${usingMsBuild},legacy_stdio_definitions.lib,>)
target_link_options(${exe} PRIVATE $<IF:${usingMsBuild},/SAFESEH:NO,>)
target_compile_definitions(${exe} PRIVATE ${compilationFlags} ${debugFlags})
# executable for the application, e.g. JA2.exe
set(exe ${app})
add_executable(${exe} WIN32
sgp/sgp.cpp
Ja2/Res/ja2.rc
)
target_link_libraries(${exe} PRIVATE ${Ja2_Libraries} $<IF:${usingMsBuild},legacy_stdio_definitions.lib,>)
target_link_options(${exe} PRIVATE $<IF:${usingMsBuild},/SAFESEH:NO,>)
target_compile_definitions(${exe} PRIVATE ${compilationFlags} ${debugFlags})
# language library for an application, e.g. JA2MAPEDITOR_ENGLISH_i18n
set(language_library ${exe}_i18n)
add_library(${language_library})
target_sources(${language_library} PRIVATE ${i18nSrc})
target_compile_definitions(${language_library} PRIVATE ${compilationFlags} ${debugFlags} ${lang})
target_link_libraries(${exe} PRIVATE ${language_library})
# language library for the application, e.g. JA2MAPEDITOR_i18n — one per app, all 8
# languages compiled in, selected at runtime by BindLanguageStrings
set(language_library ${exe}_i18n)
add_library(${language_library})
target_sources(${language_library} PRIVATE ${i18nSrc})
target_compile_definitions(${language_library} PRIVATE ${compilationFlags} ${debugFlags})
target_compile_options(${language_library} PRIVATE /w14062)
target_link_libraries(${exe} PRIVATE ${language_library})
# go through all game libraries again and link them to the app/language executable
foreach(lib IN LISTS Ja2_Libs)
target_link_libraries(${exe} PRIVATE ${app}_${lib})
endforeach()
# go through all game libraries again and link them to the app executable
foreach(lib IN LISTS Ja2_Libs)
target_link_libraries(${exe} PRIVATE ${app}_${lib})
endforeach()
# for SGP only
target_link_libraries(${app}_sgp PRIVATE "ddraw.lib" "${PROJECT_SOURCE_DIR}/fmodvc.lib")
target_link_libraries(${app}_sgp PRIVATE libpng)
target_compile_definitions(${app}_sgp PRIVATE NO_ZLIB_COMPRESSION)
target_compile_definitions(${app}_sgp PRIVATE ${compilationFlags} ${debugFlags} NO_ZLIB_COMPRESSION)
endforeach()
+2 -2
View File
@@ -29,7 +29,7 @@ void IncreaseSelectionDensity();
void DecreaseSelectionDensity();
void RemoveCursors();
extern STR16 wszSelType[6];
extern STR16 *wszSelType;
extern BOOLEAN gfCurrentSelectionWithRightButton;
@@ -40,4 +40,4 @@ extern BOOLEAN gfCurrentSelectionWithRightButton;
#endif
#endif
#endif
+1 -1
View File
@@ -325,7 +325,7 @@ extern UINT8 gubCurrMercMode, gubPrevMercMode;
#define NUM_DIFF_LVLS 5
extern STR16 zDiffNames[NUM_DIFF_LVLS];
extern STR16 *zDiffNames;
extern INT16 sCurBaseDiff;
extern INT16 gsSelectedMercID;
extern INT32 gsSelectedMercGridNo;
+1 -1
View File
@@ -40,7 +40,7 @@ MOUSE_REGION popupRegion;
UINT16 gusEntryHeight;
BOOLEAN fWaitingForLButtonRelease = FALSE;
extern CHAR16 gszScheduleActions[ NUM_SCHEDULE_ACTIONS ][20];
extern CHAR16 (*gszScheduleActions)[20]; // NUM_SCHEDULE_ACTIONS entries
//Finds the string for any popup menu in JA2 -- the strings are stored
//in different ways in each instance.
+1
View File
@@ -2749,6 +2749,7 @@ void LoadSkillTraitsExternalSettings()
gSkillTraitValues.ubTERepairRobotPenaltyReduction = iniReader.ReadInteger("Technician","REPAIR_SPEED_ROBOT_PENALTY_REDUCTION", 30, 0, 100);
if (gSkillTraitValues.ubTETraitsNumToRepairRobot == 2) {gSkillTraitValues.ubTERepairRobotPenaltyReduction /= 2; }
gSkillTraitValues.fTETraitsCanRestoreItemThreshold = iniReader.ReadBoolean( "Technician", "MERCS_CAN_DO_ADVANCED_REPAIRS", FALSE );
gSkillTraitValues.ubTechLevelNeededForAdvancedRepair = iniReader.ReadInteger("Technician", "TECH_LEVEL_NEEDED_FOR_ADVANCED_REPAIR", 2, 1, 2);
// DOCTOR
gSkillTraitValues.ubDONumberTraitsNeededForSurgery = iniReader.ReadInteger("Doctor","NUMBER_OF_TRAITS_NEEDED_FOR_SURGERY", 1, 0, 2);
+3
View File
@@ -8,8 +8,10 @@
#include "Campaign Types.h"
#include "environment.h"
#include <string_view>
#define GAME_INI_FILE "Ja2.ini"
constexpr std::string_view LANGUAGE_INI_FILE{"Language.ini"};
//If you add any options, MAKE sure you add the corresponding string to the Options Screen string array.
// look up : zOptionsScreenHelpText , zOptionsToggleText
//Also, define its initialization and add its load/save to INI lines in : InitGameSettings() , SaveGameSettings() , LoadGameSettings()
@@ -2145,6 +2147,7 @@ typedef struct
UINT8 ubTERepairRobotPenaltyReduction;
UINT8 ubTETraitsNumToRepairRobot;
BOOLEAN fTETraitsCanRestoreItemThreshold;
UINT8 ubTechLevelNeededForAdvancedRepair; // if we have a high enough technician level, we can repair items above the normal threshold (1 for technician, 2 for engineer)
// DOCTOR
UINT8 ubDONumberTraitsNeededForSurgery;
+1 -1
View File
@@ -174,7 +174,7 @@ private:
static VideoPlayer s_VP(VideoPlayer::VT_SMK | VideoPlayer::VT_BINK);
extern STR16 gzIntroScreen[];
extern STR16* gzIntroScreen;
extern HVSURFACE ghFrameBuffer;
enum
+1 -1
View File
@@ -89,7 +89,7 @@ extern BOOLEAN gfDontOverRideSaveBuffer; //this variable can be unset if u
extern void HandleTacticalUILoseCursorFromOtherScreen( );
extern STR16 pUpdatePanelButtons[];
extern STR16* pUpdatePanelButtons;
#define NUM_CHAT_TOGGLES 2
+1 -1
View File
@@ -69,7 +69,7 @@ BOOLEAN gfStartedFromMapScreen = FALSE;
BOOLEAN fRestoreBackgroundForMessageBox = FALSE;
BOOLEAN gfDontOverRideSaveBuffer = TRUE; //this variable can be unset if ur in a non gamescreen and DONT want the msg box to use the save buffer
extern void HandleTacticalUILoseCursorFromOtherScreen( );
extern STR16 pUpdatePanelButtons[];
extern STR16* pUpdatePanelButtons;
CHAR16 gzUserDefinedButton1[ 128 ];
CHAR16 gzUserDefinedButton2[ 128 ];
+1 -1
View File
@@ -1822,7 +1822,7 @@ void HandleHighLightedText( BOOLEAN fHighLight )
bLastRegion = -1;
}
if( bHighLight != -1 )
if( bHighLight != -1 && toggle_box_array[bHighLight] != -1)
{
if( bHighLight < OPT_FIRST_COLUMN_TOGGLE_CUT_OFF )
{
-50
View File
@@ -1468,31 +1468,6 @@ BOOLEAN LoadMercBioInfo(UINT8 ubIndex, STR16 pInfoString, STR16 pAddInfo)
//{
// if( pInfoString[i] > 33 )
// pInfoString[i] -= 1;
// #ifdef POLISH
// switch( pInfoString[ i ] )
// {
// case 260: pInfoString[ i ] = 165; break;
// case 262: pInfoString[ i ] = 198; break;
// case 280: pInfoString[ i ] = 202; break;
// case 321: pInfoString[ i ] = 163; break;
// case 323: pInfoString[ i ] = 209; break;
// case 211: pInfoString[ i ] = 211; break;
// case 346: pInfoString[ i ] = 338; break;
// case 379: pInfoString[ i ] = 175; break;
// case 377: pInfoString[ i ] = 143; break;
// case 261: pInfoString[ i ] = 185; break;
// case 263: pInfoString[ i ] = 230; break;
// case 281: pInfoString[ i ] = 234; break;
// case 322: pInfoString[ i ] = 179; break;
// case 324: pInfoString[ i ] = 241; break;
// case 243: pInfoString[ i ] = 243; break;
// case 347: pInfoString[ i ] = 339; break;
// case 380: pInfoString[ i ] = 191; break;
// case 378: pInfoString[ i ] = 376; break;
// }
// #endif
//}
DecodeString(pInfoString, SIZE_MERC_BIO_INFO);
@@ -1514,31 +1489,6 @@ BOOLEAN LoadMercBioInfo(UINT8 ubIndex, STR16 pInfoString, STR16 pAddInfo)
//{
// if( pAddInfo[i] > 33 )
// pAddInfo[i] -= 1;
// #ifdef POLISH
// switch( pAddInfo[ i ] )
// {
// case 260: pAddInfo[ i ] = 165; break;
// case 262: pAddInfo[ i ] = 198; break;
// case 280: pAddInfo[ i ] = 202; break;
// case 321: pAddInfo[ i ] = 163; break;
// case 323: pAddInfo[ i ] = 209; break;
// case 211: pAddInfo[ i ] = 211; break;
// case 346: pAddInfo[ i ] = 338; break;
// case 379: pAddInfo[ i ] = 175; break;
// case 377: pAddInfo[ i ] = 143; break;
// case 261: pAddInfo[ i ] = 185; break;
// case 263: pAddInfo[ i ] = 230; break;
// case 281: pAddInfo[ i ] = 234; break;
// case 322: pAddInfo[ i ] = 179; break;
// case 324: pAddInfo[ i ] = 241; break;
// case 243: pAddInfo[ i ] = 243; break;
// case 347: pAddInfo[ i ] = 339; break;
// case 380: pAddInfo[ i ] = 191; break;
// case 378: pAddInfo[ i ] = 376; break;
// }
// #endif
//}
DecodeString(pAddInfo, SIZE_MERC_BIO_INFO);
+1 -1
View File
@@ -75,7 +75,7 @@ extern INT32 iAddExplosives ;
extern INT32 iAddMechanical ;
// pop up strings
extern STR16 pImpPopUpStrings[];
extern STR16* pImpPopUpStrings;
//extern BOOLEAN fIMPCompletedFlag;
+2 -2
View File
@@ -7,6 +7,6 @@ void RenderIMPPersonalityEntrance( void );
void ExitIMPPersonalityEntrance( void );
void HandleIMPPersonalityEntrance( void );
STR16 pSkillTraitBeginIMPStrings[];
extern STR16* pSkillTraitBeginIMPStrings;
#endif
#endif
+4 -4
View File
@@ -9,13 +9,13 @@ void PrintImpText( void );
void PrintIMPPersonalityQuizQuestionAndAnsers( void );
// buttons text
extern STR16 pImpButtonText[];
extern STR16* pImpButtonText;
// extra strings not found in IMP Text Document
extern STR16 pExtraIMPStrings[];
extern STR16* pExtraIMPStrings;
extern STR16 pSkillTraitBeginIMPStrings[]; // added - SANDRO
extern STR16* pSkillTraitBeginIMPStrings; // added - SANDRO
enum{
IMP_HOME_1,
@@ -145,4 +145,4 @@ enum{
};
#endif
#endif
+10 -5
View File
@@ -186,7 +186,7 @@ REPAIR_PASS_SLOTS_TYPE gRepairPassSlotList[ NUM_REPAIR_PASS_TYPES ] =
{ /* HEADROCK HAM B2.8: LBE Slot pass */ 0, 5, VESTPOCKPOS, LTHIGHPOCKPOS, RTHIGHPOCKPOS, CPACKPOCKPOS, BPACKPOCKPOS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
};
extern STR16 sRepairsDoneString[];
extern STR16* sRepairsDoneString;
// PopUp Box Handles
INT32 ghAssignmentBox = -1;
@@ -4948,7 +4948,7 @@ static void CollectRepairableItems(SOLDIERTYPE* pRepairSoldier, SOLDIERTYPE* pSo
// Check for attachments (are there stackable items that can take attachments though?)
UINT8 attachmentIndex = 0;
for (attachmentList::const_iterator iter = (*pObj)[stackIndex]->attachments.begin(); iter != (*pObj)[stackIndex]->attachments.end(); ++iter, ++attachmentIndex) {
if (IsItemRepairable(pRepairSoldier, iter->usItem, (*iter)[attachmentIndex]->data.objectStatus, (*iter)[attachmentIndex]->data.sRepairThreshold )) {
if ( iter->exists() && IsItemRepairable(pRepairSoldier, iter->usItem, (*iter)[attachmentIndex]->data.objectStatus, (*iter)[attachmentIndex]->data.sRepairThreshold )) {
// Send the main item, not the attachment
RepairItem item(pObj, pSoldier, (INVENTORY_SLOT) pocketIndex);
itemsToFix.push(item);
@@ -5081,7 +5081,7 @@ OBJECTTYPE* FindRepairableItemInSpecificPocket(SOLDIERTYPE * pSoldier, OBJECTTYP
// have to check for attachments after...
for (attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end(); ++iter) {
// if it's repairable and NEEDS repairing
if ( IsItemRepairable( pSoldier, iter->usItem, (*iter)[subObject]->data.objectStatus, (*iter)[subObject]->data.sRepairThreshold ) && iter->exists() ) {
if ( iter->exists() && IsItemRepairable( pSoldier, iter->usItem, (*iter)[subObject]->data.objectStatus, (*iter)[subObject]->data.sRepairThreshold ) ) {
return( &(*iter) );
}
}
@@ -5171,8 +5171,12 @@ BOOLEAN RepairObject( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOwner, OBJECTTYPE *
INT16 threshold = 100;
if ( gGameExternalOptions.fAdvRepairSystem && (Item[pObj->usItem].usItemClass & (IC_WEAPON|IC_ARMOUR)) )
{
if ( !gSkillTraitValues.fTETraitsCanRestoreItemThreshold || !HAS_SKILL_TRAIT( pSoldier, TECHNICIAN_NT ) )
if (gSkillTraitValues.fTETraitsCanRestoreItemThreshold && NUM_SKILL_TRAITS(pSoldier, TECHNICIAN_NT) >= gSkillTraitValues.ubTechLevelNeededForAdvancedRepair) // Greysa: added skill check for advanced repair. If we have a high enough technician level, we can repair items above the normal threshold (1 for technician, 2 for engineer)
{
threshold = 100;
}
else
{
threshold = (*pObj)[ubLoop]->data.sRepairThreshold;
}
}
@@ -11085,7 +11089,8 @@ void DetermineWhichAssignmentMenusCanBeShown( void )
CreateDestroyMouseRegionForFacilityMenu();
CreateDestroyMouseRegionsForFacilityAssignmentMenu();
if( ( ( gCharactersList[ bSelectedInfoChar ].usSolID->stats.bLife == 0 )||( gCharactersList[bSelectedInfoChar].usSolID->bAssignment == ASSIGNMENT_POW ) ) && ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) )
const auto selectedCharacter = gCharactersList[bSelectedInfoChar].usSolID;
if( selectedCharacter < NOBODY && ( (selectedCharacter->stats.bLife == 0 )||(selectedCharacter->bAssignment == ASSIGNMENT_POW ) ) && ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) )
{
// show basic assignment menu
ShowBox( ghRemoveMercAssignBox );
+13 -5
View File
@@ -2481,6 +2481,12 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
DeleteVideoObjectFromIndex( gpAR->iIndent );
DeleteVideoSurfaceFromIndex( gpAR->iInterfaceBuffer );
// Load necessary mapinfo to place corpses
CHAR8 bFilename[50];
INT32 worldRows, worldCols;
GetMapFileName(gpAR->ubSectorX, gpAR->ubSectorY, 0, bFilename, TRUE, TRUE);
LoadWorldInfoForAutoResolve(bFilename, worldRows, worldCols);
if( fDeleteForGood )
{ //Delete the soldier instances -- done when we are completely finished.
@@ -2519,7 +2525,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
RemoveCharacterFromSquads( gpMercs[ i ].pSoldier );
ChangeSoldiersAssignment( gpMercs[ i ].pSoldier, ASSIGNMENT_DEAD );
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpMercs[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpMercs[ i ].pSoldier, RandomGridNoUnloadedSector(worldRows, worldCols), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
}
else if( gpAR->ubBattleStatus == BATTLE_SURRENDERED || gpAR->ubBattleStatus == BATTLE_CAPTURED )
{
@@ -2624,7 +2630,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
}
// Flugente: drop sector equipment
gpCivs[ i ].pSoldier->DropSectorEquipment();
const auto gridno = RandomGridNoUnloadedSector(worldRows, worldCols);
gpCivs[ i ].pSoldier->DropSectorEquipment(gridno);
if( fDeleteForGood && gpCivs[ i ].pSoldier->stats.bLife < OKLIFE/2 )
{
@@ -2649,7 +2656,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
UpdateMilitia( militia );
}
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpCivs[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpCivs[ i ].pSoldier, gridno, ADD_DEAD_SOLDIER_TO_SWEETSPOT );
StrategicRemoveMilitiaFromSector( gpCivs[ i ].pSoldier->sSectorX, gpCivs[ i ].pSoldier->sSectorY, ubCurrentRank, 1 );
if( ProcessLoyalty() )
@@ -2681,7 +2688,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass ); //add casualty to some statistic
if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 );
ProcessQueenCmdImplicationsOfDeath( gpEnemies[ i ].pSoldier );
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpEnemies[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
const auto gridno = RandomGridNoUnloadedSector(worldRows, worldCols);
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpEnemies[ i ].pSoldier, gridno, ADD_DEAD_SOLDIER_TO_SWEETSPOT);
}
}
}
@@ -6007,7 +6015,7 @@ void AutoResolveMilitiaDropAndPromote()
}
// Flugente: drop sector equipment
gpCivs[i].pSoldier->DropSectorEquipment( );
gpCivs[i].pSoldier->DropSectorEquipment( NOWHERE );
if ( gpCivs[i].pSoldier->stats.bLife < OKLIFE / 2 )
{
-4
View File
@@ -249,10 +249,6 @@ void AdvanceClock( UINT8 ubWarpCode )
guiDay = ( guiGameClock / NUM_SEC_IN_DAY );
guiHour = ( guiGameClock - ( guiDay * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR;
guiMin = ( guiGameClock - ( ( guiDay * NUM_SEC_IN_DAY ) + ( guiHour * NUM_SEC_IN_HOUR ) ) ) / NUM_SEC_IN_MIN;
uiHourLua = guiHour;
uiDayLua = guiDay;
uiMinLua = guiMin;
swprintf( WORLDTIMESTR, L"%s %d, %02d:%02d", gpGameClockString[ STR_GAMECLOCK_DAY_NAME ], guiDay, guiHour, guiMin );
+4 -1
View File
@@ -158,7 +158,6 @@ CHAR16 zString[128];
HourlyDrugUpdate();
RebelCommand::HourlyUpdate();
// WANNE: This check should avoid the resaving of a loaded auto-save game, when entering tactical
BOOLEAN doAutoSave = TRUE;
@@ -169,6 +168,10 @@ CHAR16 zString[128];
if (doAutoSave)
{
// We're also using the doAutoSave check to prevent RebelCommand::DailyUpdate() from running a second time when loading an autosave at 00:00
RebelCommand::HourlyUpdate();
if ( AutoSaveToSlot[1] == FALSE && AutoSaveToSlot[2] == FALSE && AutoSaveToSlot[3] == FALSE && AutoSaveToSlot[4] == FALSE )
AutoSaveToSlot[0] = TRUE;
+23 -3
View File
@@ -859,6 +859,7 @@ static int l_PlayerTeamFull(lua_State* L);
static int l_ProfilesStrategicInsertionData(lua_State* L);
static int l_HealBoxers(lua_State* L);
static int l_ResetBoxers(lua_State* L);
static int l_AddVolunteers(lua_State* L);
@@ -912,9 +913,6 @@ static int l_SetIntelAndQuestMapDataForSector(lua_State* L);
using namespace std;
UINT16 idProfil;
UINT32 uiHourLua;
UINT32 uiDayLua;
UINT32 uiMinLua;
UINT16 PROFILLUA_sSectorX;
UINT16 PROFILLUA_sSectorY;
@@ -1189,6 +1187,7 @@ static void IniFunction(lua_State* L, BOOLEAN bQuests)
lua_register(L, "TacticalCharacterDialogueWithSpecialEvent", l_TacticalCharacterDialogueWithSpecialEvent);
lua_register(L, "SetSalary", l_MercSalary);
lua_register(L, "SetProfileStrategicInsertionData", l_ProfilesStrategicInsertionData);
lua_register(L, "HealBoxers", l_HealBoxers);
//Get merc
lua_register(L, "GetDirection", l_GetDirection); //new
@@ -9315,6 +9314,27 @@ static int l_ResetBoxers(lua_State* L)
return 0;
}
// heal boxers back to max health in case the player stays in sector while the boxers are resting
static int l_HealBoxers(lua_State* L)
{
for (UINT8 i = 0; i < NUM_BOXERS; ++i)
{
// Get breath back
gubBoxerID[i]->bBreath = gubBoxerID[i]->bBreathMax;
gubBoxerID[i]->sBreathRed = 0;
// Get life back
gubBoxerID[i]->stats.bLife = gubBoxerID[i]->stats.bLifeMax;
gubBoxerID[i]->bBleeding = 0;
// erase insta-healable injury
gubBoxerID[i]->iHealableInjury = 0;
DebugQuestInfo(String("Lua: healed gubBoxerID[%d] %d back to full health", i, gubBoxerID[i]));
}
return 0;
}
//Set character to sector Y
static int l_SetCharacterSectorY(lua_State* L)
{
-3
View File
@@ -26,9 +26,6 @@ typedef struct
extern ACTION_ITEM_VALUES ActionItemsValues[500];
extern UINT32 uiHourLua;
extern UINT32 uiDayLua;
extern UINT32 uiMinLua;
extern UINT16 PROFILLUA_sSectorX;
extern UINT16 PROFILLUA_sSectorY;
extern UINT8 PROFILLUA_bSectorZ;
+10 -9
View File
@@ -510,15 +510,6 @@ void IniGlobalGameSetting(lua_State *L)
lua_pushinteger(L, gubBoxingMatchesWon);
lua_setglobal(L, "gubBoxingMatchesWon");
lua_pushinteger(L, uiHourLua);
lua_setglobal(L, "cHour");
lua_pushinteger(L, uiDayLua);
lua_setglobal(L, "cDay");
lua_pushinteger(L, uiMinLua);
lua_setglobal(L, "cMin");
lua_pushinteger(L, gbPlayerNum);
lua_setglobal(L, "gbPlayerNum");
@@ -590,6 +581,16 @@ void IniGlobalGameSetting(lua_State *L)
lua_pushinteger(L, guiMin);
lua_setglobal(L, "guiMin");
lua_pushinteger(L, guiDay);
lua_setglobal(L, "cDay");
lua_pushinteger(L, guiHour);
lua_setglobal(L, "cHour");
lua_pushinteger(L, guiMin);
lua_setglobal(L, "cMin");
lua_pushinteger(L, guiCurrentScreen);
lua_setglobal(L, "guiCurrentScreen");
@@ -1133,8 +1133,12 @@ void SaveSeenAndUnseenItems( void )
if(pipl->fExists && pipl->object.ubNumberOfObjects)
{
uiTotalNumberOfVisibleItems += pipl->object.ubNumberOfObjects;
if(i > uiNumberOfSeenItems)
if (i > uiNumberOfSeenItems)
{
pInventoryPoolList[uiNumberOfSeenItems] = *pipl;
pipl->fExists = FALSE;
}
uiNumberOfSeenItems++;
}
}
+1 -1
View File
@@ -194,7 +194,7 @@ INT32 iHeightOfInitFastHelpText = 0;
extern INT32 giMapContractButton;
extern INT32 giCharInfoButton[];
extern STR16 pUpdatePanelButtons[];
extern STR16* pUpdatePanelButtons;
// the list of soldiers that are moving
SOLDIERTYPE * pSoldierMovingList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
+9
View File
@@ -904,7 +904,16 @@ BOOLEAN BeginStrategicRemoveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fAddRehireButto
else
{
if (!is_networked)
{
#ifdef JA2UB
// Leave equipment to merc's current sector by default in UB
HandleLeavingOfEquipmentInCurrentSector(pSoldier->ubID);
StrategicRemoveMerc(pSoldier);
pLeaveSoldier = NULL;
#else
NotifyPlayerOfMercDepartureAndPromptEquipmentPlacement( pSoldier, fAddRehireButton );
#endif
}
else
{
// WANNE - MP: Skip all the dialog boxes that appear. Just dismiss the merc
+1 -1
View File
@@ -49,7 +49,7 @@ extern "C" {
extern CHAR16 gzUserDefinedButton1[ 128 ];
extern CHAR16 gzUserDefinedButton2[ 128 ];
extern CHAR16 pTownNames[MAX_TOWNS][MAX_TOWN_NAME_LENGHT];
extern CHAR16 (*pTownNames)[MAX_TOWN_NAME_LENGHT];
static size_t MAX_BUTTON_LENGTH = 60;
static size_t MAX_BODY_LENGTH = 450;
+2 -2
View File
@@ -2,8 +2,8 @@
#define _QUEST_TEXT_H_
STR16 QuestDescText[];
STR16 FactDescText[];
extern STR16 *QuestDescText;
extern STR16 *FactDescText;
#endif
+1 -1
View File
@@ -31,7 +31,7 @@ class SOLDIERTYPE;
#ifdef JA2EDITOR
extern CHAR16 gszScheduleActions[ NUM_SCHEDULE_ACTIONS ][20];
extern CHAR16 (*gszScheduleActions)[20]; // NUM_SCHEDULE_ACTIONS entries
#endif
BOOLEAN GetEarliestMorningScheduleEvent( SCHEDULENODE *pSchedule, UINT32 * puiTime );
+3 -3
View File
@@ -4881,14 +4881,14 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
}
// depending on which cities the player currently holds, we send out attack on multiple cities. We try to make these attacks occur simultaneously, so the player will have to fend off
// multiple gigantic attacks on different cities. Ideally, the attacks will be timed so well that the player cannot use a sqaud in both battles, even with use of the helicopter
// multiple gigantic attacks on different cities. Ideally, the attacks will be timed so well that the player cannot use a squad in both battles, even with use of the helicopter
// we first have to check which cities we have to attack. For that, we simply check wether there are troops in the target sector. If not, we will attack here
BOOLEAN fAttack_Grumm = !(SectorInfo[ SEC_H3 ].ubNumTroops > 0);
BOOLEAN fAttack_Cambria = !(SectorInfo[ SEC_H8 ].ubNumTroops > 0);
BOOLEAN fCambriaSAMOccupied = !(SectorInfo[ SEC_I8 ].ubNumTroops > 0);
BOOLEAN fAttack_Alma = !(SectorInfo[ SEC_I13 ].ubNumTroops > 0);
BOOLEAN fAttack_Alma = !(SectorInfo[ SEC_I13 ].ubNumTroops > 0);
BOOLEAN fAttack_Balime = !(SectorInfo[ SEC_L11 ].ubNumTroops > 0);
BOOLEAN fAttack_Chitzena = !(SectorInfo[ SEC_L11 ].ubNumTroops > 0);
BOOLEAN fAttack_Chitzena = !(SectorInfo[ SEC_B2 ].ubNumTroops > 0);
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + difficultyMod * 3);
+1 -1
View File
@@ -180,7 +180,7 @@ INT16 sWorldSectorLocationOfFirstBattle = 0;
// preprocess sector for mercs in it
extern BOOLEAN fSectorsWithSoldiers[ MAP_WORLD_X * MAP_WORLD_X ][ 4 ];
extern CHAR16 pTownNames[MAX_TOWNS][MAX_TOWN_NAME_LENGHT];
extern CHAR16 (*pTownNames)[MAX_TOWN_NAME_LENGHT];
+16 -2
View File
@@ -613,8 +613,8 @@ extern BOOLEAN gfAutoAIAware;
extern void HandlePreBattleInterfaceStates();
// the title for the contract button on the character info panel in the upper left portion of the mapscreen
extern STR16 pContractButtonString[];
extern STR16 pBullseyeStrings[];
extern STR16* pContractButtonString;
extern STR16* pBullseyeStrings;
extern OBJECTTYPE *gpItemDescObject;
@@ -8472,6 +8472,12 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
if ( HandleNailsVestFetish( pSoldier, i, NOTHING ) )
continue;
// tais: never strip Madlab's robot of its installed components (ammo,
// targeting, chassis/armour, utility) - the player can't re-install them
// and the robot would be left defenceless. Only its cargo slot may be emptied.
if ( AM_A_ROBOT( pSoldier ) && i != ROBOT_INVENTORY_SLOT )
continue;
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo, pSoldier->pathing.bLevel);
DeleteObj(&pSoldier->inv[i]);
}
@@ -12742,6 +12748,10 @@ void HandleShadingOfLinesForContractMenu( void )
SOLDIERTYPE* pSoldier = gCharactersList[ bSelectedContractChar ].usSolID;
const bool multipleMercsSelected = (gSelectedSoldiers.size() > 0) ? true : false;
#ifdef JA2UB
// No contract renewal in UB
const bool atLeastOneAIMmerc = false;
#else
bool atLeastOneAIMmerc = false;
if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC)
{
@@ -12759,6 +12769,7 @@ void HandleShadingOfLinesForContractMenu( void )
}
}
}
#endif // JA2UB
// is guy in AIM? and well enough to talk and make such decisions?
if( (atLeastOneAIMmerc) && ( pSoldier->stats.bLife >= OKLIFE ) )
@@ -15366,7 +15377,10 @@ BOOLEAN CanExtendContractForCharSlot( INT16 bCharNumber )
// if a vehicle, in transit, or a POW
if( /*( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) ||*/
#ifndef JA2UB
// Allow contract box in UB before helicopter ride, so mercs can be dismissed if player has hired more than 6 mercs
( pSoldier->bAssignment == IN_TRANSIT ) ||
#endif
( pSoldier->bAssignment == ASSIGNMENT_POW ) )
{
// can't extend contracts at this time
+1 -1
View File
@@ -357,7 +357,7 @@ extern HVSURFACE ghFrameBuffer;
extern BOOLEAN gfOverrideSector;
extern BOOLEAN sBadSectorsList[WORLD_MAP_X][WORLD_MAP_X];
extern STR16 pBullseyeStrings[];
extern STR16* pBullseyeStrings;
extern void HandleRPCDescription( );
-1
View File
@@ -2,4 +2,3 @@
# priority (LOW,HIGH) and description
LOW readd the C4838 (https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4838) warning to CMakeLists.txt once they're all fixed in the code
HIGH get rid of ENGLISH, GERMAN, etc preprocessor definitions completely. that way i18n can be built just once and language can be changed in the options screen pending game restart (hotloading will likely require more work)
+3 -3
View File
@@ -1423,7 +1423,7 @@ void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject )
for (attachmentList::iterator iter = seperateObject[0]->attachments.begin(); iter != seperateObject[0]->attachments.end();) {
// ARM: Note: this is only used for selling, not repairs, so attachmentes are seperated when sold to a dealer
// If the attachment is detachable
if (! (Item[ iter->usItem ].inseparable ) && iter->exists())
if (! (iter->exists() && Item[ iter->usItem ].inseparable))
{
// add this particular attachment (they can't be imprinted, or themselves have attachments!)
AddObjectToArmsDealerInventory( ubArmsDealer, &(*iter) );
@@ -1931,7 +1931,7 @@ UINT32 CalculateObjectItemRepairTime( UINT8 ubArmsDealer, OBJECTTYPE *pItemObjec
// add time to repair any attachments on it
for (attachmentList::iterator iter = (*pItemObject)[x]->attachments.begin(); iter != (*pItemObject)[x]->attachments.end(); ++iter) {
// if damaged and repairable
if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) && iter->exists())
if ( iter->exists() && ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) )
{
//uiRepairTime += CalculateSimpleItemRepairTime( ubArmsDealer, iter->usItem, (*iter)[x]->data.objectStatus );
uiRepairTime += CalculateObjectItemRepairTime( ubArmsDealer, &(*iter) );
@@ -1988,7 +1988,7 @@ UINT32 CalculateObjectItemRepairCost( UINT8 ubArmsDealer, OBJECTTYPE *pItemObjec
// add cost of repairing any attachments on it
for (attachmentList::iterator iter = (*pItemObject)[x]->attachments.begin(); iter != (*pItemObject)[x]->attachments.end(); ++iter) {
// if damaged and repairable
if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) && iter->exists())
if ( iter->exists() && ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) )
{
uiRepairCost += CalculateObjectItemRepairCost( ubArmsDealer, &(*iter));
}
+5 -2
View File
@@ -453,11 +453,14 @@ BOOLEAN BoxerAvailable( void )
return( FALSE );
}
// NOTE THIS IS NOW BROKEN BECAUSE NPC.C ASSUMES THAT BOXERSAVAILABLE < 3 IS A
// SEQUEL FIGHT. Maybe we could check Kingpin's location instead!
UINT8 BoxersAvailable( void )
{
UINT8 ubCount = 0;
// Should also run CheckOnBoxers to make sure boxer IDs are set for this function similarly to BoxerAvailable
if (CheckOnBoxers() == FALSE)
{
return(ubCount);
}
for (UINT8 ubLoop = 0; ubLoop < NUM_BOXERS; ++ubLoop)
{
+412 -556
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7035,7 +7035,7 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet
if ((pObject->exists() == true) && !ItemIsUndroppableByDefault(pObject->usItem)) // CHECK! Undroppable items cannot be stolen - SANDRO
{
// Is the enemy collapsed
if ( pOpponent->stats.bLife < OKLIFE || pOpponent->bCollapsed )
if ( pOpponent->stats.bLife < OKLIFE || pOpponent->bCollapsed || (pOpponent->usSoldierFlagMask & SOLDIER_POW) )
{
// We can steal any of his items in the inventory
fStealItem = TRUE;
+2 -2
View File
@@ -10073,7 +10073,7 @@ void DrawArmorValues( OBJECTTYPE * gpItemDescObject )
UINT16 iFinalProtectionValue = iProtectionValue;
for (attachmentList::iterator iter = (*gpItemDescObject)[0]->attachments.begin(); iter != (*gpItemDescObject)[0]->attachments.end(); ++iter)
{
if (Item[ iter->usItem ].usItemClass == IC_ARMOUR)
if ( iter->exists() && Item[ iter->usItem ].usItemClass == IC_ARMOUR)
{
iFinalProtectionValue += Armour[Item[iter->usItem].ubClassIndex].ubProtection;
}
@@ -10099,7 +10099,7 @@ void DrawArmorValues( OBJECTTYPE * gpItemDescObject )
UINT16 iComparedFinalProtectionValue = iComparedProtectionValue;
for (attachmentList::iterator iter = (*gpComparedItemDescObject)[0]->attachments.begin(); iter != (*gpComparedItemDescObject)[0]->attachments.end(); ++iter)
{
if (Item[ iter->usItem ].usItemClass == IC_ARMOUR)
if ( iter->exists() && Item[ iter->usItem ].usItemClass == IC_ARMOUR)
{
iComparedFinalProtectionValue += Armour[Item[iter->usItem].ubClassIndex].ubProtection;
}
+22 -4
View File
@@ -643,13 +643,29 @@ void popupCallbackItem(INT16 itemId){
i++;p++;
}
OBJECTTYPE pObjTmp;
static OBJECTTYPE pObjTmp;
pObjTmp.initialize();
if( bestStack->RemoveObjectAtIndex(leastDamagedIndex, &pObjTmp) ){
gpItemPointer = &pObjTmp; // pick up the object (or stack)
DoAttachment((UINT8)gubPopupStatusIndex, guiPopupItemPos); // try to attach it
//gpItemPointer = NULL; // dont drop it!
// If attaching failed, change mouse cursor to item as we're still holding it
if ( gpItemPointer->exists() ) {
// Set mouse
guiExternVo = GetInterfaceGraphicForItem(&(Item[gpItemPointer->usItem]));
gusExternVoSubIndex = Item[gpItemPointer->usItem].ubGraphicNum;
MSYS_ChangeRegionCursor(&gMPanelRegion, EXTERN_CURSOR);
MSYS_SetCurrentCursor(EXTERN_CURSOR);
fMapInventoryItem = TRUE;
fTeamPanelDirty = TRUE;
//Dirty interface
fInterfacePanelDirty = DIRTYLEVEL2;
UpdateItemHatches();
}
gItemDescAttachmentPopups[giActiveAttachmentPopup]->hide();
RenderItemDescriptionBox();
@@ -6060,7 +6076,8 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason)
gfItemAmmoDown = FALSE;
//CHRISL: We dont' want to be able to reload guns using the ammo crate from this function
if((gpItemPointer != NULL && Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubMagType >= AMMO_BOX) || !EnoughPoints(gpItemDescSoldier, APBPConstants[AP_RELOAD_GUN], 0, TRUE))//dnl ch65 040913
//Greysa: add check for ammo item
if( gpItemPointer != NULL && ( (Item[gpItemPointer->usItem].usItemClass != IC_AMMO || Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubMagType >= AMMO_BOX) ) || !EnoughPoints(gpItemDescSoldier, APBPConstants[AP_RELOAD_GUN], 0, TRUE) )//dnl ch65 040913
{
fInterfacePanelDirty = DIRTYLEVEL2;
btn->uiFlags &= (~BUTTON_CLICKED_ON );
@@ -6083,7 +6100,8 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason)
else
{
//holding an item
if(Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubCalibre == Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubCalibre)
//Greysa: add check for ammo item
if( Item[gpItemPointer->usItem].usItemClass == IC_AMMO && Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubCalibre == Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubCalibre )
{
ReloadGun(gpItemDescSoldier, gpItemDescObject, gpItemPointer, ubStatusIndex);
}
+137 -45
View File
@@ -1995,7 +1995,7 @@ OBJECTTYPE* FindAttachment( OBJECTTYPE * pObj, UINT16 usItem, UINT8 subObject )
{
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end(); ++iter) {
if (iter->usItem == usItem && iter->exists())
if ( iter->exists() && iter->usItem == usItem )
{
return &(*iter);
}
@@ -2008,7 +2008,7 @@ OBJECTTYPE* FindAttachmentByClass( OBJECTTYPE * pObj, UINT32 uiItemClass, UINT8
{
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == uiItemClass && iter->exists())
if ( iter->exists() && Item[iter->usItem].usItemClass == uiItemClass )
{
return &(*iter);
}
@@ -2021,7 +2021,7 @@ OBJECTTYPE* FindAttachmentByAttachmentClass( OBJECTTYPE * pObj, UINT32 uiAttachm
{
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end(); ++iter) {
if (Item[iter->usItem].attachmentclass == uiAttachmentClass && iter->exists())
if ( iter->exists() && Item[iter->usItem].attachmentclass == uiAttachmentClass )
{
return &(*iter);
}
@@ -2139,7 +2139,7 @@ OBJECTTYPE* FindNonSmokeLaunchableAttachment( OBJECTTYPE * pObj, UINT16 usWeapon
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (ValidLaunchable( iter->usItem, usWeapon) && Explosive[Item[iter->usItem].ubClassIndex].ubType != EXPLOSV_SMOKE && iter->exists())
if ( iter->exists() && ValidLaunchable( iter->usItem, usWeapon) && Explosive[Item[iter->usItem].ubClassIndex].ubType != EXPLOSV_SMOKE )
{
return &(*iter);
}
@@ -2162,7 +2162,7 @@ BOOLEAN ItemHasAttachments( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier, UINT8 ite
{
for(attachmentList::iterator att = (*pObj)[iter]->attachments.begin(); att != (*pObj)[iter]->attachments.end(); ++att)
{
if ( att->usItem != 0 && !ItemIsHiddenAttachment(att->usItem) )
if ( att->exists() && att->usItem != 0 && !ItemIsHiddenAttachment(att->usItem) )
{
attachmentHidden = FALSE;
break;
@@ -2178,7 +2178,7 @@ BOOLEAN ItemHasAttachments( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier, UINT8 ite
{
for(attachmentList::iterator att = (*pObj)[iter]->attachments.begin(); att != (*pObj)[iter]->attachments.end(); ++att)
{
if ( att->usItem != 0 && !ItemIsHiddenAttachment(att->usItem) )
if ( att->exists() && att->usItem != 0 && !ItemIsHiddenAttachment(att->usItem) )
{
attachmentHidden = FALSE;
break;
@@ -3872,13 +3872,111 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier, bool aReloadEvenIfNotEmpty )
{
OBJECTTYPE *pObj, *pObj2;
INT8 bSlot;
INT16 bAPCost;
INT16 bAPCost;
BOOLEAN fRet = FALSE;
CHECKF( pSoldier );
// Flugente: check for underbarrel weapons and use that object if necessary
pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
pObj2 = NULL;
if (pSoldier->IsValidSecondHandShotForReloadingPurposes()) //check for valid second hand weapon for reloading purposes (something that doesn't use ammo)
{
pObj2 = pSoldier->GetUsedWeapon( &(pSoldier->inv[SECONDHANDPOS]) );
}
// Greysa: Check if weapon is jammed and unjam it first
if ((*pObj)[0]->data.gun.bGunAmmoStatus < 0 || ((pObj2 != NULL) && (*pObj2)[0]->data.gun.bGunAmmoStatus < 0))
{
if ((*pObj)[0]->data.gun.bGunAmmoStatus < 0)
{
//borrowed from Weapons.cpp
if (EnoughPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM], FALSE))
{
DeductPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM]);
INT8 bChanceMod;
if (Weapon[pObj->usItem].EasyUnjam)
bChanceMod = 100;
else
bChanceMod = (INT8)(GetReliability(pObj) * 4);
int iResult = SkillCheck(pSoldier, UNJAM_GUN_CHECK, bChanceMod);
if (iResult > 0)
{
// yay! unjammed the gun
(*pObj)[0]->data.gun.bGunAmmoStatus *= -1;
// MECHANICAL/DEXTERITY GAIN: Unjammed a gun
if (bChanceMod < 100) // don't give exp for unjamming an easily unjammable gun
{
StatChange(pSoldier, MECHANAMT, 5, FALSE);
StatChange(pSoldier, DEXTAMT, 5, FALSE);
}
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
PlayJA2Sample(Weapon[Item[pObj->usItem].ubClassIndex].ManualReloadSound, RATE_11025, SoundVolume(HIGHVOLUME, pSoldier->sGridNo), 1, SoundDir(pSoldier->sGridNo));
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_UNJAMMED], pSoldier->GetName(), ItemNames[pObj->usItem]);
// merc voice feedback?
}
else
{
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_FAILED_UNJAM], pSoldier->GetName(), ItemNames[pObj->usItem]);
}
}
else
{
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_NO_AP_NO_UNJAM], pSoldier->GetName(), ItemNames[pObj->usItem]);
}
}
if ((pObj2 != NULL) && (*pObj2)[0]->data.gun.bGunAmmoStatus < 0)
{
if (EnoughPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM], FALSE))
{
DeductPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM]);
INT8 bChanceMod;
if (Weapon[pObj2->usItem].EasyUnjam)
bChanceMod = 100;
else
bChanceMod = (INT8)(GetReliability(pObj2) * 4);
int iResult = SkillCheck(pSoldier, UNJAM_GUN_CHECK, bChanceMod);
if (iResult > 0)
{
// yay! unjammed the gun
(*pObj2)[0]->data.gun.bGunAmmoStatus *= -1;
// MECHANICAL/DEXTERITY GAIN: Unjammed a gun
if (bChanceMod < 100) // don't give exp for unjamming an easily unjammable gun
{
StatChange(pSoldier, MECHANAMT, 5, FALSE);
StatChange(pSoldier, DEXTAMT, 5, FALSE);
}
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
PlayJA2Sample(Weapon[Item[pObj2->usItem].ubClassIndex].ManualReloadSound, RATE_11025, SoundVolume(HIGHVOLUME, pSoldier->sGridNo), 1, SoundDir(pSoldier->sGridNo));
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_UNJAMMED], pSoldier->GetName(), ItemNames[pObj2->usItem]);
// merc voice feedback?
}
else
{
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_FAILED_UNJAM], pSoldier->GetName(), ItemNames[pObj2->usItem]);
}
}
else
{
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_NO_AP_NO_UNJAM], pSoldier->GetName(), ItemNames[pObj2->usItem]);
}
}
return FALSE; // Greysa: We want to skip reloading if we attempted to unjam, regardless of outcome. Return value doesn't seem to matter as there doesn't seem to be any actual checks on the returned value. I picked FALSE as actual reload hasn't occurred
}
//<SB> manual recharge
if ((*pObj)[0]->data.gun.ubGunShotsLeft && !((*pObj)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
@@ -3915,10 +4013,8 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier, bool aReloadEvenIfNotEmpty )
PlayJA2Sample( Weapon[ Item[pObj->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
if ( pSoldier->IsValidSecondHandShot( ) )
if (pObj2 != NULL)
{
pObj2 = &(pSoldier->inv[SECONDHANDPOS]);
if ((*pObj2)[0]->data.gun.ubGunShotsLeft && !((*pObj2)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
{
(*pObj2)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
@@ -3930,10 +4026,8 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier, bool aReloadEvenIfNotEmpty )
}
else
{
if ( pSoldier->IsValidSecondHandShot( ) )
if (pObj2 != NULL)
{
pObj2 = &(pSoldier->inv[SECONDHANDPOS]);
if ((*pObj2)[0]->data.gun.ubGunShotsLeft && !((*pObj2)[0]->data.gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) )
{
(*pObj2)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
@@ -3989,21 +4083,19 @@ BOOLEAN AutoReload( SOLDIERTYPE * pSoldier, bool aReloadEvenIfNotEmpty )
// if we are valid for two-pistol shooting (reloading) and we have enough APs still
// then do a reload of both guns!
// Flugente: only reload if it's empty, or we really want to
if ( pSoldier->IsValidSecondHandShotForReloadingPurposes()
&& ( aReloadEvenIfNotEmpty || !EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS ) ) )
if ( pObj2 != NULL && ( aReloadEvenIfNotEmpty || !EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS ) ) )
{
// Flugente: check for underbarrel weapons and use that object if necessary
pObj = pSoldier->GetUsedWeapon( &( pSoldier->inv[SECONDHANDPOS] ) );
bSlot = FindAmmoToReload( pSoldier, SECONDHANDPOS, NO_SLOT );
if ( bSlot != NO_SLOT )
{
// ce would reload using this ammo!
bAPCost = GetAPsToReloadGunWithAmmo( pSoldier, pObj, &( pSoldier->inv[bSlot] ) );
bAPCost = GetAPsToReloadGunWithAmmo( pSoldier, pObj2, &( pSoldier->inv[bSlot] ) );
if ( EnoughPoints( pSoldier, (INT16)bAPCost, 0, FALSE ) )
{
// reload the 2nd gun too
fRet = ReloadGun( pSoldier, pObj, &( pSoldier->inv[bSlot] ) );
fRet = ReloadGun( pSoldier, pObj2, &( pSoldier->inv[bSlot] ) );
}
else
{
@@ -5566,7 +5658,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
//Madd: if the attaching/merging item had any attachments on it, then try to move them to the first result
for (attachmentList::iterator iter = (*pAttachment)[0]->attachments.begin(); iter != (*pAttachment)[0]->attachments.end();) {
if( ValidItemAttachmentSlot(this, iter->usItem, TRUE, FALSE, subObject )){
if( iter->exists() && ValidItemAttachmentSlot(this, iter->usItem, TRUE, FALSE, subObject )){
//This seems to be rather valid. Can't be 100% sure though.
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
CreateItem(iter->usItem, (*iter)[0]->data.objectStatus, &tempAttachment);
@@ -5903,7 +5995,7 @@ void RemoveProhibitedAttachments(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
//Start by trying to re-attach inseperable items. They take precedence over items that can normally be removed
for (attachmentList::iterator iter = tempAttachList.begin(); iter != tempAttachList.end();) {
if(Item[iter->usItem].inseparable && ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, 0, -1, 0, NULL, usAttachmentSlotIndexVector)){
if( iter->exists() && Item[iter->usItem].inseparable && ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, 0, -1, 0, NULL, usAttachmentSlotIndexVector)){
//This seems to be rather valid. Can't be 100% sure though.
if(pObj->AttachObject(NULL, &(*iter), FALSE, 0, -1, FALSE, usAttachmentSlotIndexVector)){
//Ok now we can be sure, lets remove this object so we don't try to drop it later.
@@ -5917,7 +6009,7 @@ void RemoveProhibitedAttachments(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
}
//Try to attach all the other attachments that didn't fit their current slot.
for (attachmentList::iterator iter = tempAttachList.begin(); iter != tempAttachList.end();) {
if(ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, 0, -1, 0, NULL, usAttachmentSlotIndexVector)){
if( iter->exists() && ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, 0, -1, 0, NULL, usAttachmentSlotIndexVector)){
//This seems to be rather valid. Can't be 100% sure though.
if(pObj->AttachObject(NULL, &(*iter), FALSE, 0, -1, FALSE, usAttachmentSlotIndexVector)){
//Ok now we can be sure, lets remove this object so we don't try to drop it later.
@@ -6093,7 +6185,7 @@ attachmentList ReInitMergedItem(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
//First re-attach any slot-changing attachments.
for (attachmentList::iterator iter = tempSlotChangingAttachList.begin(); iter != tempSlotChangingAttachList.end();) {
if( ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, ubStatusIndex )){
if( iter->exists() && ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, ubStatusIndex )){
//This seems to be rather valid. Can't be 100% sure though.
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
CreateItem(iter->usItem, (*iter)[0]->data.objectStatus, &tempAttachment);
@@ -6110,7 +6202,7 @@ attachmentList ReInitMergedItem(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
//Time to re-attach the other attachments, if we can. I am the king of copy pasta.
for (attachmentList::iterator iter = tempAttachList.begin(); iter != tempAttachList.end();) {
if( ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, ubStatusIndex)){
if( iter->exists() && ValidItemAttachmentSlot(pObj, iter->usItem, TRUE, FALSE, ubStatusIndex)){
//This seems to be rather valid. Can't be 100% sure though.
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
CreateItem(iter->usItem, (*iter)[0]->data.objectStatus, &tempAttachment);
@@ -6127,7 +6219,7 @@ attachmentList ReInitMergedItem(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
//drop all items we couldn't re-attach.
for (attachmentList::iterator iter = tempSlotChangingAttachList.begin(); iter != tempSlotChangingAttachList.end(); ++iter) {
if ( Item[iter->usItem].inseparable != 1)
if ( iter->exists() && Item[iter->usItem].inseparable != 1)
{//WarmSteel - Couldn't re-attach this item, try to drop it.
if (pSoldier) {
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
@@ -6145,7 +6237,7 @@ attachmentList ReInitMergedItem(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
}
//and the rest too
for (attachmentList::iterator iter = tempAttachList.begin(); iter != tempAttachList.end(); ++iter) {
if ( Item[iter->usItem].inseparable != 1)
if ( iter->exists() && Item[iter->usItem].inseparable != 1)
{//WarmSteel - Couldn't re-attach this item, try to drop it.
if (pSoldier) {
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
@@ -10330,7 +10422,7 @@ BOOLEAN NCTHIsScoped( OBJECTTYPE * pObj )
return TRUE;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[iter->usItem].scopemagfactor > 1.0 && iter->exists() )
if ( iter->exists() && Item[iter->usItem].scopemagfactor > 1.0 )
return TRUE;
}
}
@@ -10349,7 +10441,7 @@ BOOLEAN IsScoped( OBJECTTYPE * pObj )
return TRUE;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[iter->usItem].aimbonus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].aimbonus > 0 )
return TRUE;
}
}
@@ -10436,7 +10528,7 @@ INT16 GetBaseScopeAimBonus( OBJECTTYPE * pObj, INT32 iRange )
//Search for the most powerful scope we can use.
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); iter++)
{
if(Item[iter->usItem].aimbonus > bonus && iRange >= Item[iter->usItem].minrangeforaimbonus && iter->exists())
if( iter->exists() && Item[iter->usItem].aimbonus > bonus && iRange >= Item[iter->usItem].minrangeforaimbonus )
{
bonus = Item[iter->usItem].aimbonus;
}
@@ -10514,7 +10606,7 @@ UINT32 FindRangeBonusAttachment( OBJECTTYPE * pObj )
{
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].rangebonus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].rangebonus > 0 )
{
return( Item[iter->usItem].uiIndex );
}
@@ -10535,7 +10627,7 @@ INT16 GetRangeBonus( OBJECTTYPE * pObj )
bonus += Item[(*pObj)[0]->data.gun.usGunAmmoItem].rangebonus;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( !ItemIsDuckbill(iter->usItem) || (ItemIsDuckbill(iter->usItem) && (*pObj)[0]->data.gun.ubGunAmmoType == AMMO_BUCKSHOT ) && iter->exists())
if ( iter->exists() && !ItemIsDuckbill(iter->usItem) || (ItemIsDuckbill(iter->usItem) && (*pObj)[0]->data.gun.ubGunAmmoType == AMMO_BUCKSHOT ) )
bonus += BonusReduce( Item[iter->usItem].rangebonus, (*iter)[0]->data.objectStatus );
}
}
@@ -11961,7 +12053,7 @@ BOOLEAN HasThermalOptics( SOLDIERTYPE * pSoldier )
OBJECTTYPE* pObj = &pSoldier->inv[HANDPOS];
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (ItemIsThermalOptics(iter->usItem) && iter->exists() )
if ( iter->exists() && ItemIsThermalOptics(iter->usItem) )
return TRUE;
}
}
@@ -12018,7 +12110,7 @@ BOOLEAN IsDuckbill( OBJECTTYPE * pObj )
return TRUE;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (ItemIsDuckbill(iter->usItem) && iter->exists() )
if ( iter->exists() && ItemIsDuckbill(iter->usItem) )
{
return( TRUE );
}
@@ -12069,7 +12161,7 @@ BOOLEAN IsDetonatorAttached( OBJECTTYPE * pObj )
// return TRUE;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( IsAttachmentClass( iter->usItem, AC_DETONATOR ) && iter->exists() )
if ( iter->exists() && IsAttachmentClass( iter->usItem, AC_DETONATOR ) )
{
return( TRUE );
}
@@ -12085,7 +12177,7 @@ BOOLEAN IsRemoteDetonatorAttached( OBJECTTYPE * pObj )
// return TRUE;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( IsAttachmentClass( iter->usItem, AC_REMOTEDET ) && iter->exists() )
if ( iter->exists() && IsAttachmentClass( iter->usItem, AC_REMOTEDET ) )
{
return( TRUE );
}
@@ -12357,7 +12449,7 @@ OBJECTTYPE* FindAttachedBatteries( OBJECTTYPE * pObj )
{
if (pObj->exists() == true) {
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (ItemIsBatteries(iter->usItem) && iter->exists())
if ( iter->exists() && ItemIsBatteries(iter->usItem) )
{
return( &(*iter) );
}
@@ -12589,7 +12681,7 @@ INT16 GetCamoBonus( OBJECTTYPE * pObj )
bonus = (Item[pObj->usItem].camobonus);// * (WEAPON_STATUS_MOD((*pObj)[0]->data.objectStatus) / 100)) ;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (!ItemIsCamoKit(iter->usItem) && iter->exists())
if ( iter->exists() && !ItemIsCamoKit(iter->usItem) )
bonus += (INT16) (Item[iter->usItem].camobonus);// * (WEAPON_STATUS_MOD((*iter)[0]->data.objectStatus) / 100));
}
}
@@ -12602,7 +12694,7 @@ INT16 GetUrbanCamoBonus( OBJECTTYPE * pObj )
bonus = (Item[pObj->usItem].urbanCamobonus);// * (WEAPON_STATUS_MOD((*pObj)[0]->data.objectStatus) / 100)) ;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (!ItemIsCamoKit(iter->usItem) && iter->exists())
if ( iter->exists() && !ItemIsCamoKit(iter->usItem) )
bonus += (INT16) (Item[iter->usItem].urbanCamobonus);// * (WEAPON_STATUS_MOD((*iter)[0]->data.objectStatus) / 100));
}
}
@@ -12615,7 +12707,7 @@ INT16 GetDesertCamoBonus( OBJECTTYPE * pObj )
bonus = (Item[pObj->usItem].desertCamobonus);// * (WEAPON_STATUS_MOD((*pObj)[0]->data.objectStatus) / 100)) ;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (!ItemIsCamoKit(iter->usItem) && iter->exists())
if ( iter->exists() && !ItemIsCamoKit(iter->usItem) )
bonus += (INT16) (Item[iter->usItem].desertCamobonus);// * (WEAPON_STATUS_MOD((*iter)[0]->data.objectStatus) / 100));
}
}
@@ -12628,7 +12720,7 @@ INT16 GetSnowCamoBonus( OBJECTTYPE * pObj )
bonus = (Item[pObj->usItem].snowCamobonus);// * (WEAPON_STATUS_MOD((*pObj)[0]->data.objectStatus) / 100)) ;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (!ItemIsCamoKit(iter->usItem) && iter->exists())
if ( iter->exists() && !ItemIsCamoKit(iter->usItem) )
bonus += (INT16) (Item[iter->usItem].snowCamobonus);// * (WEAPON_STATUS_MOD((*iter)[0]->data.objectStatus) / 100));
}
}
@@ -13073,7 +13165,7 @@ OBJECTTYPE* FindNightGogglesInInv( SOLDIERTYPE * pSoldier, INT8 * bSlot, BOOLEAN
if (searchAllInventory) {
for (UINT8 loop = 0; loop < pSoldier->inv[bLoop].ubNumberOfObjects; loop ++){
for (attachmentList::iterator iter = pSoldier->inv[bLoop][loop]->attachments.begin(); iter != pSoldier->inv[bLoop][loop]->attachments.end(); ++iter) {
if ( Item[ iter->usItem ].cavevisionrangebonus > bonusToBeat && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists() ) {
if ( iter->exists() && Item[ iter->usItem ].cavevisionrangebonus > bonusToBeat && Item[ iter->usItem ].usItemClass == IC_FACE ) {
pGoggles = &(*iter);
*bSlot = bLoop;
*isAttach = TRUE;
@@ -13131,7 +13223,7 @@ INT16 GetMinRangeForAimBonus( SOLDIERTYPE* pSoldier, OBJECTTYPE * pObj )
attachmentList::iterator iterend = (*pObj)[0]->attachments.end();
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( !gGameExternalOptions.fScopeModes || !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
if ( !gGameExternalOptions.fScopeModes || (iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT )) )
bonus += Item[iter->usItem].minrangeforaimbonus;
}
}
@@ -14049,7 +14141,7 @@ INT16 GetAverageBestLaserRange( OBJECTTYPE * pObj )
}
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if (Item[iter->usItem].bestlaserrange > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].bestlaserrange > 0 )
{
numModifiers++;
bonus += (FLOAT) Item[iter->usItem].bestlaserrange;
@@ -14075,7 +14167,7 @@ INT16 GetBestLaserRange( OBJECTTYPE * pObj )
}
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if (Item[iter->usItem].bestlaserrange > range && iter->exists())
if ( iter->exists() && Item[iter->usItem].bestlaserrange > range )
{
range = Item[iter->usItem].bestlaserrange;
}
@@ -15088,7 +15180,7 @@ BOOLEAN OBJECTTYPE::TransformObject( SOLDIERTYPE * pSoldier, UINT8 ubStatusIndex
// I am the prince of copy pasta ;)
for (attachmentList::iterator iter = unattachableList.begin(); iter != unattachableList.end();)
{
if( ValidItemAttachmentSlot(&gTempObject, iter->usItem, TRUE, FALSE, ubStatusIndex ))
if( iter->exists() && ValidItemAttachmentSlot(&gTempObject, iter->usItem, TRUE, FALSE, ubStatusIndex ))
{
//This seems to be rather valid. Can't be 100% sure though.
OBJECTTYPE tempAttachment; // Madd: we must recreate the attachments because they may themselves have default inseparable attachments...
@@ -15776,7 +15868,7 @@ INT32 GetPercentRangeBonus( OBJECTTYPE * pObj )
bonus = ( bonus * ( 100 + Item[(*pObj)[0]->data.gun.usGunAmmoItem].percentrangebonus ) ) / 100;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( !ItemIsDuckbill(iter->usItem) || (ItemIsDuckbill(iter->usItem) && (*pObj)[0]->data.gun.ubGunAmmoType == AMMO_BUCKSHOT ))
if ( iter->exists() && !ItemIsDuckbill(iter->usItem) || (ItemIsDuckbill(iter->usItem) && (*pObj)[0]->data.gun.ubGunAmmoType == AMMO_BUCKSHOT ))
bonus = ( bonus * ( 100 + BonusReduce( Item[iter->usItem].percentrangebonus, (*iter)[0]->data.objectStatus ) ) ) / 100;
}
}
+1 -2
View File
@@ -167,7 +167,6 @@ extern BOOLEAN KeyExistsInInventory( SOLDIERTYPE *pSoldier, UINT8 ubKeyID );
extern BOOLEAN KeyExistsInKeyRing( SOLDIERTYPE *pSoldier, UINT8 ubKeyID, UINT8 * pubPos );
extern BOOLEAN SoldierHasKey( SOLDIERTYPE *pSoldier, UINT8 ubKeyID );
extern STR16 sKeyDescriptionStrings[];
/**********************************
* Door utils add by Kris Morness *
**********************************/
@@ -281,4 +280,4 @@ void AttachStringToDoor( INT32 sGridNo );
void DropKeysInKeyRing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, INT8 bVisible, BOOLEAN fAddToDropList, INT32 iDropListSlot, BOOLEAN fUseUnLoaded );
#endif
#endif
+1 -1
View File
@@ -171,7 +171,7 @@ INT32 GetSpreadPattern( OBJECTTYPE * pObj )
//If there are attachments, check them. Stop on the first one with something defined.
//Dear God, I hate C++ iterators. What a fugly mess. //WarmSteel - I made it even messier ;3
for (attachmentList::iterator iter = pObj[0][0]->attachments.begin(); iter != pObj[0][0]->attachments.end(); ++iter){
if( (n=Item[ iter->usItem ].spreadPattern) && iter->exists()){
if( iter->exists() && (n=Item[ iter->usItem ].spreadPattern) ){
//An attachment has it, and it trumps everything, so return it's value.
return n;}
}
+1 -1
View File
@@ -106,7 +106,7 @@ namespace LogicalBodyTypes {
data->filter = FilterDB::Instance().FindFilter(aFilter);
if (data->filter == NULL) throw XMLParseException("Unknown filter specified!", name, data->pParser);
}
if (aPalette != NULL && strcmp(aFilter, "") != 0 && strcmp(aFilter, "default") != 0) {
if (aPalette != NULL && strcmp(aPalette, "") != 0 && strcmp(aPalette, "default") != 0) {
data->paletteTable = PaletteDB::Instance().FindPaletteTable(aPalette);
if (data->paletteTable == NULL) throw XMLParseException("Unknown palette specified!", name, data->pParser);
}
+1
View File
@@ -20,6 +20,7 @@ FLOAT gdMajorMapVersion = MAJOR_MAP_VERSION;
BOOLEAN gfWorldLoaded;
MAPCREATE_STRUCT gMapInformation;
MAPCREATE_STRUCT gMapInformationAutoResolve;
//CHRISL: MINOR_MAP_VERSION information moved to worlddef.h by ADB. We're using these values elsewhere and need them
// in the header file
+1
View File
@@ -57,6 +57,7 @@ public:
};
extern MAPCREATE_STRUCT gMapInformation;
extern MAPCREATE_STRUCT gMapInformationAutoResolve;
void LoadMapInformation(INT8** hBuffer, FLOAT dMajorMapVersion);
void SaveMapInformation(HWFILE hFile, FLOAT dMajorMapVersion, UINT8 ubMinorMapVersion);
+2 -2
View File
@@ -6909,7 +6909,7 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen )
for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
{
pTeamSoldier = MercSlots[ cnt ];
if ( pTeamSoldier && pTeamSoldier->stats.bLife >= OKLIFE && !pTeamSoldier->aiData.bNeutral )
if ( pTeamSoldier && pTeamSoldier->stats.bLife >= OKLIFE && !pTeamSoldier->aiData.bNeutral && !(pTeamSoldier->usSoldierFlagMask & SOLDIER_POW) )
{
if ( SoldierHasSeenEnemiesLastFewTurns( pTeamSoldier ) )
{
@@ -11403,7 +11403,7 @@ void TeamDropAll(UINT8 bTeam, BOOLEAN fForce)
// if soldier is in the current sector, drop all equipment (that has the TAKEN_BY_MILITIA-flag set)
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
{
pSoldier->DropSectorEquipment();
pSoldier->DropSectorEquipment( NOWHERE );
}
}
}
+1 -1
View File
@@ -1380,7 +1380,7 @@ INT16 AStarPathfinder::CalcAP(int const terrainCost, UINT8 const direction)
}
// Flugente: dragging someone
if ( pSoldier->IsDragging( false ) )
if ( pSoldier->IsDragging() )
{
movementAPCost *= gItemSettings.fDragAPCostModifier;
}
+9 -7
View File
@@ -713,6 +713,10 @@ void RemoveCorpse( INT32 iCorpseID )
DeleteAniTile( gRottingCorpse[ iCorpseID ].pAniTile );
FreeCorpsePalettes( &( gRottingCorpse[ iCorpseID ] ) );
const auto sGridNo = gRottingCorpse[iCorpseID].def.sGridNo;
auto pStructure = FindLastStructure(sGridNo, STRUCTURE_CORPSE);
DeleteStructureFromWorld(pStructure);
}
BOOLEAN CreateCorpsePalette( ROTTING_CORPSE *pCorpse )
@@ -1062,7 +1066,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
DropKeysInKeyRing( pSoldier, pSoldier->sGridNo, pSoldier->pathing.bLevel, bVisible, FALSE, 0, FALSE );
// Flugente: even if we forbid militia from dropping their equipment, they will still drop what they took via sector inventory (this functions only drops what they took)
pSoldier->DropSectorEquipment();
pSoldier->DropSectorEquipment( NOWHERE );
}
// Make team look for items
@@ -1108,7 +1112,8 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
iCorpseID = AddRottingCorpse( &Corpse );
// If this is our guy......make visible...
if ( iCorpseID != -1 && pSoldier->bTeam == OUR_TEAM || gbPublicOpplist[OUR_TEAM][pSoldier->ubID] == SEEN_CURRENTLY )
//if ( pSoldier->bTeam == gbPlayerNum )
if ( iCorpseID != -1 )
{
MakeCorpseVisible( pSoldier, &( gRottingCorpse[ iCorpseID ] ) );
}
@@ -1770,10 +1775,10 @@ BOOLEAN IsValidDecapitationCorpse( ROTTING_CORPSE *pCorpse )
ROTTING_CORPSE *GetCorpseAtGridNo( INT32 sGridNo, INT8 bLevel )
{
STRUCTURE *pStructure, *pBaseStructure;
STRUCTURE *pStructure, *pBaseStructure;
INT32 sBaseGridNo;
pStructure = FindStructure( sGridNo, STRUCTURE_CORPSE );
pStructure = FindLastStructure( sGridNo, STRUCTURE_CORPSE );
if ( pStructure != NULL )
{
@@ -2535,9 +2540,6 @@ void LookForAndMayCommentOnSeeingCorpse( SOLDIERTYPE *pSoldier, INT32 sGridNo, U
return;
}
if (pCorpse->fActivated && pCorpse->def.bVisible != 1)
pCorpse->def.bVisible = 1;
if ( pCorpse->def.ubType != ROTTING_STAGE2 )
{
return;
+1 -1
View File
@@ -3031,7 +3031,7 @@ BOOLEAN RepairIsDone(DEALER_SPECIAL_ITEM* pSpecial)
// max condition of all permanent attachments on it
for (attachmentList::iterator iter = RepairItem.ItemObject[0]->attachments.begin(); iter != RepairItem.ItemObject[0]->attachments.end(); ++iter) {
if ( CanDealerRepairItem( gbSelectedArmsDealerID, iter->usItem ) && iter->exists())
if ( iter->exists() && CanDealerRepairItem( gbSelectedArmsDealerID, iter->usItem ) )
{
// fix it up
(*iter)[0]->data.objectStatus = 100;
+6 -6
View File
@@ -9046,7 +9046,7 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier
}
// Flugente: drag people
if ( pSoldier->IsDragging( false ) )
if ( pSoldier->IsDragging() )
{
pSoldier->sAniDelay = gItemSettings.fDragAPCostModifier * pSoldier->sAniDelay;
}
@@ -11516,7 +11516,7 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR
// Flugente: as we move a tile, we would now be too far away to drag someone.
// So remember whether we were dragging (we have to set our position now, otherwise the person we drag woul soon occupy our gridno).
BOOLEAN currentlydragging = this->IsDragging();
BOOLEAN currentlydragging = this->IsDragging(true);
INT32 sOldGridNo = this->sGridNo;
// OK, set new position
@@ -14668,7 +14668,7 @@ void SOLDIERTYPE::SoldierInventoryCoolDown( void )
attachmentList::iterator iterend = (*pObj)[0]->attachments.end( );
for ( attachmentList::iterator iter = (*pObj)[0]->attachments.begin( ); iter != iterend; ++iter )
{
if ( Item[iter->usItem].usFlashLightRange )
if ( iter->exists() && Item[iter->usItem].usFlashLightRange )
flashlightfound = TRUE;
}
}
@@ -16818,7 +16818,7 @@ BOOLEAN SOLDIERTYPE::UpdateMultiTurnAction( )
return TRUE;
}
void SOLDIERTYPE::DropSectorEquipment( )
void SOLDIERTYPE::DropSectorEquipment( INT32 UnloadedSectorGridNo)
{
// not if we already dropped the gear
if ( this->usSoldierFlagMask & SOLDIER_EQUIPMENT_DROPPED )
@@ -16887,7 +16887,7 @@ void SOLDIERTYPE::DropSectorEquipment( )
}
}
AddItemsToUnLoadedSector( this->sSectorX, this->sSectorY, this->bSectorZ, RandomGridNo( ), counter, pObject, 0, WORLD_ITEM_REACHABLE, 0, 1, FALSE );
AddItemsToUnLoadedSector( this->sSectorX, this->sSectorY, this->bSectorZ, UnloadedSectorGridNo, counter, pObject, 0, WORLD_ITEM_REACHABLE, 0, 1, FALSE );
}
}
@@ -24226,7 +24226,7 @@ BOOLEAN SOLDIERTYPE::CanBreakWindow(void)
BOOLEAN SOLDIERTYPE::CanStartDrag(void)
{
if (!this->IsDragging(false) && this->CanDragInPrinciple())
if (!this->IsDragging() && this->CanDragInPrinciple())
{
INT32 sNewGridNo = NewGridNo(this->sGridNo, DirectionInc(this->ubDirection));
+2 -2
View File
@@ -1916,7 +1916,7 @@ public:
void CancelMultiTurnAction(BOOLEAN fFinished);
BOOLEAN UpdateMultiTurnAction();
void DropSectorEquipment();
void DropSectorEquipment( INT32 UnloadedSectorGridNo);
// sevenfm: Take new bomb with id = usItem from iventory to HANDPOS
void TakeNewBombFromInventory(UINT16 usItem);
@@ -2056,7 +2056,7 @@ public:
BOOLEAN CanDragPerson(SoldierID usID, BOOLEAN fCheckStance = FALSE);
BOOLEAN CanDragCorpse(UINT16 usCorpseNum, BOOLEAN fCheckStance = FALSE);
BOOLEAN CanDragStructure(INT32 sGridNo, BOOLEAN fCheckStance = FALSE);
BOOLEAN IsDragging(bool aStopIfConditionNotSatisfied = true);
BOOLEAN IsDragging(bool aStopIfConditionNotSatisfied = false);
void SetDragOrderPerson( SoldierID usID );
void SetDragOrderCorpse( UINT32 uiCorpseID );
void SetDragOrderStructure( INT32 sGridNo );
+1 -1
View File
@@ -147,7 +147,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
{
OBJECTTYPE* pObject = &(gusSelectedSoldier->inv[HANDPOS]);
for (attachmentList::iterator iter = (*pObject)[0]->attachments.begin(); iter != (*pObject)[0]->attachments.end(); ++iter) {
if ( Item[iter->usItem].visionrangebonus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].visionrangebonus > 0 )
{
fMercIsUsingScope = TRUE;
break;
+17 -13
View File
@@ -2221,7 +2221,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
// sevenfm: also stop dragging
if (gusSelectedSoldier != NOBODY &&
gusSelectedSoldier &&
gusSelectedSoldier->IsDragging(false))
gusSelectedSoldier->IsDragging())
{
gusSelectedSoldier->CancelDrag();
DirtyMercPanelInterface(gusSelectedSoldier, DIRTYLEVEL2);
@@ -4303,21 +4303,25 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
// Make auto reload with magazines from sector inventory
case 'R':
HandleTBReloadAll();
if (fAlt && gusSelectedSoldier != NOBODY ) // Greysa: Moved here from 'r' to retain all functionality during testing.
{
if (CHEATER_CHEAT_LEVEL())
{
ReloadWeapon(gusSelectedSoldier, gusSelectedSoldier->ubAttackingHand);
}
}
else
{
HandleTBReloadAll();
}
break;
case 'r':
if( gusSelectedSoldier != NOBODY )
{
if( fAlt ) //reload selected merc's weapon
if( fAlt )
{
if ( CHEATER_CHEAT_LEVEL( ) )
{
ReloadWeapon( gusSelectedSoldier, gusSelectedSoldier->ubAttackingHand );
}
else
HandleTBReload();
}
HandleTBReload();
}
else if( fCtrl )
{
if ( INFORMATION_CHEAT_LEVEL( ) )
@@ -6766,7 +6770,7 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
if ( iter->exists() && Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
@@ -6814,7 +6818,7 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
if ( iter->exists() && Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus;
+1 -1
View File
@@ -2081,7 +2081,7 @@ UINT8 HandleNonActivatedTossCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEA
//sevenfm this should be checked only for guns because we can throw items with attached explosives
if(Item[pObj->usItem].usItemClass & IC_WEAPON )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV && iter->exists())
if ( iter->exists() && Item[ iter->usItem ].usItemClass & IC_EXPLOSV )
{
pObject = &(*iter);
break;
+12 -12
View File
@@ -1036,7 +1036,7 @@ INT32 EffectiveArmour( OBJECTTYPE * pObj )
iValue = iValue * (*pObj)[0]->data.objectStatus * Armour[ Item[pObj->usItem].ubClassIndex ].ubCoverage / 10000;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
INT32 iValue2;
@@ -1062,7 +1062,7 @@ INT32 EffectiveArmourLBE( OBJECTTYPE * pObj )
iValue = 0;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
INT32 iValue2;
@@ -1088,7 +1088,7 @@ INT32 ExplosiveEffectiveArmourLBE( OBJECTTYPE * pObj )
iValue = 0;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
INT32 iValue2;
@@ -1214,7 +1214,7 @@ INT32 ExplosiveEffectiveArmour( OBJECTTYPE * pObj )
}
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
INT32 iValue2;
@@ -1295,7 +1295,7 @@ INT16 FireEffectiveArmour( OBJECTTYPE * pObj )
for ( attachmentList::iterator iter = ( *pObj )[0]->attachments.begin(); iter != ( *pObj )[0]->attachments.end(); ++iter )
{
if ( Item[iter->usItem].usItemClass == IC_ARMOUR && ( *iter )[0]->data.objectStatus > 0 && iter->exists() )
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && ( *iter )[0]->data.objectStatus > 0 )
{
iValue += Item[iter->usItem].sFireResistance * ( *iter )[0]->data.objectStatus / 100;
}
@@ -2560,7 +2560,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
for (attachmentList::iterator iter = (*pObjAttHand)[0]->attachments.begin(); iter != (*pObjAttHand)[0]->attachments.end(); ++iter)
{
if (ItemHasHiddenMuzzleFlash(iter->usItem))
if ( iter->exists() && ItemHasHiddenMuzzleFlash(iter->usItem))
{
OBJECTTYPE* pA= &(*iter);
if ( (*pA)[0]->data.objectStatus >=USABLE)
@@ -3346,7 +3346,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
for (attachmentList::iterator iter = (*pObjUsed)[0]->attachments.begin(); iter != (*pObjUsed)[0]->attachments.end(); ++iter)
{
if (ItemHasHiddenMuzzleFlash(iter->usItem))
if ( iter->exists() && ItemHasHiddenMuzzleFlash(iter->usItem))
{
OBJECTTYPE* pA= &(*iter);
if ( (*pA)[0]->data.objectStatus >=USABLE)
@@ -4233,7 +4233,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// give bonus for surprise, but not so much as struggle would still occur
iHitChance = CalcChanceToSteal( pSoldier, pTargetSoldier, pSoldier->aiData.bAimTime ) + 20;
}
else if ( pTargetSoldier->stats.bLife < OKLIFE || pTargetSoldier->bCollapsed )
else if (pTargetSoldier->stats.bLife < OKLIFE || pTargetSoldier->bCollapsed || pTargetSoldier->usSoldierFlagMask & SOLDIER_POW)
{
iHitChance = 100;
fSoldierCollapsed = TRUE;
@@ -5111,7 +5111,7 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
pObj = &(pSoldier->inv[HANDPOS]);
attachmentList::iterator iter;
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV && iter->exists())
if ( iter->exists() && Item[ iter->usItem ].usItemClass & IC_EXPLOSV )
{
break;
}
@@ -7993,7 +7993,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
if (iSlot == VESTPOS && pVestPack->exists() == true)
{
for (attachmentList::iterator iter = (*pVestPack)[0]->attachments.begin(); iter != (*pVestPack)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
INT32 protection = ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
@@ -8025,7 +8025,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
if (pArmour->exists() == true)
{
for (attachmentList::iterator iter = (*pArmour)[0]->attachments.begin(); iter != (*pArmour)[0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
// bullet got through jacket; apply ceramic plate armour
INT32 protection = ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
@@ -8071,7 +8071,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
{
//Madd: put any attachments that someone might have added to the armour in the merc's inventory
for (attachmentList::iterator iter = (*pArmour)[0]->attachments.begin(); iter != (*pArmour)[0]->attachments.end(); ++iter) {
if ( !AutoPlaceObject( pTarget, &(*iter), FALSE ) && iter->exists())
if ( iter->exists() && !AutoPlaceObject( pTarget, &(*iter), FALSE ) )
{ // put it on the ground
AddItemToPool( pTarget->sGridNo, &(*iter), 1, pTarget->pathing.bLevel, 0 , -1 );
}
+1 -1
View File
@@ -1180,7 +1180,7 @@ profileEndElementHandle(void *userData, const XML_Char *name)
#include <vfs/Core/vfs_file_raii.h> // added by Flugente for vfs-stuff
#include <iostream>
extern STR16 gzMercSkillTextNew[];
extern STR16* gzMercSkillTextNew;
void AnalyzeProfiles()
{
+1 -1
View File
@@ -2207,7 +2207,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 ub
// check for ceramic plates; these do affect monster spit
for (attachmentList::iterator iter = pOpponent->inv[VESTPOS][0]->attachments.begin(); iter != pOpponent->inv[VESTPOS][0]->attachments.end(); ++iter) {
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists() )
if ( iter->exists() && Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
{
iTorsoProt += (INT32) Armour[Item[iter->usItem].ubClassIndex].ubProtection *
(INT32) (*iter)[0]->data.objectStatus / 100;
-5
View File
@@ -38,9 +38,6 @@
typedef struct
{
//SB: unify structure for all versions
// #if defined( CRIPPLED_VERSION ) || defined( RUSSIAN )
// UINT8 ubIdentifier[4];
// #endif
UINT16 fFlags;
@@ -74,9 +71,7 @@ typedef struct
INT16 sActionData; // special action value
//SB: unify structure for all versions
//#if !defined( CRIPPLED_VERSION ) && !defined( RUSSIAN )
UINT8 ubUnused[4];
//#endif
} _old_NPCQuoteInfo; // 32 bytes
+1 -1
View File
@@ -22,7 +22,7 @@ UINT32 guiFireAmbientLastUpdate = 0;
extern STR8 pVertStrings[];
extern STR8 pHortStrings[];
extern CHAR16 pTownNames[MAX_TOWNS][MAX_TOWN_NAME_LENGHT];
extern CHAR16 (*pTownNames)[MAX_TOWN_NAME_LENGHT];
UINT8 gubCurrentSteadyStateAmbience = SSA_NONE;
UINT8 gubCurrentSteadyStateSound = 0;
+64 -1
View File
@@ -1319,7 +1319,7 @@ BOOLEAN FindFenceJumpDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStar
return( FALSE );
}
//Simply chooses a random gridno within valid boundaries (for dropping things in unloaded sectors)
//Simply chooses a random gridno within valid boundaries (for dropping things in loaded sectors)
INT32 RandomGridNo()
{
INT32 iMapXPos, iMapYPos, iMapIndex;
@@ -1332,6 +1332,69 @@ INT32 RandomGridNo()
return iMapIndex;
}
static bool pointLeftOfEdge(INT32 xp, INT32 yp, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
{
//Test whether the point(xp, yp) lies on the left-hand side of the edge(x1, y1) - (x2, y2)
const auto D = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1);
return (D > 0);
}
INT32 RandomGridNoUnloadedSector(INT32 worldRows, INT32 worldCols)
{
INT32 iMapIndex;
const auto centerHeight = gpWorldLevelDataAutoResolve[gMapInformationAutoResolve.sCenterGridNo].sHeight;
const auto CenterWorldX = (WORLD_ROWS) / 2 * CELL_X_SIZE;
const auto CenterWorldY = (WORLD_COLS) / 2 * CELL_Y_SIZE;
// Sector corners are shifted inwards a bit to limit the area to be slightly smaller than actual sector.
// It fixed a few annyoing edge cases where a tile would evaluate to being inside the map, but it was juuust out of reach in actual gameplay
const auto TLX = 2*CELL_X_SIZE; // Shift X-coordinate by one tile inwards from actual edge.
const auto TLY = (WORLD_ROWS / 2) * CELL_X_SIZE;
const auto TRX = (WORLD_COLS / 2) * CELL_Y_SIZE;
const auto TRY = 2*CELL_X_SIZE; // Shift Y-coordinate by one tile inwards from actual edge
const auto BLX = ((WORLD_COLS / 2) * CELL_Y_SIZE);
const auto BLY = ((WORLD_ROWS-1) * CELL_Y_SIZE); // Shift Y-coordinate by one row inwards from actual edge
const auto BRX = ((WORLD_COLS-1) * CELL_Y_SIZE); // Shift X-coordinate by one row inwards from actual edge
const auto BRY = ((WORLD_ROWS / 2) * CELL_X_SIZE);
UINT8 randomGridHeight = 255;
do
{
randomGridHeight = 255; // Reset height to be tested
INT32 iMapXPos = Random(worldCols);
INT32 iMapYPos = Random(worldRows);
iMapIndex = iMapYPos * worldCols + iMapXPos;
// Discard gridno that is not within map bounds.
// Check point against world area's edges. If any edge test fails, it means point is not inside.
// Edge traverals goes counterclockwise, Top Right -> Top Left -> Bottom Left -> Bottom Right -> Top Right
const auto pX = iMapXPos * CELL_X_SIZE;
const auto pY = iMapYPos * CELL_Y_SIZE;
//TR->TL
if ( !pointLeftOfEdge(pX, pY, TLX, TLY, TRX, TRY) )
continue;
//TL->BL
if ( !pointLeftOfEdge(pX, pY, BLX, BLY, TLX, TLY) )
continue;
//BL->BR
if ( !pointLeftOfEdge(pX, pY, BRX, BRY, BLX, BLY) )
continue;
//BR->TR
if ( !pointLeftOfEdge(pX, pY, TRX, TRY, BRX, BRY) )
continue;
// Compare randomGridHeight with height of the center grid of the map, as long as the center of the map is on walkable height it will work properly
randomGridHeight = gpWorldLevelDataAutoResolve[iMapIndex].sHeight;
} while ( !(randomGridHeight == centerHeight) );
return iMapIndex;
}
// Flugente: is this gridno near a player merc?
BOOLEAN GridNoNearPlayerMercs( INT32 sGridNo, INT16 sRadius )
{
+1
View File
@@ -113,6 +113,7 @@ BOOLEAN FindFenceJumpDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStar
//Simply chooses a random gridno within valid boundaries (for dropping things in unloaded sectors)
INT32 RandomGridNo();
INT32 RandomGridNoUnloadedSector(INT32 worldRows, INT32 worldCols);
extern UINT32 guiForceRefreshMousePositionCalculation;
+22 -9
View File
@@ -8518,8 +8518,7 @@ void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
gsStartPointY_W = sRenderCenterY_W - sTempPosY_W;
// NOTE: Increase X map value by 1 tile to offset where on screen we are...
if ( gsStartPointX_W > 0 )
gsStartPointX_W += CELL_X_SIZE;
gsStartPointX_W += CELL_X_SIZE;
// d) screen start point is screen distances minus screen center
gsStartPointX_S = sLeft - VIEWPORT_XOFFSET_S;
@@ -8527,8 +8526,8 @@ void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
// STEP FOUR - Determine Start block
// a) Find start block
gsStartPointX_M = ( gsStartPointX_W ) / CELL_X_SIZE;
gsStartPointY_M = ( gsStartPointY_W ) / CELL_Y_SIZE;
gsStartPointX_M = floor( DOUBLE(gsStartPointX_W) / DOUBLE(CELL_X_SIZE) );
gsStartPointY_M = floor( DOUBLE(gsStartPointY_W) / DOUBLE(CELL_Y_SIZE) );
// STEP 5 - Determine Deltas for center and find screen values
//Make sure these coordinates are multiples of scroll steps
@@ -8564,7 +8563,7 @@ void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
gsLEndXS = sRight + LARGER_VIEWPORT_XOFFSET_S;
gsLEndYS = sBottom + LARGER_VIEWPORT_YOFFSET_S;
// STEP THREE - determine starting point in world coords
// STEP THREE - determine starting point in world coords
// a) Determine where in screen coords to start rendering
gsLStartPointX_S = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) - (sLeft - LARGER_VIEWPORT_XOFFSET_S);
gsLStartPointY_S = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) - (sTop - LARGER_VIEWPORT_YOFFSET_S);
@@ -8578,8 +8577,7 @@ void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
gsLStartPointY_W = sRenderCenterY_W - sTempPosY_W;
// NOTE: Increase X map value by 1 tile to offset where on screen we are...
if ( gsLStartPointX_W > 0 )
gsLStartPointX_W += CELL_X_SIZE;
gsLStartPointX_W += CELL_X_SIZE;
// d) screen start point is screen distances minus screen center
gsLStartPointX_S = sLeft - LARGER_VIEWPORT_XOFFSET_S;
@@ -8587,8 +8585,23 @@ void CalcRenderParameters(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
// STEP FOUR - Determine Start block
// a) Find start block
gsLStartPointX_M = ( gsLStartPointX_W ) / CELL_X_SIZE;
gsLStartPointY_M = ( gsLStartPointY_W ) / CELL_Y_SIZE;
gsLStartPointX_M = floor( DOUBLE(gsLStartPointX_W) / DOUBLE(CELL_X_SIZE) );
gsLStartPointY_M = floor( DOUBLE(gsLStartPointY_W) / DOUBLE(CELL_Y_SIZE) );
// Check and correct the difference between smaller and larger start blocks in tile coordinates.
// Regardless of resolution, the difference between the start blocks are constant 10 tiles in X- and 6 tiles in Y-direction.
// If the difference doesn't match, static world is rendered in the wrong place relative to dynamic world.
// Mainly evident in 960x540 resolution.
const auto ratioX_M = gsStartPointX_M - gsLStartPointX_M;
if ( ratioX_M != 10)
{
gsLStartPointX_M -= 10 - ratioX_M;
}
const auto ratioY_M = gsStartPointY_M - gsLStartPointY_M;
if ( ratioY_M != 6 )
{
gsLStartPointY_M -= 6 - ratioY_M;
}
// Adjust starting screen coordinates
gsLStartPointX_S -= sOffsetX_S;
+28
View File
@@ -1428,6 +1428,7 @@ STRUCTURE * SwapStructureForPartnerForcingGraphicalChange( INT32 sGridNo, STRUCT
}
#endif
// Finds the first structure with matching flag
STRUCTURE * FindStructure( INT32 sGridNo, UINT32 fFlags )
{
// finds a structure that matches any of the given flags
@@ -1451,6 +1452,33 @@ STRUCTURE * FindStructure( INT32 sGridNo, UINT32 fFlags )
return( NULL );
}
// Finds the last structure with matching flag
STRUCTURE* FindLastStructure(INT32 sGridNo, UINT32 fFlags)
{
// finds a structure that matches any of the given flags
STRUCTURE* pCurrent;
STRUCTURE* pLastMatch = nullptr;
//bug fix for win98 crash when traveling between sectors
if ( TileIsOutOfBounds(sGridNo) )
{
return(NULL);
}
pCurrent = gpWorldLevelData[sGridNo].pStructureHead;
while ( pCurrent != NULL )
{
if ( (pCurrent->fFlags & fFlags) != 0 )
{
pLastMatch = pCurrent;
//return(pCurrent);
}
pCurrent = pCurrent->pNext;
}
return(pLastMatch);
}
STRUCTURE * FindNextStructure( STRUCTURE * pStructure, UINT32 fFlags )
{
STRUCTURE * pCurrent;
+1
View File
@@ -47,6 +47,7 @@ BOOLEAN DeleteStructureFromWorld( STRUCTURE * pStructure );
// functions to find a structure in a location
//
STRUCTURE * FindStructure( INT32 sGridNo, UINT32 fFlags );
STRUCTURE* FindLastStructure(INT32 sGridNo, UINT32 fFlags);
STRUCTURE * FindNextStructure( STRUCTURE * pStructure, UINT32 fFlags );
STRUCTURE * FindStructureByID( INT32 sGridNo, UINT16 usStructureID );
STRUCTURE * FindBaseStructure( STRUCTURE * pStructure );
+292 -1
View File
@@ -138,7 +138,8 @@ void SaveMapLights( HWFILE hfile );
void LoadMapLights( INT8 **hBuffer );
// Global Variables
MAP_ELEMENT *gpWorldLevelData;
MAP_ELEMENT* gpWorldLevelData;
MAP_ELEMENT *gpWorldLevelDataAutoResolve;
INT32 *gpDirtyData;
UINT32 gSurfaceMemUsage;
//UINT8 gubWorldMovementCosts[ WORLD_MAX ][MAXDIR][2];
@@ -3312,6 +3313,296 @@ BOOLEAN LoadWorld(const STR8 puiFilename, FLOAT* pMajorMapVersion, UINT8* pMinor
return(TRUE);
}
// A stub LoadWorld function so we can read a sector's tile height values into gpWorldLevelDataAutoResolve[].sHeight and entrypoint gridnos into gMapInformationAutoResolve
// They are needed when placing corpses and dropped items into a random gridno in an unloaded sector when we're finished with autoresolve battle.
BOOLEAN LoadWorldInfoForAutoResolve(const STR8 puiFilename, INT32& iRowSize, INT32& iColSize)
{
HWFILE hfile;
FLOAT dMajorMapVersion;
UINT8 ubMinorMapVersion;
UINT32 uiFlags;
UINT32 uiBytesRead;
UINT32 uiFileSize;
INT32 i, cnt, cnt2;
UINT8 ubType;
CHAR8 aFilename[2 * FILENAME_BUFLEN];
UINT8 ubCombine;
UINT8(*bCounts)[8] = NULL;
INT8* pBuffer;
INT8* pBufferHead;
// Append exension to filename!
if ( gfForceLoad )
sprintf(aFilename, "MAPS\\%s", gzForceLoadFile);
else
sprintf(aFilename, "MAPS\\%s", puiFilename);
// Open file
hfile = FileOpen(aFilename, FILE_ACCESS_READ);
if ( !hfile )
{
#ifndef JA2EDITOR
SET_ERROR("Could not load map file %S", aFilename);
#endif
return(FALSE);
}
// Get the file size and alloc one huge buffer for it. We will use this buffer to transfer all of the data from.
uiFileSize = FileGetSize(hfile);
pBuffer = (INT8*)MemAlloc(uiFileSize);
pBufferHead = pBuffer;
FileRead(hfile, pBuffer, uiFileSize, &uiBytesRead);
FileClose(hfile);
// Read JA2 Version ID
LOADDATA(&dMajorMapVersion, pBuffer, sizeof(FLOAT));
LOADDATA(&ubMinorMapVersion, pBuffer, sizeof(UINT8));
iRowSize = OLD_WORLD_ROWS;
iColSize = OLD_WORLD_COLS;
if ( dMajorMapVersion >= 7.00 )
{
LOADDATA(&iRowSize, pBuffer, sizeof(INT32));
LOADDATA(&iColSize, pBuffer, sizeof(INT32));
}
// Actual world size of the map we loaded!
INT32 iWorldSize = iRowSize * iColSize;
gMapTrn.ResizeTrnCfg(WORLD_ROWS, WORLD_COLS, iRowSize, iColSize);
// Initialize world data
if ( gpWorldLevelDataAutoResolve != NULL )
MemFree(gpWorldLevelDataAutoResolve);
gpWorldLevelDataAutoResolve = (MAP_ELEMENT*)MemAlloc(sizeof(MAP_ELEMENT) * WORLD_MAX);
memset(gpWorldLevelDataAutoResolve, 0, sizeof(MAP_ELEMENT) * WORLD_MAX);
bCounts = (UINT8(*)[8])MemAlloc(WORLD_MAX * 8);
memset(bCounts, 0, sizeof(UINT8) * WORLD_MAX * 8);
// Read FLAGS FOR WORLD
LOADDATA(&uiFlags, pBuffer, sizeof(INT32));
SKIPDATA(pBuffer, pBuffer, sizeof(INT32)); // TilesetID
// Load soldier size
SKIPDATA(pBuffer, pBuffer, sizeof(INT32));
// NOTE! We need this!
// Read height values
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
LOADDATA(&gpWorldLevelDataAutoResolve[cnt].sHeight, pBuffer, sizeof(INT16));
}
// Read layer counts
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
// Read combination of land/world flags
LOADDATA(&ubCombine, pBuffer, sizeof(UINT8));
// Split
bCounts[cnt][0] = (UINT8)(ubCombine & 0x0F);
gpWorldLevelDataAutoResolve[cnt].uiFlags |= (UINT8)((ubCombine & 0xF0) >> 4);
// Read #objects, structs
LOADDATA(&ubCombine, pBuffer, sizeof(UINT8));
// Split
bCounts[cnt][1] = (UINT8)(ubCombine & 0x0F);
bCounts[cnt][2] = (UINT8)((ubCombine & 0xF0) >> 4);
// Read shadows, roof
LOADDATA(&ubCombine, pBuffer, sizeof(UINT8));
// Split
bCounts[cnt][3] = (UINT8)(ubCombine & 0x0F);
bCounts[cnt][4] = (UINT8)((ubCombine & 0xF0) >> 4);
// Read OnRoof, nothing
LOADDATA(&ubCombine, pBuffer, sizeof(UINT8));
// Split
bCounts[cnt][5] = (UINT8)(ubCombine & 0x0F);
}
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
for ( cnt2 = 0; cnt2 < bCounts[cnt][0]; cnt2++ )
{
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
}
// New load require UINT16 for the type subindex due to the fact that ROADPIECES contain over 300 type subindices.
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
// Set objects
for ( cnt2 = 0; cnt2 < bCounts[cnt][1]; cnt2++ )
{
LOADDATA(&ubType, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT16));
if ( ubType >= FIRSTPOINTERS )
continue;
}
}
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
// Set structs
for ( cnt2 = 0; cnt2 < bCounts[cnt][2]; cnt2++ )
{
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
}
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
for ( cnt2 = 0; cnt2 < bCounts[cnt][3]; cnt2++ )
{
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
}
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
for ( cnt2 = 0; cnt2 < bCounts[cnt][4]; cnt2++ )
{
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
}
for ( i = 0; i < iWorldSize; i++ )
{
gMapTrn.GetTrnCnt(cnt = i);
for ( cnt2 = 0; cnt2 < bCounts[cnt][5]; cnt2++ )
{
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
}
// For old Russian Maps which have version 6.0
if ( dMajorMapVersion == 6.00 && ubMinorMapVersion < 27 )
{
UINT32 uiNums[37];
LOADDATA(uiNums, pBuffer, sizeof(INT32) * 37);
dMajorMapVersion = 5.00;
}
// For new maps
else if ( dMajorMapVersion == 6.00 && ubMinorMapVersion < 27 && MAJOR_MAP_VERSION == 6.00 )
{
UINT32 uiNums[37];
LOADDATA(uiNums, pBuffer, sizeof(UINT32) * 37);
}
//now the data is discarded and when saved, as 6.27, you won't have this problem!
for ( i = 0; i < iWorldSize; i++ ) {
// Read room information, 2 byte for new files
if ( ubMinorMapVersion < 29 ) {
SKIPDATA(pBuffer, pBuffer, sizeof(INT8));
}
else {
SKIPDATA(pBuffer, pBuffer, sizeof(UINT16));
}
}
// Load out item information
if ( uiFlags & MAP_WORLDITEMS_SAVED )
{
WORLDITEM dummyItem;
UINT32 uiNumWorldItems;
//Read the number of items that were saved in the map.
LOADDATA(&uiNumWorldItems, pBuffer, 4);
if ( gTacticalStatus.uiFlags & LOADING_SAVED_GAME && !gfEditMode )
{ //The sector has already been visited. The items are saved in a different format that will be
//loaded later on. So, all we need to do is skip the data entirely.
if ( dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 ) {
for ( unsigned int x = 0; x < uiNumWorldItems; ++x )
{
//ADB WORLDITEM's size on disk is unknown
dummyItem.Load(&pBuffer, dMajorMapVersion, ubMinorMapVersion);
}
}
else
{
pBuffer += sizeof(OLD_WORLDITEM_101) * uiNumWorldItems;
}
}
else for ( i = 0; i < uiNumWorldItems; i++ )
{
dummyItem.Load(&pBuffer, dMajorMapVersion, ubMinorMapVersion);
}
}
if ( uiFlags & MAP_AMBIENTLIGHTLEVEL_SAVED )
{
//Ambient light levels are only saved in underground levels
SKIPDATA(pBuffer, pBuffer, sizeof(BOOLEAN));
SKIPDATA(pBuffer, pBuffer, sizeof(BOOLEAN));
SKIPDATA(pBuffer, pBuffer, sizeof(UINT8));
}
if ( uiFlags & MAP_WORLDLIGHTS_SAVED )
{
SGPPaletteEntry LColors[3];
UINT8 ubNumColors;
UINT16 usNumLights;
CHAR8 str[30];
UINT8 ubStrLen;
LIGHT_SPRITE TmpLight;
// read in the light colors!
LOADDATA(&ubNumColors, pBuffer, 1);
LOADDATA(LColors, pBuffer, sizeof(SGPPaletteEntry) * ubNumColors);
LOADDATA(&usNumLights, pBuffer, 2);
for ( cnt = 0; cnt < usNumLights; cnt++ )
{
LOADDATA(&TmpLight, pBuffer, sizeof(LIGHT_SPRITE));
LOADDATA(&ubStrLen, pBuffer, 1);
if ( ubStrLen )
{
LOADDATA(str, pBuffer, ubStrLen);
}
}
}
gMapInformationAutoResolve.Load(&pBuffer, dMajorMapVersion);
// NOTE! We need these!
// Translation routine for map grid numbers
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sCenterGridNo);
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sIsolatedGridNo);
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sNorthGridNo);
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sEastGridNo);
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sWestGridNo);
gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sSouthGridNo);
// Remove this rather large chunk of memory from the system now!
MemFree(pBufferHead);
MemFree(bCounts);
return(TRUE);
}
//****************************************************************************************
//
// Deletes everything then re-creates the world with simple ground tiles
+2
View File
@@ -281,6 +281,7 @@ typedef struct
// World Data
extern MAP_ELEMENT *gpWorldLevelData;
extern MAP_ELEMENT* gpWorldLevelDataAutoResolve;
extern UINT8 (*gubWorldMovementCosts)[MAXDIR][2];//dnl ch43 260909
//dnl ch44 290909 Translation routine
@@ -339,6 +340,7 @@ BOOLEAN NewWorld( INT32 nMapRows, INT32 nMapCols );
BOOLEAN SaveWorld(const STR8 puiFilename, FLOAT dMajorMapVersion=MAJOR_MAP_VERSION, UINT8 ubMinorMapVersion=MINOR_MAP_VERSION);//dnl ch33 150909
BOOLEAN LoadWorld(const STR8 puiFilename, FLOAT* pMajorMapVersion=NULL, UINT8* pMinorMapVersion=NULL);//dnl ch44 290909
BOOLEAN LoadWorldInfoForAutoResolve(const STR8 puiFilename, INT32& iRowSize, INT32& iColSize);
void CompileWorldMovementCosts(void);//dnl ch56 151009
void RecompileLocalMovementCosts( INT32 sCentreGridNo );
-2
View File
@@ -8,10 +8,8 @@ set(UtilsSrc
"${CMAKE_CURRENT_SOURCE_DIR}/Encrypted File.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Event Pump.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Font Control.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ImportStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/INIReader.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/KeyMap.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LocalizedStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MapUtility.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MercTextBox.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/message.cpp"
-132
View File
@@ -96,137 +96,5 @@ void DecodeString(STR16 pDestString, UINT32 uiSeekAmount)
if( pDestString[i] > 33 )
pDestString[i] -= 1;
//#ifdef GERMAN
// //switch( pDestString[ i ] )
// //{
// // // ü
// // case 252: pDestString[i] = 252; break;
// // // Ü
// // case 220: pDestString[i] = 220; break;
// // // ä
// // case 228: pDestString[i] = 228; break;
// // // Ä
// // case 196: pDestString[i] = 196; break;
// // // ö
// // case 246: pDestString[i] = 246; break;
// // // Ö
// // case 214: pDestString[i] = 214; break;
// // // ß
// // case 223: pDestString[i] = 223; break;
// //}
//#endif
//#ifdef RUSSIAN
// switch( pDestString[ i ] )
// {
// //capital letters
// case 168: pDestString[ i ] = 1025; break; //U+0401 d0 81 CYRILLIC CAPITAL LETTER IO
// case 192: pDestString[ i ] = 1040; break; //U+0410 A d0 90 CYRILLIC CAPITAL LETTER A
// case 193: pDestString[ i ] = 1041; break;
// case 194: pDestString[ i ] = 1042; break;
// case 195: pDestString[ i ] = 1043; break;
// case 196: pDestString[ i ] = 1044; break;
// case 197: pDestString[ i ] = 1045; break;
// case 198: pDestString[ i ] = 1046; break;
// case 199: pDestString[ i ] = 1047; break;
// case 200: pDestString[ i ] = 1048; break;
// case 201: pDestString[ i ] = 1049; break;
// case 202: pDestString[ i ] = 1050; break;
// case 203: pDestString[ i ] = 1051; break;
// case 204: pDestString[ i ] = 1052; break;
// case 205: pDestString[ i ] = 1053; break;
// case 206: pDestString[ i ] = 1054; break;
// case 207: pDestString[ i ] = 1055; break;
// case 208: pDestString[ i ] = 1056; break;
// case 209: pDestString[ i ] = 1057; break;
// case 210: pDestString[ i ] = 1058; break;
// case 211: pDestString[ i ] = 1059; break;
// case 212: pDestString[ i ] = 1060; break;
// case 213: pDestString[ i ] = 1061; break;
// case 214: pDestString[ i ] = 1062; break;
// case 215: pDestString[ i ] = 1063; break;
// case 216: pDestString[ i ] = 1064; break;
// case 217: pDestString[ i ] = 1065; break;
// case 218: pDestString[ i ] = 1066; break;
// case 219: pDestString[ i ] = 1067; break;
// case 220: pDestString[ i ] = 1068; break;
// case 221: pDestString[ i ] = 1069; break;
// case 222: pDestString[ i ] = 1070; break;
// case 223: pDestString[ i ] = 1071; break; //U+042F d0 af CYRILLIC CAPITAL LETTER YA
// //small letters
// case 184: pDestString[ i ] = 1105; break; //U+0451 d1 91 CYRILLIC SMALL LETTER IO
//case 185: pDestString[ i ] = 8470; break; // ?
//case 178: pDestString[ i ] = 1030; break; // ?
//case 161: pDestString[ i ] = 1038; break; // í
//case 179: pDestString[ i ] = 1110; break; // ?
//case 162: pDestString[ i ] = 1118; break; // ó
//case 165: pDestString[ i ] = 1168; break; // Ń
//case 170: pDestString[ i ] = 1028; break; // Ź
//case 175: pDestString[ i ] = 1031; break; // ť
//case 180: pDestString[ i ] = 1169; break; // ?
//case 186: pDestString[ i ] = 1108; break; // ?
//case 191: pDestString[ i ] = 1111; break; // ?
// case 224: pDestString[ i ] = 1072; break; //U+0430 a d0 b0 CYRILLIC SMALL LETTER A
// case 225: pDestString[ i ] = 1073; break;
// case 226: pDestString[ i ] = 1074; break;
// case 227: pDestString[ i ] = 1075; break;
// case 228: pDestString[ i ] = 1076; break;
// case 229: pDestString[ i ] = 1077; break;
// case 230: pDestString[ i ] = 1078; break;
// case 231: pDestString[ i ] = 1079; break;
// case 232: pDestString[ i ] = 1080; break;
// case 233: pDestString[ i ] = 1081; break;
// case 234: pDestString[ i ] = 1082; break;
// case 235: pDestString[ i ] = 1083; break;
// case 236: pDestString[ i ] = 1084; break;
// case 237: pDestString[ i ] = 1085; break;
// case 238: pDestString[ i ] = 1086; break;
// case 239: pDestString[ i ] = 1087; break; //U+043F d0 bf CYRILLIC SMALL LETTER PE
// case 240: pDestString[ i ] = 1088; break; //U+0440 p d1 80 CYRILLIC SMALL LETTER ER
// case 241: pDestString[ i ] = 1089; break;
// case 242: pDestString[ i ] = 1090; break;
// case 243: pDestString[ i ] = 1091; break;
// case 244: pDestString[ i ] = 1092; break;
// case 245: pDestString[ i ] = 1093; break;
// case 246: pDestString[ i ] = 1094; break;
// case 247: pDestString[ i ] = 1095; break;
// case 248: pDestString[ i ] = 1096; break;
// case 249: pDestString[ i ] = 1097; break;
// case 250: pDestString[ i ] = 1098; break;
// case 251: pDestString[ i ] = 1099; break;
// case 252: pDestString[ i ] = 1100; break;
// case 253: pDestString[ i ] = 1101; break;
// case 254: pDestString[ i ] = 1102; break;
// case 255: pDestString[ i ] = 1103; break; //U+044F d1 8f CYRILLIC SMALL LETTER YA
// }
//#endif
//#ifdef POLISH
// switch( pDestString[ i ] )
// {
// case 165: pDestString[ i ] = 260; break;
// case 198: pDestString[ i ] = 262; break;
// case 202: pDestString[ i ] = 280; break;
// case 163: pDestString[ i ] = 321; break;
// case 209: pDestString[ i ] = 323; break;
// case 211: pDestString[ i ] = 211; break;
// case 338: pDestString[ i ] = 346; break;
// case 175: pDestString[ i ] = 379; break;
// case 143: pDestString[ i ] = 377; break;
// case 185: pDestString[ i ] = 261; break;
// case 230: pDestString[ i ] = 263; break;
// case 234: pDestString[ i ] = 281; break;
// case 179: pDestString[ i ] = 322; break;
// case 241: pDestString[ i ] = 324; break;
// case 243: pDestString[ i ] = 243; break;
// case 339: pDestString[ i ] = 347; break;
// case 191: pDestString[ i ] = 380; break;
// case 376: pDestString[ i ] = 378; break;
// }
//#endif
}
}
+58 -47
View File
@@ -199,7 +199,10 @@ WRAPPED_STRING *LineWrap(INT32 iFont, UINT16 usLineWidthPixels, UINT16 *pusLineW
usCurrentWidthPixels = usCurrentWidthPixels + WFStringPixLength( OneChar, iFont);
//If we are at the end of the string
if(TempString[ usCurIndex ] == 0)
//Juqi: Add NEWLINE_CHAR detect
// NEWLINE_CHAR "±" is only used to handle Chinese ITMES.XML file.
if (TempString[ usCurIndex ] == 0 && !fNewLine)
{
//get to next WrappedString structure
pWrappedString = &FirstWrappedString;
@@ -224,10 +227,13 @@ WRAPPED_STRING *LineWrap(INT32 iFont, UINT16 usLineWidthPixels, UINT16 *pusLineW
}
if( (g_lang != i18n::Lang::zh && usCurrentWidthPixels > usLineWidthPixels)
||
(g_lang == i18n::Lang::zh && usCurrentWidthPixels > usLineWidthPixels
//Juqi: Allow manual line breaks to be added in XML,
// rather than relying solely on width for automatic line breaks.
if((usCurrentWidthPixels > usLineWidthPixels || fNewLine)
&&
((g_lang != i18n::Lang::zh)
||
(g_lang == i18n::Lang::zh
&& TempString[usCurIndex] != L''
&& TempString[usCurIndex] != L''
&& TempString[usCurIndex] != L''
@@ -239,8 +245,9 @@ WRAPPED_STRING *LineWrap(INT32 iFont, UINT16 usLineWidthPixels, UINT16 *pusLineW
&& TempString[usCurIndex] != L''
&& TempString[usCurIndex] != L')'
&& TempString[usCurIndex] != L''
)//||(DestString[ usDestIndex ]==NEWLINE_CHAR )||(fNewLine))
)
))
)
{
//if an error has occured, and the string is too long
@@ -251,51 +258,55 @@ WRAPPED_STRING *LineWrap(INT32 iFont, UINT16 usLineWidthPixels, UINT16 *pusLineW
// Fix really long unbroken strings, the above code dosent work for it
usLastMaxWidthIndex = usDestIndex;
//Go back to begining of word
while(
(g_lang != i18n::Lang::zh && DestString[ usDestIndex ] != L' ' && usCurIndex > 0 && usDestIndex > 0)
||
(g_lang == i18n::Lang::zh && DestString[ usDestIndex ] != L' ' && usCurIndex > 0 && usDestIndex > 0 && DestString[usDestIndex] < 255))
{
OneChar[0] = DestString[ usDestIndex ];
//Juqi: if NEWLINE_CHAR, don't go back
if (!fNewLine)
{
//Go back to begining of word
while(
(g_lang != i18n::Lang::zh && DestString[ usDestIndex ] != L' ' && usCurIndex > 0 && usDestIndex > 0)
||
(g_lang == i18n::Lang::zh && DestString[ usDestIndex ] != L' ' && usCurIndex > 0 && usDestIndex > 0 && DestString[usDestIndex] < 255))
{
OneChar[0] = DestString[ usDestIndex ];
usCurrentWidthPixels = usCurrentWidthPixels - WFStringPixLength( OneChar, iFont);
usCurrentWidthPixels = usCurrentWidthPixels - WFStringPixLength( OneChar, iFont);
usCurIndex--;
usDestIndex--;
}
if (g_lang == i18n::Lang::zh && DestString[usDestIndex] > 255)
{
if (DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L','
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L'?'
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L')'
|| DestString[usDestIndex] == L'')
{usDestIndex++;}
else
{usCurIndex--;}
}
usCurIndex--;
usDestIndex--;
}
if (g_lang == i18n::Lang::zh && DestString[usDestIndex] > 255)
{
if (DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L','
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L'?'
|| DestString[usDestIndex] == L''
|| DestString[usDestIndex] == L')'
|| DestString[usDestIndex] == L'')
{usDestIndex++;}
else
{usCurIndex--;}
}
usEndIndex = usDestIndex;
usEndIndex = usDestIndex;
// OJW - 20090427
// Fix really long unbroken strings
if( usEndIndex <= 0 )
{
usEndIndex = usLastMaxWidthIndex;
usDestIndex = usLastMaxWidthIndex;
usCurIndex += usLastMaxWidthIndex - 1;
}
// OJW - 20090427
// Fix really long unbroken strings
if( usEndIndex <= 0 )
{
usEndIndex = usLastMaxWidthIndex;
usDestIndex = usLastMaxWidthIndex;
usCurIndex += usLastMaxWidthIndex - 1;
}
// put next line into temp buffer
DestString[usEndIndex] = 0;
// put next line into temp buffer
DestString[usEndIndex] = 0;
} //Juqi: endif
//get to next WrappedString structure
pWrappedString = &FirstWrappedString;
+5
View File
@@ -28,6 +28,11 @@ typedef enum
LANGUAGE_LOCATION zlanguageText[1000];
// Single shared buffer for all languages (declared in Text.h): filled at runtime from
// NewTacticalMessages.xml below, never from compiled-in per-language data, so it is not
// part of the BindLanguageStrings pointer-rebind scheme.
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS];
typedef struct
{
LANGUAGE_PARSE_STAGE curElement;
-1
View File
@@ -1,6 +1,5 @@
function(CopyUserPresetTemplate)
if(
NOT DEFINED Languages AND
NOT DEFINED Applications AND
NOT EXISTS "${CMAKE_SOURCE_DIR}/CMakePresets.json" AND
NOT EXISTS "${CMAKE_SOURCE_DIR}/CMakeUserPresets.json"
-2
View File
@@ -7,8 +7,6 @@
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
// Valid choices: ENGLISH;GERMAN;FRENCH;ITALIAN;POLISH;DUTCH;RUSSIAN;CHINESE. If empty (""), will configure all.
"Languages": "ENGLISH",
// Valid choices: JA2;JA2MAPEDITOR;JA2UB;JA2UBMAPEDITOR. If empty (""), will configure all.
"Applications": "JA2",
// For debugging: enter your desired gamedir. e.g. C:/Games/JA2
+3 -16
View File
@@ -1,23 +1,10 @@
set(i18nSrc
"${CMAKE_CURRENT_SOURCE_DIR}/language.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LanguageStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LocalizedStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Ja2 Libs.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ExportStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_ChineseText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_DutchText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_EnglishText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_FrenchText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_GermanText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_ItalianText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25ChineseText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25DutchText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25EnglishText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25FrenchText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25GermanText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25ItalianText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25PolishText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_Ja25RussianText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_PolishText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/_RussianText.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ImportStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Multi Language Graphic Utils.cpp"
PARENT_SCOPE
)
+421 -452
View File
File diff suppressed because it is too large Load Diff
-28
View File
@@ -27,34 +27,6 @@ LibraryInitHeader gGameLibaries[ ] =
{ "TileSets.slf", TRUE, TRUE },
{ "LoadScreens.slf", TRUE, TRUE },
{ "Intro.slf", TRUE, TRUE },
#ifdef GERMAN
{ "German.slf", FALSE, TRUE },
#endif
#ifdef POLISH
{ "Polish.slf", FALSE, TRUE },
#endif
#ifdef DUTCH
{ "Dutch.slf", FALSE, TRUE },
#endif
#ifdef ITALIAN
{ "Italian.slf", FALSE, TRUE },
#endif
#ifdef RUSSIAN
{ "Russian.slf", FALSE, TRUE },
#endif
#ifdef FRENCH
{ "French.slf", FALSE, TRUE },
#endif
#ifdef CHINESE
{ "Chinese.slf", FALSE, TRUE },
#endif
};
+126
View File
@@ -0,0 +1,126 @@
#include "Text.h"
#include "Item Statistics.h"
#include <language.hpp>
#include <type_traits>
namespace lang_en {
#include "_EnglishText.cpp"
#include "_Ja25EnglishText.cpp"
}
namespace lang_de {
#include "_GermanText.cpp"
#include "_Ja25GermanText.cpp"
}
namespace lang_ru {
#include "_RussianText.cpp"
#include "_Ja25RussianText.cpp"
}
namespace lang_nl {
#include "_DutchText.cpp"
#include "_Ja25DutchText.cpp"
}
namespace lang_pl {
#include "_PolishText.cpp"
#include "_Ja25PolishText.cpp"
}
namespace lang_fr {
#include "_FrenchText.cpp"
#include "_Ja25FrenchText.cpp"
}
namespace lang_it {
#include "_ItalianText.cpp"
#include "_Ja25ItalianText.cpp"
}
namespace lang_zh {
#include "_ChineseText.cpp"
#include "_Ja25ChineseText.cpp"
}
namespace lang_default = lang_en;
// definitions (default language)
#define X(NAME) \
std::decay_t<decltype(lang_default::NAME)> NAME = lang_default::NAME;
#include "text.def"
#undef X
namespace {
auto bind_en() -> void {
#define X(NAME) NAME = lang_en::NAME;
#include "text.def"
#undef X
}
auto bind_de() -> void {
#define X(NAME) NAME = lang_de::NAME;
#include "text.def"
#undef X
}
auto bind_ru() -> void {
#define X(NAME) NAME = lang_ru::NAME;
#include "text.def"
#undef X
}
auto bind_nl() -> void {
#define X(NAME) NAME = lang_nl::NAME;
#include "text.def"
#undef X
}
auto bind_pl() -> void {
#define X(NAME) NAME = lang_pl::NAME;
#include "text.def"
#undef X
}
auto bind_fr() -> void {
#define X(NAME) NAME = lang_fr::NAME;
#include "text.def"
#undef X
}
auto bind_it() -> void {
#define X(NAME) NAME = lang_it::NAME;
#include "text.def"
#undef X
}
auto bind_zh() -> void {
#define X(NAME) NAME = lang_zh::NAME;
#include "text.def"
#undef X
}
} // namespace
auto BindLanguageStrings(i18n::Lang lang) -> void {
switch (lang) {
case i18n::Lang::en:
bind_en();
break;
case i18n::Lang::de:
bind_de();
break;
case i18n::Lang::ru:
bind_ru();
break;
case i18n::Lang::nl:
bind_nl();
break;
case i18n::Lang::pl:
bind_pl();
break;
case i18n::Lang::fr:
bind_fr();
break;
case i18n::Lang::it:
bind_it();
break;
case i18n::Lang::zh:
bind_zh();
break;
}
}
+149 -166
View File
@@ -1,20 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("CHINESE")
#if defined( CHINESE )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_ChineseText_public_symbol(void){;}
#if defined( CHINESE )
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -110,10 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
@@ -2361,6 +2341,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"没有能够训练的民兵。", //L"No militia that can be drilled present.",
L"%s 已经完全的探索了 %s。", //L"%s has fully explored %s."
// The first %s is a merc name and the second %s is an item name
L"%s 排除了 %s 的故障。", //L"%s unjammed %s.",
L"%s 未能排除 %s 的故障。", //L"%s failed to unjam %s.",
L"%s 的行动点数不足以排除 %s 的故障。", //L"%s does not have enough APs to unjam %s.",
};
// the country and its noun in the game
@@ -7551,7 +7536,7 @@ STR16 gzLateLocalizedString[] =
L"%s用完了医药箱里的药品!", //"%s ran out of medical kits!",
L"%s没有所需技能来医疗他人!", //"%s lacks the necessary skill to doctor anyone!",
L"%s用完工具箱里的工具!", //"%s ran out of tool kits!",
L"%s没有所需技能来修理物品!", //"%s lacks the necessary skill to repair anything!",
L"%s没有所需技能或属性来修理物品!", //"%s lacks the necessary skill to repair anything!",
//44-45
L"修理时间", //L"Repair Time",
@@ -9385,7 +9370,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d% 对人员治疗疾病的效率 \n", //L" %s%d%% effectiveness at treating population against diseases\n",
L" 能够发现%d格之内的脚印 \n", //L"Can spot tracks up to %d tiles away\n",
L" %s%d% 被伏击时的初始距离 \n", //L" %s%d%% initial distance to enemy in ambush\n",
L" %s%d% 几率回避攻击 \n", //L" %s%d%% chance to evade snake attacks\n",
L" %s%d% 闪避蛇类攻击 \n", //L" %s%d%% chance to evade snake attacks\n",
L" 对某些其他背景的厌恶 \n", //L" dislikes some other backgrounds\n",
L" 吸烟者", //L"Smoker",
@@ -9482,8 +9467,8 @@ STR16 szNationalityText[]=
L"古巴人", // 5
L"丹麦人",
L"法国人",
L"",
L"Tracona", // (UB takes place in Tracona)
L"罗斯",
L"特拉科纳", // (UB takes place in Tracona)
L"瑞士人", // 10
L"牙买加人",
L"波兰人",
@@ -9492,103 +9477,103 @@ STR16 szNationalityText[]=
L"南非人", // 15
L"匈牙利人",
L"苏格兰人",
L"Arulco",
L"阿鲁科",
L"德国人",
L"非洲人", // 20
L"意大利人",
L"荷兰人",
L"罗马亚人",
L"Metavira",
L"罗马亚人",
L"梅塔维拉",
// newly added from here on
L"Afghan", // 25
L"Albanian",
L"Argentinian",
L"Armenian",
L"Azerbaijani",
L"Bangladeshi ", // 30
L"阿富汗人", // 25
L"阿尔巴尼亚人",
L"阿根廷人",
L"亚美尼亚人",
L"阿塞拜疆人",
L"孟加拉国人", // 30
L"白俄罗斯人",
L"比利时人",
L"Beninese",
L"Bolivian",
L"Bosnian", // 35
L"贝宁人",
L"玻利维亚人",
L"波斯尼亚人", // 35
L"巴西人",
L"保加利亚人",
L"Cambodian",
L"Chadian",
L"Chilean", // 40
L"Columbian",
L"Congolese",
L"Croatian",
L"Ecuadorian",
L"Egyptian", // 45
L"English",
L"Eritrean",
L"柬埔寨人",
L"乍得人",
L"智利人", // 40
L"哥伦比亚人",
L"刚果人",
L"克罗地亚人",
L"厄瓜多尔人",
L"埃及人", // 45
L"英格兰人",
L"厄立特里亚人",
L"爱沙尼亚人",
L"Ethiopian",
L"Filipino", // 50
L"埃塞俄比亚人",
L"菲律宾人", // 50
L"芬兰人",
L"Georgian",
L"格鲁吉亚人",
L"希腊人",
L"Guatemalan",
L"Haitian", // 55
L"Honduran",
L"危地马拉人",
L"海地人", // 55
L"洪都拉斯人",
L"印度人",
L"Indonesian",
L"印度尼西亚人",
L"伊朗人",
L"伊拉克人", // 60
L"Islandic",
L"冰岛人",
L"以色列人",
L"日本人",
L"Jordanian",
L"Kazakhstani", // 65
L"Korean",
L"Kyrgyzstani",
L"Laotian",
L"Latvian",
L"Lebanese", // 70
L"Lithuanian",
L"Lybian",
L"Macedonian",
L"Malaysian",
L"约旦人",
L"哈萨克斯坦人", // 65
L"韩国人和朝鲜人",
L"吉尔吉斯斯坦人",
L"老挝人",
L"拉脱维亚人",
L"黎巴嫩人", // 70
L"立陶宛人",
L"利比亚人",
L"马其顿人",
L"马来西亚人",
L"墨西哥人", // 75
L"Mongolian",
L"Moroccan",
L"Mozambican",
L"Myanma",
L"Namibian", // 80
L"Nicaraguan",
L"蒙古人",
L"摩洛哥人",
L"莫桑比克人",
L"缅甸人",
L"纳米比亚人", // 80
L"尼加拉瓜人",
L"尼日利亚人",
L"Nigerien",
L"尼日尔人",
L"挪威人",
L"Pakistani", // 85
L"Panamanian",
L"巴基斯坦人", // 85
L"巴拿马人",
L"葡萄牙人",
L"Rwandanese",
L"Salvadoran",
L"Saudi", // 90
L"卢旺达人",
L"萨尔瓦多人",
L"沙特人", // 90
L"塞尔维亚人",
L"Slovakian",
L"Slovenian",
L"Somali",
L"斯洛伐克人",
L"斯洛文尼亚人",
L"索马里人",
L"西班牙人", // 95
L"Sudanese",
L"苏丹人",
L"瑞典人",
L"叙利亚人",
L"Thai",
L"Togolese", // 100
L"Tunisian",
L"泰国人",
L"多哥人", // 100
L"突尼斯人",
L"土耳其人",
L"Ugandan",
L"Ukrainian",
L"Uruguayan", // 105
L"Uzbekistani",
L"乌干达人",
L"乌克兰人",
L"乌拉圭人", // 105
L"乌兹别克斯坦人",
L"委内瑞拉人",
L"Vietnamese",
L"Welsh",
L"Yemeni", // 110
L"Zamundan", // Zamunda
L"Zimbabwean",
L"越南人",
L"威尔士人",
L"也门人", // 110
L"扎蒙达人", // Zamunda
L"津巴布韦人",
};
STR16 szNationalityTextAdjective[] =
@@ -9601,8 +9586,8 @@ STR16 szNationalityTextAdjective[] =
L"古巴人", // 5
L"丹麦人",
L"法国人",
L"",
L"traconia" // UB takes place in Tracona
L"罗斯",
L"特拉科纳" // UB takes place in Tracona
L"瑞士人", // 10
L"牙买加人",
L"波兰人",
@@ -9611,103 +9596,103 @@ STR16 szNationalityTextAdjective[] =
L"南非人", // 15
L"匈牙利人",
L"苏格兰人",
L"Arulco",
L"阿鲁科",
L"德国人",
L"非洲人", // 20
L"意大利人",
L"荷兰人",
L"罗马亚人",
L"Metavira",
L"罗马亚人",
L"梅塔维拉",
// newly added from here on
L"afghans", // 25
L"albanians",
L"argentinians",
L"armenians",
L"azerbaijani",
L"bangladeshi", // 30
L"阿富汗人", // 25
L"阿尔巴尼亚人",
L"阿根廷人",
L"亚美尼亚人",
L"阿塞拜疆人",
L"孟加拉国人", // 30
L"白俄罗斯人",
L"比利时人",
L"beninese",
L"bolivians",
L"bosnians", // 35
L"贝宁人",
L"玻利维亚人",
L"波斯尼亚人", // 35
L"巴西人",
L"保加利亚人",
L"cambodians",
L"chadians",
L"chileans", // 40
L"columbians",
L"congolese",
L"croatians",
L"ecuadorians",
L"egyptians", // 45
L"englishmen",
L"eritreans",
L"柬埔寨人",
L"乍得人",
L"智利人", // 40
L"哥伦比亚人",
L"刚果人",
L"克罗地亚人",
L"厄瓜多尔人",
L"埃及人", // 45
L"英格兰人",
L"厄立特里亚人",
L"爱沙尼亚人",
L"ethiopians",
L"filipinos", // 50
L"埃塞俄比亚人",
L"菲律宾人", // 50
L"芬兰人",
L"georgians",
L"格鲁吉亚人",
L"希腊人",
L"guatemalans",
L"haitians", // 55
L"hondurans",
L"危地马拉人",
L"海地人", // 55
L"洪都拉斯人",
L"印度人",
L"indonesians",
L"印度尼西亚人",
L"伊朗人",
L"伊拉克人", // 60
L"islandics",
L"冰岛人",
L"以色列人",
L"日本人",
L"jordanians",
L"kazakhstani", // 65
L"koreans",
L"kyrgyzstani",
L"laotians",
L"latvians",
L"lebanese", // 70
L"lithuanians",
L"lybians",
L"macedonians",
L"malaysians",
L"约旦人",
L"哈萨克斯坦人", // 65
L"韩国人和朝鲜人",
L"吉尔吉斯斯坦人",
L"老挝人",
L"拉脱维亚人",
L"黎巴嫩人", // 70
L"立陶宛人",
L"利比亚人",
L"马其顿人",
L"马来西亚人",
L"墨西哥人", // 75
L"mongolians",
L"moroccans",
L"mozambicans",
L"myanmarians",
L"namibians", // 80
L"nicaraguans",
L"蒙古人",
L"摩洛哥人",
L"莫桑比克人",
L"缅甸人",
L"纳米比亚人", // 80
L"尼加拉瓜人",
L"尼日利亚人",
L"nigeriens",
L"尼日尔人",
L"挪威人",
L"巴基斯坦人", // 85
L"panamanians",
L"巴拿马人",
L"葡萄牙人",
L"rwandanese",
L"salvadorans",
L"saudis", // 90
L"卢旺达人",
L"萨尔瓦多人",
L"沙特人", // 90
L"塞尔维亚人",
L"slovakians",
L"slovenians",
L"somali",
L"斯洛伐克人",
L"斯洛文尼亚人",
L"索马里人",
L"西班牙人", // 95
L"sudanese",
L"苏丹人",
L"瑞典人",
L"叙利亚人",
L"thais",
L"togolese", // 100
L"tunisians",
L"泰国人",
L"多哥人", // 100
L"突尼斯人",
L"土耳其人",
L"ugandans",
L"ukrainians",
L"uruguayans", // 105
L"uzbekistani",
L"乌干达人",
L"乌克兰人",
L"乌拉圭人", // 105
L"乌兹别克斯坦人",
L"委内瑞拉人",
L"vietnamese",
L"welshs",
L"yemenites", // 110
L"zamundans", // Zamunda
L"zimbabweans",
L"越南人",
L"威尔士人",
L"也门人", // 110
L"扎蒙达人", // Zamunda
L"津巴布韦人",
};
// special text used if we do not hate any nation (value of -1)
@@ -12292,5 +12277,3 @@ STR16 szRobotText[] =
L"机器人的额外装甲破坏了!", //L"The robot's extra armour plating was destroyed!",
L"机器人附加%s技能效果。", //L"The robot gains the benefit of the %s skill trait.",
};
#endif //CHINESE
+6 -25
View File
@@ -1,22 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("DUTCH")
#if defined( DUTCH )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_DutchText_public_symbol(void){;}
#ifdef DUTCH
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -112,10 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
STR16 pMenuStrings[] =
@@ -2360,6 +2338,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.", // TODO.Translate
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12302,5 +12285,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //DUTCH
+6 -24
View File
@@ -1,20 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("ENGLISH")
#if defined( ENGLISH )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_EnglishText_public_symbol(void);
#if defined( ENGLISH )
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -110,11 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
STR16 pMenuStrings[] =
@@ -2361,6 +2340,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.",
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12292,5 +12276,3 @@ STR16 szRobotText[] =
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //ENGLISH
+6 -23
View File
@@ -1,20 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("FRENCH")
#ifdef FRENCH
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_FrenchText_public_symbol(void){;}
#ifdef FRENCH
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -115,10 +99,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
@@ -2369,6 +2349,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.", // TODO.Translate
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game // TODO.Translate
@@ -12284,5 +12269,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //FRENCH
+6 -24
View File
@@ -1,21 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("GERMAN")
#ifdef GERMAN
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_GermanText_public_symbol(void){;}
#ifdef GERMAN
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
******************************************************************************************************
@@ -134,10 +117,6 @@ Remove any LOOTF comment that has been checked, except maybe for "alt." (alterna
07/2010 LootFragg
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
@@ -2403,6 +2382,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s hat %s vollständig erkundet.",
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12207,5 +12191,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //GERMAN
+6 -23
View File
@@ -1,20 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("ITALIAN")
#if defined( ITALIAN )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_ItalianText_public_symbol(void){;}
#ifdef ITALIAN
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -110,10 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
STR16 pMenuStrings[] =
@@ -2355,6 +2335,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.", // TODO.Translate
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12293,5 +12278,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //ITALIAN
+3 -18
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("CHINESE")
#ifdef CHINESE
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25ChineseText_public_symbol(void){;}
#ifdef CHINESE
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -396,8 +383,8 @@ STR16 gzIMPMajorTraitsHelpTextsSurvival[] =
L"疾病抗性 %s%d%%\n",//L" %s%d%% disease resistance\n",
L"食物消耗 %s%d%%\n",//L" %s%d%% food consumption\n",
L"耗 %s%d%%\n",//L" %s%d%% water consumption\n",
L"回避几率 +%d%%\n", //L"+%d%% snake evasion\n",
L"耗 %s%d%%\n",//L" %s%d%% water consumption\n",
L"闪避蛇类 +%d%%\n", //L"+%d%% snake evasion\n",
L"迷彩涂装效果 +%d%%\n",// L"+%d%s camouflage effectiveness\n",
};
@@ -524,5 +511,3 @@ STR16 gzDisplayCoverText[]=
L"隐蔽难度", //L"Stealth difficulty",
L"陷阱等级", //L"Trap level",
};
#endif
+1 -17
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("DUTCH")
#ifdef DUTCH
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25DutchText_public_symbol(void){;}
#ifdef DUTCH
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -525,6 +512,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -16
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("ENGLISH")
#ifdef ENGLISH
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25EnglishText_public_symbol(void);
#ifdef ENGLISH
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -524,5 +511,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -17
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("FRENCH")
#ifdef FRENCH
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25FrenchText_public_symbol(void){;}
#ifdef FRENCH
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -525,6 +512,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -17
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("GERMAN")
#ifdef GERMAN
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25GermanText_public_symbol(void){;}
#ifdef GERMAN
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
//these strings match up with the defines in IMP Skill trait.cpp
STR16 gzIMPSkillTraitsText[]=
@@ -526,6 +513,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -17
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("ITALIAN")
#ifdef ITALIAN
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25ItalianText_public_symbol(void){;}
#ifdef ITALIAN
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -523,6 +510,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -18
View File
@@ -1,18 +1,4 @@
// WANNE: This pragma should not be needed anymore for Polish version, after we set the encoding to UTF8
// WANNE: Yes we need this here exclusivly in Polish version, because we do not have a codepage in the code like for other versions.
//#pragma setlocale("POLISH")
#ifdef POLISH
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25PolishText_public_symbol(void){;}
#ifdef POLISH
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -525,6 +511,3 @@ STR16 gzDisplayCoverText[]=
L"Stealth difficulty",
L"Trap level",
};
#endif
+1 -16
View File
@@ -1,17 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("RUSSIAN")
#ifdef RUSSIAN
#include "Text.h"
#include "FileMan.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_Ja25RussianText_public_symbol(void){;}
#ifdef RUSSIAN
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
// VERY TRUNCATED FILE COPIED FROM JA2.5 FOR ITS FEATURES FOR JA2 GOLD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - New STOMP laptop strings
@@ -524,5 +511,3 @@ STR16 gzDisplayCoverText[]=
L"Сложность остаться незаметным", //Stealth difficulty
L"Уровень ловушки",
};
#endif
+6 -24
View File
@@ -1,21 +1,4 @@
// WANNE: This pragma should not be needed anymore for Polish version, after we set the encoding to UTF8
// WANNE: Yes we need this here exclusivly in Polish version, because we do not have a codepage in the code like for other versions.
//#pragma setlocale("POLISH")
#if defined( POLISH )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_PolishText_public_symbol(void){;}
#ifdef POLISH
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -111,10 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
@@ -2367,6 +2346,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.", // TODO.Translate
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12306,5 +12290,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //POLISH
+6 -23
View File
@@ -1,20 +1,4 @@
// WANNE: Yes, this should be disabled, otherwise we get weird behavior when running the game with a VS 2005 build!
//#pragma setlocale("RUSSIAN")
#if defined( RUSSIAN )
#include "Text.h"
#include "FileMan.h"
#include "Scheduling.h"
#include "EditorMercs.h"
#include "Item Statistics.h"
#endif
//suppress : warning LNK4221: no public symbols found; archive member will be inaccessible
void this_is_the_RussianText_public_symbol(void){;}
#ifdef RUSSIAN
/*
/*
******************************************************************************************************
** IMPORTANT TRANSLATION NOTES **
@@ -110,10 +94,6 @@ FAST HELP TEXT -- Explains how the syntax of fast help text works.
*/
CHAR16 XMLTacticalMessages[1000][MAX_MESSAGE_NAMES_CHARS] =
{
L"",
};
//Encyclopedia
@@ -2361,6 +2341,11 @@ CHAR16 Message[][STRING_LENGTH] =
L"No militia that can be drilled present.",
L"%s has fully explored %s.", // TODO.Translate
// The first %s is a merc name and the second %s is an item name
L"%s unjammed %s.",
L"%s failed to unjam %s.",
L"%s does not have enough APs to unjam %s."
};
// the country and its noun in the game
@@ -12287,5 +12272,3 @@ STR16 szRobotText[] = // TODO: Translate
L"The robot's extra armour plating was destroyed!",
L"The robot gains the benefit of the %s skill trait.",
};
#endif //RUSSIAN
-24
View File
@@ -30,30 +30,6 @@
LIBRARY_LOADSCREENS,
LIBRARY_INTRO,
#ifdef GERMAN
LIBRARY_GERMAN_DATA,
#endif
#ifdef DUTCH
LIBRARY_DUTCH_DATA,
#endif
#ifdef POLISH
LIBRARY_POLISH_DATA,
#endif
#ifdef ITALIAN
LIBRARY_ITALIAN_DATA,
#endif
#ifdef RUSSIAN
LIBRARY_RUSSIAN_DATA,
#endif
#ifdef FRENCH
LIBRARY_FRENCH_DATA,
#endif
NUMBER_OF_LIBRARIES
};
@@ -7,30 +7,6 @@
namespace Loc
{
enum Language
{
Chinese,
Dutch,
English,
French,
German,
Italian,
Polish,
Russian,
};
static const wchar_t* LangSuffix [] = {
L"_cn",
L"_nl",
L"_en",
L"_fr",
L"_de",
L"_it",
L"_pl",
L"_ru",
L"_tw",
};
enum Topic
{
AIM_BIOGRAPHY,
+493 -504
View File
File diff suppressed because it is too large Load Diff
+36 -36
View File
@@ -1,49 +1,49 @@
#ifndef _JA25ENGLISHTEXT__H_
#ifndef _JA25ENGLISHTEXT__H_
#define _JA25ENGLISHTEXT__H_
extern STR16 gzIMPSkillTraitsText[];
extern STR16* gzIMPSkillTraitsText;
////////////////////////////////////////////////////////
// added by SANDRO
extern STR16 gzIMPSkillTraitsTextNewMajor[];
extern STR16 gzIMPSkillTraitsTextNewMinor[];
extern STR16* gzIMPSkillTraitsTextNewMajor;
extern STR16* gzIMPSkillTraitsTextNewMinor;
extern STR16 gzIMPMajorTraitsHelpTextsAutoWeapons[];
extern STR16 gzIMPMajorTraitsHelpTextsHeavyWeapons[];
extern STR16 gzIMPMajorTraitsHelpTextsSniper[];
extern STR16 gzIMPMajorTraitsHelpTextsRanger[];
extern STR16 gzIMPMajorTraitsHelpTextsGunslinger[];
extern STR16 gzIMPMajorTraitsHelpTextsMartialArts[];
extern STR16 gzIMPMajorTraitsHelpTextsSquadleader[];
extern STR16 gzIMPMajorTraitsHelpTextsTechnician[];
extern STR16 gzIMPMajorTraitsHelpTextsDoctor[];
extern STR16 gzIMPMajorTraitsHelpTextsCovertOps[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsRadioOperator[]; // added by Flugente
extern STR16 gzIMPMajorTraitsHelpTextsNone[];
extern STR16* gzIMPMajorTraitsHelpTextsAutoWeapons;
extern STR16* gzIMPMajorTraitsHelpTextsHeavyWeapons;
extern STR16* gzIMPMajorTraitsHelpTextsSniper;
extern STR16* gzIMPMajorTraitsHelpTextsRanger;
extern STR16* gzIMPMajorTraitsHelpTextsGunslinger;
extern STR16* gzIMPMajorTraitsHelpTextsMartialArts;
extern STR16* gzIMPMajorTraitsHelpTextsSquadleader;
extern STR16* gzIMPMajorTraitsHelpTextsTechnician;
extern STR16* gzIMPMajorTraitsHelpTextsDoctor;
extern STR16* gzIMPMajorTraitsHelpTextsCovertOps; // added by Flugente
extern STR16* gzIMPMajorTraitsHelpTextsRadioOperator; // added by Flugente
extern STR16* gzIMPMajorTraitsHelpTextsNone;
extern STR16 gzIMPMinorTraitsHelpTextsAmbidextrous[];
extern STR16 gzIMPMinorTraitsHelpTextsMelee[];
extern STR16 gzIMPMinorTraitsHelpTextsThrowing[];
extern STR16 gzIMPMinorTraitsHelpTextsStealthy[];
extern STR16 gzIMPMinorTraitsHelpTextsNightOps[];
extern STR16 gzIMPMinorTraitsHelpTextsAthletics[];
extern STR16 gzIMPMinorTraitsHelpTextsBodybuilding[];
extern STR16 gzIMPMinorTraitsHelpTextsDemolitions[];
extern STR16 gzIMPMinorTraitsHelpTextsTeaching[];
extern STR16 gzIMPMinorTraitsHelpTextsScouting[];
extern STR16 gzIMPMinorTraitsHelpTextsSnitch[];
extern STR16 gzIMPMajorTraitsHelpTextsSurvival[]; // added by Flugente
extern STR16 gzIMPMinorTraitsHelpTextsNone[];
extern STR16* gzIMPMinorTraitsHelpTextsAmbidextrous;
extern STR16* gzIMPMinorTraitsHelpTextsMelee;
extern STR16* gzIMPMinorTraitsHelpTextsThrowing;
extern STR16* gzIMPMinorTraitsHelpTextsStealthy;
extern STR16* gzIMPMinorTraitsHelpTextsNightOps;
extern STR16* gzIMPMinorTraitsHelpTextsAthletics;
extern STR16* gzIMPMinorTraitsHelpTextsBodybuilding;
extern STR16* gzIMPMinorTraitsHelpTextsDemolitions;
extern STR16* gzIMPMinorTraitsHelpTextsTeaching;
extern STR16* gzIMPMinorTraitsHelpTextsScouting;
extern STR16* gzIMPMinorTraitsHelpTextsSnitch;
extern STR16* gzIMPMajorTraitsHelpTextsSurvival; // added by Flugente
extern STR16* gzIMPMinorTraitsHelpTextsNone;
extern STR16 gzIMPOldSkillTraitsHelpTexts[];
extern STR16* gzIMPOldSkillTraitsHelpTexts;
extern STR16 gzIMPNewCharacterTraitsHelpTexts[];
extern STR16* gzIMPNewCharacterTraitsHelpTexts;
extern STR16 gzIMPDisabilitiesHelpTexts[];
extern STR16* gzIMPDisabilitiesHelpTexts;
extern STR16 gzIMPProfileCostText[];
extern STR16* gzIMPProfileCostText;
extern STR16 zGioNewTraitsImpossibleText[];
extern STR16* zGioNewTraitsImpossibleText;
///////////////////////////////////////////////////////
enum
@@ -52,7 +52,7 @@ enum
IMM__SOFT_IRON_MAN_MODE_WARNING_TEXT,
IMM__EXTREME_IRON_MAN_MODE_WARNING_TEXT,
};
extern STR16 gzIronManModeWarningText[];
extern STR16* gzIronManModeWarningText;
// display cover message (for tactical usually, seperated)
// display cover terrain type info (used in cover information)
@@ -80,7 +80,7 @@ enum
DC_TTI__DETAILED_STEALTH,
DC_TTI__DETAILED_TRAP_LEVEL,
};
extern STR16 gzDisplayCoverText[];
extern STR16* gzDisplayCoverText;
#endif

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