mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d996e1f739 | ||
|
|
86506b5ec7 | ||
|
|
8f1813cd0b | ||
|
|
4e0e98dda9 | ||
|
|
8ff09aa10e | ||
|
|
caa64822dd | ||
|
|
bad50cd335 | ||
|
|
71c8b851e6 | ||
|
|
16b2681c79 | ||
|
|
764ab01d9d | ||
|
|
ef78c35a30 | ||
|
|
2e4998168c | ||
|
|
eef4571cfe | ||
|
|
2e8c742fdb | ||
|
|
8782428615 | ||
|
|
d62ec1b939 | ||
|
|
5fb69175e5 | ||
|
|
157f4434d5 | ||
|
|
43fb1ec5f2 | ||
|
|
80679572c3 | ||
|
|
7f0017a858 | ||
|
|
7e95e1b405 | ||
|
|
03cc1f8ae4 | ||
|
|
c4f6f9c9c7 | ||
|
|
987419945f | ||
|
|
461b12037a | ||
|
|
e072cfda7c | ||
|
|
8bd0147578 | ||
|
|
b68655f7c8 | ||
|
|
9d68ae2d4b | ||
|
|
7eec7a132e | ||
|
|
3d630de332 | ||
|
|
b39d5d9a57 | ||
|
|
d654233614 | ||
|
|
6f9d1fc1f8 | ||
|
|
fee5b7daa1 | ||
|
|
f36f204dd7 | ||
|
|
cc7e471df0 | ||
|
|
4b8478911e | ||
|
|
deb6d2d0ea | ||
|
|
1354ff2ec6 | ||
|
|
38eed54c9f | ||
|
|
5230d0aeca | ||
|
|
62f9eb1987 | ||
|
|
ef791b872a | ||
|
|
bbf8e84696 | ||
|
|
b8add3dec5 | ||
|
|
d3ff9d04b4 | ||
|
|
587ca5bee1 | ||
|
|
20bf2ce145 | ||
|
|
486c897243 | ||
|
|
87eca4898a | ||
|
|
3515dac146 | ||
|
|
73deda86c8 | ||
|
|
d39535e0a6 | ||
|
|
5c246ba614 | ||
|
|
33943bb6ff | ||
|
|
81f4af927b | ||
|
|
e2dcb3e0b2 | ||
|
|
88197f7fed | ||
|
|
0b14111472 | ||
|
|
8448a24339 | ||
|
|
388a5de994 | ||
|
|
803eeb4d27 | ||
|
|
2714b3bfc8 | ||
|
|
0409eb67e4 | ||
|
|
ea74ff7d0c | ||
|
|
e05010c752 | ||
|
|
9f8a5b4766 | ||
|
|
6a773780a7 | ||
|
|
e2ad532607 | ||
|
|
181560265f | ||
|
|
ca42b01193 | ||
|
|
73ac86d493 | ||
|
|
7dc499eb24 | ||
|
|
944a1be064 | ||
|
|
bc882680e4 | ||
|
|
cfcfa21afe | ||
|
|
0095ec212b | ||
|
|
83d8104ed8 | ||
|
|
c74ddc1cbc | ||
|
|
0746d6b483 | ||
|
|
3c8ec03e30 | ||
|
|
0b67cb4125 | ||
|
|
e84c5fdc1d | ||
|
|
a56162c949 | ||
|
|
272b082d72 | ||
|
|
4f43a47a09 | ||
|
|
9c97d0da44 | ||
|
|
c1b279f2fa | ||
|
|
3ebc4326c5 | ||
|
|
257a1f7b33 | ||
|
|
a66db5a386 | ||
|
|
db547212e8 | ||
|
|
10ffa66256 | ||
|
|
9734d18d68 | ||
|
|
e706fba989 | ||
|
|
884c00ffeb | ||
|
|
78ef06c8e6 | ||
|
|
d75d46d281 | ||
|
|
fc1d9dbfc2 | ||
|
|
b50dcaa151 | ||
|
|
53f427fcac | ||
|
|
818c2eb6b2 | ||
|
|
ad2b9ab0fb | ||
|
|
46349c5d69 | ||
|
|
8a8455efea | ||
|
|
6e7ba2f5b9 | ||
|
|
da08bdbf83 | ||
|
|
dc97dad94c | ||
|
|
82cf074845 | ||
|
|
8e95b2d8f6 | ||
|
|
81638168c2 | ||
|
|
56459ee5f0 | ||
|
|
35276dfe59 | ||
|
|
0400671f38 | ||
|
|
30cb8b7ee9 | ||
|
|
273c44e788 | ||
|
|
4ef8986bda | ||
|
|
dbf5e36b86 | ||
|
|
386d373376 | ||
|
|
360037a2fd | ||
|
|
a3c8f0f609 | ||
|
|
7dda156ee7 | ||
|
|
31a5dbc61c | ||
|
|
c476e54db0 | ||
|
|
95dc75da38 | ||
|
|
e276c59447 | ||
|
|
1c3e2f2eb1 | ||
|
|
3dcc26a739 | ||
|
|
8ef6a66134 | ||
|
|
0bba6ccb54 | ||
|
|
8f846eda6e | ||
|
|
572cbd059f | ||
|
|
f02ba1993b | ||
|
|
f800b7bb33 | ||
|
|
de3d6256e3 | ||
|
|
ae0f3d6fdc | ||
|
|
f46ffb4ea5 | ||
|
|
c7ecf1c070 | ||
|
|
8c277730bf | ||
|
|
898e7bb4e0 | ||
|
|
3e955572be | ||
|
|
7fc5dc47b4 | ||
|
|
71e3ee4801 | ||
|
|
59eacce6be | ||
|
|
ff53d2515d | ||
|
|
8fd5182bb5 | ||
|
|
2677d9faa7 | ||
|
|
9fe3ed5d98 | ||
|
|
e6610c4bbe | ||
|
|
31630f6627 | ||
|
|
489f62f5cb | ||
|
|
1f802cab6f | ||
|
|
788593cdcc | ||
|
|
680310f702 | ||
|
|
4f36136a39 | ||
|
|
48355fa637 | ||
|
|
6af62af27d | ||
|
|
bd76a3ded7 | ||
|
|
3a08488895 | ||
|
|
2941157174 | ||
|
|
2148650313 | ||
|
|
6dee4e1183 | ||
|
|
b2e60ba62e | ||
|
|
a71c2c901a | ||
|
|
4f3c1a60b4 | ||
|
|
9674c16928 | ||
|
|
0c035a05df | ||
|
|
51cd2eab69 | ||
|
|
323631835b | ||
|
|
135c26ab70 | ||
|
|
34092900a6 | ||
|
|
c8fe92ef7d | ||
|
|
b578aecc59 | ||
|
|
b57a87f98f | ||
|
|
2156f82184 | ||
|
|
be6947e3d2 | ||
|
|
f0784e2987 | ||
|
|
1a6a9e5ec1 | ||
|
|
0be6011c19 | ||
|
|
6f45d45fcd | ||
|
|
f413bb8b9a | ||
|
|
e3907c3647 | ||
|
|
007386caec | ||
|
|
c593269ee7 | ||
|
|
1976461b72 | ||
|
|
9fa123d15f | ||
|
|
3b6435d8a4 | ||
|
|
7322634780 | ||
|
|
7f0398c618 | ||
|
|
4e3f065453 | ||
|
|
378bc8a126 | ||
|
|
e92c994744 | ||
|
|
a1d0e59287 | ||
|
|
40f2050f8c | ||
|
|
c33c200b51 | ||
|
|
26693fd0ed | ||
|
|
033c8bf8ef | ||
|
|
ddf2854938 | ||
|
|
637de0e07d | ||
|
|
ff1c87f0c5 | ||
|
|
66c0ed8cb2 | ||
|
|
f3bbfbfa28 | ||
|
|
41a1fead58 | ||
|
|
a0cf633899 | ||
|
|
a09611edc6 | ||
|
|
291370a96c | ||
|
|
576bea2aa9 | ||
|
|
765b19e045 | ||
|
|
f4fe4211e1 | ||
|
|
0c3d6004a7 | ||
|
|
f6675cf241 | ||
|
|
736c2cb6fe | ||
|
|
13445a1b83 | ||
|
|
4417947c56 | ||
|
|
6903d59e6d | ||
|
|
5e3e37f74c | ||
|
|
e090fd833b | ||
|
|
1ab8407407 | ||
|
|
a4558993e0 | ||
|
|
f1131b87c6 | ||
|
|
465bc649be | ||
|
|
9db5f45545 | ||
|
|
fb4770edc4 | ||
|
|
921f14f43f | ||
|
|
d013d59afd | ||
|
|
2828e08f68 | ||
|
|
0b08035b97 | ||
|
|
62b0955807 | ||
|
|
67b46cd4a6 | ||
|
|
bb13e3f219 | ||
|
|
7ecdfe362f | ||
|
|
4f34217625 | ||
|
|
f4666dad18 | ||
|
|
536e3b2741 | ||
|
|
f4c72a4e6e | ||
|
|
db40eae68f | ||
|
|
f1626e846a | ||
|
|
5429217c0a | ||
|
|
59aee239fe | ||
|
|
d429af8011 | ||
|
|
ba186590bc | ||
|
|
f94cadf767 | ||
|
|
aea263eddd | ||
|
|
b7fc0fb1d7 | ||
|
|
b8c3f89279 | ||
|
|
82eb78e185 | ||
|
|
d8fafa85a9 | ||
|
|
a121d09704 | ||
|
|
b0fa170ffd | ||
|
|
c9712f75ee | ||
|
|
7f426608d2 | ||
|
|
81af621b3c | ||
|
|
0ed00a0a41 | ||
|
|
89eff96b69 |
@@ -26,6 +26,7 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
!ducible.exe
|
||||
|
||||
# NetBeans
|
||||
nbproject/private/
|
||||
|
||||
+980
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -645,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -664,12 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# sfall
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://github.com/phobos2077/sfall/actions/workflows/build.yml)
|
||||
[](https://github.com/phobos2077/sfall/actions/workflows/gh-pages.yml)
|
||||
|
||||
A set of engine modifications for the classic game Fallout 2 in the form of a DLL, which modifies executable in memory without changing anything in EXE file itself.
|
||||
|
||||
@@ -11,12 +13,52 @@ A set of engine modifications for the classic game Fallout 2 in the form of a DL
|
||||
- Many additional features for users, such as item highlight button, party member control, etc.
|
||||
- Extended scripting capabilities for modders (many new opcodes to control sfall features as well as previously unavailable vanilla engine functions)
|
||||
|
||||
|
||||
Original author: **Timeslip**
|
||||
|
||||
Original description: A set of engine modifications for the classic game Fallout 2 by Interplay. Includes fixes for bugs in the original engine, allows fallout to run correctly on modern operating systems, and adds additional features for modders.
|
||||
Original description: A set of engine modifications for the classic game Fallout 2 by Interplay. Includes fixes for bugs in the original engine, allows Fallout to run correctly on modern operating systems, and adds additional features for modders.
|
||||
|
||||
---
|
||||
#### Fallout Engine IDA Database
|
||||
[Download for IDA Pro 6.8](https://www.dropbox.com/s/tm0nyx0lnk4yui0/Fallout_1_and_2_IDA68.rar?dl=1 "Download from Dropbox")
|
||||
| [Download for IDA Pro 7.0](https://www.dropbox.com/s/61srq09pn8grfpu/Fallout_1_and_2_IDA70.rar?dl=1 "Download from Dropbox") (comments are in Russian)
|
||||
## Installation
|
||||
|
||||
- Download `sfall_*.7z` from the [release archive](https://sourceforge.net/projects/sfall/files/).
|
||||
|
||||
- Extract `ddraw.dll`, `ddraw.ini`, and `sfall.dat` to Fallout's base directory (i.e. the one that contains `fallout2.exe`).
|
||||
|
||||
- __Important Note:__\
|
||||
If you are using a mod that already included sfall (e.g. killap's [Unofficial Patch](https://github.com/BGforgeNet/Fallout2_Unofficial_Patch) or [Restoration Project](https://github.com/BGforgeNet/Fallout2_Restoration_Project)), then that mod has probably included a custom modified `ddraw.ini`. In that case, overwriting it with sfall's vanilla `ddraw.ini` will be likely break your game. Instead, only overwrite `ddraw.dll`, and keep the mod's existing copy of `ddraw.ini`. (Or, if you know what you're doing, you can merge them together by hand.)
|
||||
|
||||
- The folder `translations` contains translations of some of the strings that sfall displays in the game. To use a translation, copy this folder to Fallout's base directory too, and then in `ddraw.ini` change the __TranslationsINI__ setting to `.\translations\<your language>.ini`.
|
||||
|
||||
## Uninstallation
|
||||
|
||||
Delete `ddraw.dll`, `ddraw.ini`, and `sfall.dat` from your Fallout directory.
|
||||
|
||||
## Usage
|
||||
|
||||
This mod is configured via the `ddraw.ini` file, which can be opened with any text editor. Details of every configerable option are included in that file. Where a comment refers to a DX scancode, the complete list of codes can be found at the link below:\
|
||||
https://kippykip.com/b3ddocs/commands/scancodes.htm
|
||||
|
||||
In a default installation using an unmodified copy of `ddraw.ini`, the middle mouse button will be set to switch between weapons and the mouse wheel will be set to scroll through any menus that respond to the up/down arrow keys. Holding **Ctrl** and hitting numpad keys 0 to 6 (with Num Lock off) will adjust the game speed. Holding **left Ctrl** will let you move items between inventory lists by simply clicking on them. Pressing **left Shift** will highlight items on the ground, and holding the key will let you move an entire stack of items at once. The script extender and any engine fixes are also enabled. Most of the options that change gameplay in some way not originally intended by the developers are disabled.
|
||||
|
||||
For [__Wine__](https://www.winehq.org/) users:\
|
||||
You need to set DLL overrides for `ddraw.dll` to __"native, builtin"__ in `winecfg` or use `WINEDLLOVERRIDES="ddraw=n,b"` to run Fallout from the command line. If you want to play alternative sound files, you'll also need to install GStreamer Good 32-bit plugins.
|
||||
|
||||
## Build Instructions
|
||||
|
||||
### Prerequisites:
|
||||
|
||||
* Visual C++ 2010 Express SP1 or Visual Studio 2010 SP1.
|
||||
* [DirectX SDK (February 2010)](https://archive.org/details/dxsdk_feb10). You will also need `dinput.lib` from DXSDK August 2007. The file can be found in the [DirectX SDK Collection repo](https://github.com/NovaRain/DXSDK_Collection).
|
||||
* [DirectX Runtime (June 2010)](https://www.microsoft.com/en-us/download/details.aspx?id=8109).
|
||||
|
||||
### Steps:
|
||||
|
||||
1. Set up a `postbuild.cmd` using the template from the repo.
|
||||
2. Open the solution file and build with the **Release** configuration.
|
||||
3. If everything is set up correctly, you should have a new sfall `ddraw.dll` in your Fallout 2 directory.
|
||||
|
||||
## Additional info
|
||||
|
||||
* [Changelog](CHANGELOG.md)
|
||||
* [Scripting Documentation](https://sfall-team.github.io/sfall/)
|
||||
* Fallout Engine IDA Database: [for IDA Pro 6.8](https://www.dropbox.com/s/tm0nyx0lnk4yui0/Fallout_1_and_2_IDA68.rar?dl=1 "Download from Dropbox") | [for IDA Pro 7.0](https://www.dropbox.com/s/61srq09pn8grfpu/Fallout_1_and_2_IDA70.rar?dl=1 "Download from Dropbox") (comments are in Russian)
|
||||
* [Fallout 2 Reference Edition](https://github.com/alexbatalov/fallout2-re)
|
||||
|
||||
@@ -2,15 +2,64 @@
|
||||
|
||||
;When adding extra perks to a mod, it's advisable to use the fake perk scripting functions rather than make
|
||||
; modifications in this file, as some perks have hardcoded effects which may catch you out
|
||||
;Set the bonus value to 0 in the 'PerksTweak' section for perks to get around this problem
|
||||
|
||||
;Since traits need to be picked before any scripts run, they have an additional NoHardcode option in this file which can
|
||||
; be used to remove their hardcoded effects, and add new stat/skill effects
|
||||
;Since traits need to be picked before any scripts run, they have an additional 'NoHardcode' option in this file
|
||||
; which can be used to remove their hardcoded effects, and add new stat/skill effects
|
||||
|
||||
;##############################################################################
|
||||
[PerksTweak]
|
||||
;Changes the light level bonus for 'Night Vision' perk (ID 9)
|
||||
;valid range: 0..100, 20 - default bonus
|
||||
NightVisionBonus=20
|
||||
|
||||
;Changes the Outdoorsman skill bonus for 'Survivalist' perk (ID 16)
|
||||
;125 - maximum bonus, 25 - default bonus
|
||||
SurvivalistBonus=25
|
||||
|
||||
;Changes the bonus for 'Master Trader' perk (ID 17)
|
||||
;25 - default bonus
|
||||
MasterTraderBonus=25
|
||||
|
||||
;Changes the skill point bonus for 'Educated' perk (ID 18)
|
||||
;125 - maximum bonus, 2 - default bonus
|
||||
EducatedBonus=2
|
||||
|
||||
;Changes the hit point bonuses for 'Healer' perk (ID 19)
|
||||
;999 - maximum bonus, 4 - default bonus
|
||||
HealerMinBonus=4
|
||||
;999 - maximum bonus, 10 - default bonus
|
||||
HealerMaxBonus=10
|
||||
|
||||
;Changes the hit point bonus for 'Lifegiver' perk (ID 28)
|
||||
;125 - maximum bonus, 4 - default bonus
|
||||
LifegiverBonus=4
|
||||
|
||||
;Changes the Science and Repair skill bonus for 'Mr.Fixit' perk (ID 31)
|
||||
;125 - maximum bonus, 10 - default bonus
|
||||
MrFixitBonus=10
|
||||
|
||||
;Changes the skill bonuses for 'Medic' perk (ID 32)
|
||||
;125 - maximum bonus, 10 - default bonus
|
||||
MedicFirstAidBonus=10
|
||||
MedicDoctorBonus=10
|
||||
|
||||
;Changes the Lockpick and Steal skill bonus for 'Master Thief' perk (ID 33)
|
||||
;125 - maximum bonus, 15 - default bonus
|
||||
MasterThiefBonus=15
|
||||
|
||||
;Changes the Speech skill bonus for 'Speaker' perk (ID 34)
|
||||
;125 - maximum bonus, 20 - default bonus
|
||||
SpeakerBonus=20
|
||||
|
||||
;Changes the Sneak skill bonus (when in darkness) for 'Ghost' perk (ID 38)
|
||||
;125 - maximum bonus, 20 - default bonus
|
||||
GhostBonus=20
|
||||
|
||||
;Changes the Outdoorsman skill bonus for 'Ranger' perk (ID 47)
|
||||
;125 - maximum bonus, 15 - default bonus
|
||||
RangerOutdoorsmanBonus=15
|
||||
|
||||
;Changes the distance bonus for 'Weapon Long Range' weapon perk (ID 58)
|
||||
;2 - no bonus, 4 - default bonus
|
||||
WeaponLongRangeBonus=4
|
||||
@@ -30,13 +79,36 @@ WeaponScopeRangeBonus=5
|
||||
VaultCityInoculationsPoisonBonus=10
|
||||
VaultCityInoculationsRadBonus=10
|
||||
|
||||
;Changes the distance bonus for 'Cautious Nature' perk (ID 80)
|
||||
;Affects where critters spawn in 'surrounding' random encounters without a specified distance
|
||||
;valid range: -12..20, 3 - default bonus
|
||||
CautiousNatureBonus=3
|
||||
|
||||
;Changes the percentage bonus for 'Comprehension' perk (ID 81)
|
||||
;50 - default bonus
|
||||
ComprehensionBonus=50
|
||||
|
||||
;Changes the damage bonus per level for 'Demolition Expert' perk (ID 82)
|
||||
;999 - maximum bonus, 10 - default bonus
|
||||
DemolitionExpertBonus=10
|
||||
|
||||
;Changes the damage bonus for 'Living Anatomy' perk (ID 97)
|
||||
;125 - maximum bonus, 5 - default bonus
|
||||
;Changes the Gambling skill bonus for 'Gambler' perk (ID 83)
|
||||
;125 - maximum bonus, 20 - default bonus
|
||||
GamblerBonus=20
|
||||
|
||||
;Changes the Steal skill bonus for 'Harmless' perk (ID 91)
|
||||
;125 - maximum bonus, 20 - default bonus
|
||||
HarmlessBonus=20
|
||||
|
||||
;Changes the damage bonus and the Doctor skill bonus for 'Living Anatomy' perk (ID 97)
|
||||
;125 - maximum bonus, 5 - default damage bonus
|
||||
LivingAnatomyBonus=5
|
||||
;125 - maximum bonus, 10 - default skill bonus
|
||||
LivingAnatomyDoctorBonus=10
|
||||
|
||||
;Changes the Speech and Barter skill bonus for 'Negotiator' perk (ID 99)
|
||||
;125 - maximum bonus, 10 - default bonus
|
||||
NegotiatorBonus=10
|
||||
|
||||
;Changes the damage bonus for 'Pyromaniac' perk (ID 101)
|
||||
;125 - maximum bonus, 5 - default bonus
|
||||
@@ -50,10 +122,23 @@ SalesmanBonus=20
|
||||
;valid range: 0..100, 50 - default percent
|
||||
StonewallPercent=50
|
||||
|
||||
;Changes the Lockpick, Steal, and Traps skill bonus for 'Thief' perk (ID 105)
|
||||
;125 - maximum bonus, 10 - default bonus
|
||||
ThiefBonus=10
|
||||
|
||||
;Changes the strength bonus for 'Weapon Handling' perk (ID 106)
|
||||
;0 - no bonus, 10 - maximum bonus, 3 - default bonus
|
||||
WeaponHandlingBonus=3
|
||||
|
||||
;Changes the skill bonuses for 'Vault City Training' perk (ID 107)
|
||||
;125 - maximum bonus, 5 - default bonus
|
||||
VaultCityTrainingFirstAidBonus=5
|
||||
VaultCityTrainingDoctorBonus=5
|
||||
|
||||
;Changes the Speech skill bonus for 'Expert Excrement Expeditor' perk (ID 116)
|
||||
;125 - maximum bonus, 5 - default bonus
|
||||
ExpertExcrementExpeditorBonus=5
|
||||
|
||||
;##############################################################################
|
||||
[Perks]
|
||||
;Set to 1 to enable the modifications for perks
|
||||
@@ -86,7 +171,6 @@ Enable=0
|
||||
|
||||
;If the value is set to -99999, the variable will be ignored (similar to comment out that line)
|
||||
|
||||
;##############################################################################
|
||||
;This is a modification to perk 119
|
||||
[119]
|
||||
Name=Example
|
||||
|
||||
@@ -11,6 +11,12 @@ PartyLvlMsg=Lvl:
|
||||
PartyACMsg=AC:
|
||||
PartyAddictMsg=Addict
|
||||
NPCPickupFail=%s cannot pick up the item.
|
||||
AmmoInfoGlovz=Div: DR/%d, DT/%d
|
||||
AmmoInfoYAAM=DT Mod: %d
|
||||
|
||||
PartyOrderAttackHuman=I'll take care of it.|Okay, I got it.|Sounds like a plan.
|
||||
PartyOrderAttackCreature=::Growl::
|
||||
PartyOrderAttackRobot=::Beep::
|
||||
|
||||
[AppearanceMod]
|
||||
RaceText=Race
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
;in the proto for other items, so AI will use them for healing in combat as well
|
||||
STIMPAK=40
|
||||
SUPER_STIMPAK=144
|
||||
HEALING_POWDER=237
|
||||
HEALING_POWDER=273
|
||||
|
||||
+152
-78
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,201 @@
|
||||
;Example Ammo INI for vanilla damage formula
|
||||
|
||||
; PID_EXPLOSIVE_ROCKET
|
||||
[1]
|
||||
pid=14
|
||||
ac_adjust=0
|
||||
dr_adjust=-25
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_10MM_JHP
|
||||
[2]
|
||||
pid=29
|
||||
ac_adjust=0
|
||||
dr_adjust=25
|
||||
dam_mult=2
|
||||
dam_div=1
|
||||
|
||||
; PID_10MM_AP
|
||||
[3]
|
||||
pid=30
|
||||
ac_adjust=0
|
||||
dr_adjust=-25
|
||||
dam_mult=1
|
||||
dam_div=2
|
||||
|
||||
; PID_44_MAGNUM_JHP
|
||||
[4]
|
||||
pid=31
|
||||
ac_adjust=0
|
||||
dr_adjust=20
|
||||
dam_mult=2
|
||||
dam_div=1
|
||||
|
||||
; PID_FLAMETHROWER_FUEL
|
||||
[5]
|
||||
pid=32
|
||||
ac_adjust=-20
|
||||
dr_adjust=25
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_14MM_AP
|
||||
[6]
|
||||
pid=33
|
||||
ac_adjust=0
|
||||
dr_adjust=-50
|
||||
dam_mult=1
|
||||
dam_div=2
|
||||
|
||||
; PID_223_FMJ
|
||||
[7]
|
||||
pid=34
|
||||
ac_adjust=-20
|
||||
dr_adjust=-20
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_5MM_JHP
|
||||
[8]
|
||||
pid=35
|
||||
ac_adjust=0
|
||||
dr_adjust=35
|
||||
dam_mult=2
|
||||
dam_div=1
|
||||
|
||||
; PID_5MM_AP
|
||||
[9]
|
||||
pid=36
|
||||
ac_adjust=0
|
||||
dr_adjust=-35
|
||||
dam_mult=1
|
||||
dam_div=2
|
||||
|
||||
; PID_ROCKET_AP
|
||||
[10]
|
||||
pid=37
|
||||
ac_adjust=-15
|
||||
dr_adjust=-50
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_SMALL_ENERGY_CELL
|
||||
[11]
|
||||
pid=38
|
||||
ac_adjust=0
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_MICRO_FUSION_CELL
|
||||
[12]
|
||||
pid=39
|
||||
ac_adjust=0
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_SHOTGUN_SHELLS
|
||||
[13]
|
||||
pid=95
|
||||
ac_adjust=-10
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_44_FMJ_MAGNUM
|
||||
[14]
|
||||
pid=111
|
||||
ac_adjust=0
|
||||
dr_adjust=-20
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_9MM_BALL
|
||||
[15]
|
||||
pid=121
|
||||
ac_adjust=0
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_BBS
|
||||
[16]
|
||||
pid=163
|
||||
ac_adjust=0
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_ROBO_ROCKET_AMMO
|
||||
[17]
|
||||
pid=274
|
||||
ac_adjust=0
|
||||
dr_adjust=-25
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_45_CALIBER_AMMO
|
||||
[18]
|
||||
pid=357
|
||||
ac_adjust=0
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_2MM_EC_AMMO
|
||||
[19]
|
||||
pid=358
|
||||
ac_adjust=-30
|
||||
dr_adjust=-20
|
||||
dam_mult=3
|
||||
dam_div=2
|
||||
|
||||
; PID_4_7MM_CASELESS
|
||||
[20]
|
||||
pid=359
|
||||
ac_adjust=-5
|
||||
dr_adjust=-10
|
||||
dam_mult=3
|
||||
dam_div=2
|
||||
|
||||
; PID_9MM_AMMO
|
||||
[21]
|
||||
pid=360
|
||||
ac_adjust=0
|
||||
dr_adjust=10
|
||||
dam_mult=1
|
||||
dam_div=2
|
||||
|
||||
; PID_HN_NEEDLER_CARTRIDGE
|
||||
[22]
|
||||
pid=361
|
||||
ac_adjust=-10
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_HN_AP_NEEDLER_CARTRIDGE
|
||||
[23]
|
||||
pid=362
|
||||
ac_adjust=-10
|
||||
dr_adjust=0
|
||||
dam_mult=2
|
||||
dam_div=1
|
||||
|
||||
; PID_7_62MM_AMMO
|
||||
[24]
|
||||
pid=363
|
||||
ac_adjust=-5
|
||||
dr_adjust=-10
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
|
||||
; PID_FLAMETHROWER_FUEL_MK_II
|
||||
[25]
|
||||
pid=382
|
||||
ac_adjust=-20
|
||||
dr_adjust=0
|
||||
dam_mult=1
|
||||
dam_div=1
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
A basic example of how to use set_spray_settings function for script-based burst control
|
||||
*/
|
||||
|
||||
#include "..\headers\define.h"
|
||||
#include "..\headers\sfall\define_extra.h"
|
||||
#include "..\headers\sfall\sfall.h"
|
||||
|
||||
procedure start;
|
||||
procedure ammocost_handler;
|
||||
|
||||
procedure start begin
|
||||
if game_loaded then begin
|
||||
register_hook_proc(HOOK_AMMOCOST, ammocost_handler);
|
||||
end
|
||||
end
|
||||
|
||||
procedure ammocost_handler begin
|
||||
variable
|
||||
weapon := get_sfall_arg,
|
||||
bullets := get_sfall_arg,
|
||||
cost := get_sfall_arg,
|
||||
event := get_sfall_arg;
|
||||
|
||||
if (event == 2 and weapon > 0) then begin // when calculating number of burst rounds
|
||||
if (obj_pid(weapon) == PID_ASSAULT_RIFLE) then begin
|
||||
set_spray_settings(1, 1, 1, 1); // burst attack will not hit other targets
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,28 +1,69 @@
|
||||
/*
|
||||
Example algorithm of how the game engine calculates combat damage
|
||||
This script reimplements the combat damage calculation of the original game.
|
||||
Use this to implement your own damage formula!
|
||||
*/
|
||||
|
||||
#include "..\headers\define.h"
|
||||
#include "..\headers\command.h"
|
||||
#include "..\headers\sfall\sfall.h"
|
||||
#include "..\headers\sfall\define_extra.h"
|
||||
#include "../sfall/define_lite.h"
|
||||
#include "../sfall/define_extra.h"
|
||||
#include "../sfall/sfall.h"
|
||||
|
||||
#define DAMAGE_FORMULA_VANILLA (0)
|
||||
#define DAMAGE_FORMULA_GLOVZ (1)
|
||||
#define DAMAGE_FORMULA_GLOVZ2 (2)
|
||||
#define DAMAGE_FORMULA_YAAM (5)
|
||||
|
||||
procedure start;
|
||||
procedure compute_damage_F2;
|
||||
procedure item_w_damage_hook;
|
||||
procedure combatdamage_handler;
|
||||
procedure itemdamage_handler;
|
||||
procedure calc_damage_YAAM(variable weapon, variable rounds, variable armorDT, variable armorDR, variable bonusRangedDamage, variable multiplyDamage, variable difficulty);
|
||||
procedure item_w_subtype(variable weapon, variable hit_mode);
|
||||
procedure get_ammo_value(variable weapon, variable param);
|
||||
|
||||
variable item_w_damage;
|
||||
variable
|
||||
damage_formula,
|
||||
item_damage_min,
|
||||
item_damage_max,
|
||||
item_damage_weapon,
|
||||
item_damage_attacker;
|
||||
|
||||
procedure start begin
|
||||
if game_loaded then begin
|
||||
register_hook_proc(HOOK_COMBATDAMAGE, compute_damage_F2);
|
||||
register_hook_proc(HOOK_ITEMDAMAGE, item_w_damage_hook);
|
||||
damage_formula := get_ini_setting("ddraw.ini|Misc|DamageFormula");
|
||||
register_hook_proc(HOOK_COMBATDAMAGE, combatdamage_handler);
|
||||
register_hook_proc(HOOK_ITEMDAMAGE, itemdamage_handler);
|
||||
end
|
||||
end
|
||||
|
||||
procedure compute_damage_F2 begin
|
||||
/*
|
||||
HOOK_COMBATDAMAGE
|
||||
|
||||
Runs when:
|
||||
1) Game calculates how much damage each target will get. This includes primary target as well as all extras (explosions and bursts). This happens BEFORE the actual attack animation.
|
||||
2) AI decides whether it is safe to use area attack (burst, grenades), if he might hit friendlies.
|
||||
|
||||
Does not run for misses, or non-combat damage like dynamite explosions.
|
||||
|
||||
Critter arg0 - The target
|
||||
Critter arg1 - The attacker
|
||||
int arg2 - The amount of damage to the target
|
||||
int arg3 - The amount of damage to the attacker
|
||||
int arg4 - The special effect flags for the target (use bwand DAM_* to check specific flags)
|
||||
int arg5 - The special effect flags for the attacker (use bwand DAM_* to check specific flags)
|
||||
Item arg6 - The weapon used in the attack
|
||||
int arg7 - The bodypart that was struck
|
||||
int arg8 - Damage Multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2; for critical hits, the value is taken from the critical table; with Silent Death perk and the corresponding attack conditions, the value will be doubled)
|
||||
int arg9 - Number of bullets actually hit the target (1 for melee attacks)
|
||||
int arg10 - The amount of knockback to the target
|
||||
int arg11 - Attack Type (see ATKTYPE_* constants)
|
||||
mixed arg12 - computed attack data (see C_ATTACK_* for offsets and use get/set_object_data functions to get/set the data)
|
||||
|
||||
int ret0 - The damage to the target
|
||||
int ret1 - The damage to the attacker
|
||||
int ret2 - The special effect flags for the target
|
||||
int ret3 - The special effect flags for the attacker
|
||||
int ret4 - The amount of knockback to the target
|
||||
*/
|
||||
procedure combatdamage_handler begin
|
||||
variable dmg_type, weapon_perk, dmg_thresh, dmg_resist, weapon_subtype, bonus_ranged, difficulty, i, dmg_mult, dmg_div, damage;
|
||||
variable target, flags, knockback, amount;
|
||||
|
||||
@@ -40,6 +81,11 @@ procedure compute_damage_F2 begin
|
||||
amountKnockback := get_sfall_arg,
|
||||
hit_mode := get_sfall_arg;
|
||||
|
||||
if (ctdSource != item_damage_attacker or weapon != item_damage_weapon) then begin
|
||||
debug_msg("! ERROR ! compute_damage: Expected attacker or weapon differs!");
|
||||
return;
|
||||
end
|
||||
|
||||
if (flagsSource bwand DAM_HIT) then begin
|
||||
target := ctdTarget;
|
||||
flags := flagsTarget;
|
||||
@@ -50,7 +96,6 @@ procedure compute_damage_F2 begin
|
||||
knockback := 0;
|
||||
end
|
||||
|
||||
//amount := 0;
|
||||
if target and (obj_type(target) == OBJ_TYPE_CRITTER) then begin
|
||||
if weapon then begin
|
||||
dmg_type := weapon_dmg_type(weapon);
|
||||
@@ -77,7 +122,7 @@ procedure compute_damage_F2 begin
|
||||
end
|
||||
|
||||
weapon_subtype := item_w_subtype(weapon, hit_mode); // item_w_subtype_
|
||||
if (ctdSource != dude_obj) or (weapon_subtype != WEAPON_TYPE_GUNS) then
|
||||
if (ctdSource != dude_obj) or (weapon_subtype != WEAPON_TYPE_RANGED) then
|
||||
bonus_ranged := 0;
|
||||
else
|
||||
bonus_ranged := has_trait(TRAIT_PERK, ctdSource, PERK_bonus_ranged_damage) * 2;
|
||||
@@ -90,27 +135,31 @@ procedure compute_damage_F2 begin
|
||||
difficulty := 125;
|
||||
end
|
||||
|
||||
// F2 default start
|
||||
// Damage = (1 - (DR_armor + DR_ammo_adjust) * (((raw_damage * (dmg_mult * damageMultiplier)) / dmg_div) - dmg_thresh)
|
||||
dmg_resist += get_ammo_value(weapon, PROTO_AM_DR_MOD); // item_w_dr_adjust_ (DR Adjust %)
|
||||
if (dmg_resist < 100) then begin
|
||||
if (dmg_resist < 0) then dmg_resist := 0;
|
||||
if (damage_formula == DAMAGE_FORMULA_YAAM) then begin
|
||||
amount := calc_damage_YAAM(weapon, rounds, dmg_thresh, dmg_resist, bonus_ranged, damageMultiplier, difficulty);
|
||||
end else begin
|
||||
// F2 default start
|
||||
// Damage = (1 - (DR_armor + DR_ammo_adjust) * (((raw_damage * (dmg_mult * damageMultiplier)) / dmg_div) - dmg_thresh)
|
||||
dmg_resist += get_ammo_value(weapon, PROTO_AM_DR_MOD); // item_w_dr_adjust_ (DR Adjust %)
|
||||
if (dmg_resist < 100) then begin
|
||||
if (dmg_resist < 0) then dmg_resist := 0;
|
||||
|
||||
dmg_mult := damageMultiplier * get_ammo_value(weapon, PROTO_AM_DMG_MULT); // item_w_dam_mult_ (Dmg mod A)
|
||||
dmg_div := get_ammo_value(weapon, PROTO_AM_DMG_DIV); // item_w_dam_div_ (Dmg mod B)
|
||||
dmg_mult := damageMultiplier * get_ammo_value(weapon, PROTO_AM_DMG_MULT); // item_w_dam_mult_ (Dmg mod A)
|
||||
dmg_div := get_ammo_value(weapon, PROTO_AM_DMG_DIV); // item_w_dam_div_ (Dmg mod B)
|
||||
|
||||
for (i := 1; i <= rounds; i++) begin
|
||||
damage := (item_w_damage + bonus_ranged) * dmg_mult; // item_w_damage_ (raw_damage)
|
||||
if dmg_div then damage /= dmg_div;
|
||||
for (i := 1; i <= rounds; i++) begin
|
||||
damage := (random(item_damage_min, item_damage_max) + bonus_ranged) * dmg_mult; // item_w_damage_ (raw_damage)
|
||||
if dmg_div then damage /= dmg_div;
|
||||
|
||||
damage := (((damage / 2) * difficulty) / 100) - dmg_thresh;
|
||||
if (damage > 0) then begin
|
||||
damage := damage - ((damage * dmg_resist) / 100); // reduce damage by the percentage of DR_armor + DR_Ammo
|
||||
if (damage > 0) then amount += damage;
|
||||
damage := (((damage / 2) * difficulty) / 100) - dmg_thresh;
|
||||
if (damage > 0) then begin
|
||||
damage := damage - ((damage * dmg_resist) / 100); // reduce damage by the percentage of DR_armor + DR_Ammo
|
||||
if (damage > 0) then amount += damage;
|
||||
end
|
||||
end
|
||||
end
|
||||
// F2 default end
|
||||
end
|
||||
// F2 default end
|
||||
|
||||
if (ctdSource == dude_obj) then begin
|
||||
if has_trait(TRAIT_PERK, ctdSource, PERK_living_anatomy_perk) and (critter_kill_type(ctdTarget) != KILL_TYPE_robot_kills)
|
||||
@@ -140,11 +189,11 @@ procedure compute_damage_F2 begin
|
||||
end
|
||||
|
||||
if (flagsSource bwand DAM_HIT) then begin
|
||||
display_msg("amountTarget = " + amountTarget+ ", amount = " + amount);
|
||||
display_msg("COMBATDAMAGE amountTarget = " + amountTarget+ ", amount = " + amount);
|
||||
amountTarget := amount;
|
||||
flagsTarget := flags;
|
||||
end else begin
|
||||
display_msg("amountSource = " + amountSource+ ", amount = " + amount);
|
||||
display_msg("COMBATDAMAGE amountSource = " + amountSource+ ", amount = " + amount);
|
||||
amountSource := amount;
|
||||
flagsSource := flags;
|
||||
end
|
||||
@@ -154,40 +203,118 @@ procedure compute_damage_F2 begin
|
||||
set_sfall_return(flagsTarget);
|
||||
set_sfall_return(flagsSource);
|
||||
set_sfall_return(amountKnockback);
|
||||
|
||||
set_sfall_arg(2, amountTarget);
|
||||
set_sfall_arg(3, amountSource);
|
||||
set_sfall_arg(4, flagsTarget);
|
||||
set_sfall_arg(5, flagsSource);
|
||||
set_sfall_arg(10, amountKnockback);
|
||||
end
|
||||
|
||||
procedure item_w_damage_hook begin
|
||||
variable
|
||||
item_w_damage_min := get_sfall_arg,
|
||||
item_w_damage_max := get_sfall_arg;
|
||||
//weapon := get_sfall_arg,
|
||||
//source := get_sfall_arg,
|
||||
procedure calc_damage_YAAM(variable weapon, variable rounds, variable armorDT, variable armorDR, variable bonusRangedDamage, variable multiplyDamage, variable difficulty) begin
|
||||
variable accumulatedDamage, ammoDiv, ammoMult, ammoDT, calcDT, _calcDT, calcDR, i, rawDamage, resistedDamage;
|
||||
if (rounds <= 0) then begin
|
||||
return 0;
|
||||
end
|
||||
|
||||
ammoDiv := get_ammo_value(weapon, PROTO_AM_DMG_DIV);
|
||||
ammoMult := get_ammo_value(weapon, PROTO_AM_DMG_MULT);
|
||||
|
||||
// Damage Multipler = Critical Multipler * Ammo Dividend
|
||||
multiplyDamage *= ammoMult;
|
||||
|
||||
// Retrieve ammo DT (well, it's really Retrieve ammo DR, but since we're treating ammo DR as ammo DT...)
|
||||
ammoDT := get_ammo_value(weapon, PROTO_AM_DR_MOD);
|
||||
|
||||
calcDT := armorDT - ammoDT;
|
||||
_calcDT := calcDT;
|
||||
|
||||
if (calcDT >= 0) then begin
|
||||
_calcDT := 0;
|
||||
end else begin
|
||||
// note that this should be a negative value
|
||||
_calcDT *= 10;
|
||||
calcDT := 0;
|
||||
end
|
||||
|
||||
// DR = armor DR + DT (note that DT should be less than or equal to zero)
|
||||
calcDR = armorDR + _calcDT;
|
||||
if (calcDR < 0) then begin
|
||||
calcDR = 0;
|
||||
end else if (calcDR >= 100) then begin
|
||||
return 0;
|
||||
end
|
||||
|
||||
display_msg("YAAM: AmmoDT=" + ammoDT + ", DT=" + calcDT + "/" + armorDT + ", DR=" + calcDR + "/" + armorDR);
|
||||
// Start of damage calculation loop
|
||||
for (i := 0; i < rounds; i++) begin
|
||||
rawDamage = random(item_damage_min, item_damage_max);
|
||||
rawDamage += bonusRangedDamage;
|
||||
|
||||
rawDamage -= calcDT;
|
||||
if (rawDamage <= 0) then
|
||||
continue;
|
||||
|
||||
rawDamage *= multiplyDamage;
|
||||
if (ammoDiv != 0) then begin
|
||||
rawDamage /= ammoDiv;
|
||||
end
|
||||
rawDamage /= 2; // related to critical hit damage multiplier bonus
|
||||
rawDamage *= difficulty; // combat difficulty setting (75 if wimpy, 100 if normal or if attacker is player, 125 if rough)
|
||||
rawDamage /= 100;
|
||||
|
||||
resistedDamage = calcDR * rawDamage;
|
||||
resistedDamage /= 100;
|
||||
rawDamage -= resistedDamage;
|
||||
|
||||
if (rawDamage > 0) then begin
|
||||
display_msg("YAAM: Bullet " + i + " dmg=" + rawDamage);
|
||||
accumulatedDamage += rawDamage;
|
||||
end
|
||||
end
|
||||
return accumulatedDamage;
|
||||
end
|
||||
|
||||
/*
|
||||
HOOK_ITEMDAMAGE
|
||||
|
||||
Runs when retrieving the damage rating of the player's used weapon. (Which may be their fists.)
|
||||
|
||||
int arg0 - The default min damage
|
||||
int arg1 - The default max damage
|
||||
Item arg2 - The weapon used (0 if unarmed)
|
||||
Critter arg3 - The critter doing the attacking
|
||||
int arg4 - The type of attack
|
||||
int arg5 - non-zero if this is an attack using a melee weapon
|
||||
|
||||
int ret0 - Either the damage to be used, if ret1 isn't given, or the new minimum damage if it is
|
||||
int ret1 - The new maximum damage
|
||||
*/
|
||||
procedure itemdamage_handler begin
|
||||
item_damage_min := get_sfall_arg;
|
||||
item_damage_max := get_sfall_arg;
|
||||
item_damage_weapon := get_sfall_arg;
|
||||
item_damage_attacker := get_sfall_arg;
|
||||
//hit_mode := get_sfall_arg,
|
||||
//isMelee := get_sfall_arg;
|
||||
|
||||
item_w_damage := (item_w_damage_min + (item_w_damage_max - item_w_damage_min) / 2);
|
||||
display_msg("item_w_damage_ = " + item_w_damage);
|
||||
|
||||
set_sfall_return(item_w_damage);
|
||||
display_msg("itemdamage: " + item_damage_min + "-" + item_damage_max);
|
||||
end
|
||||
|
||||
procedure item_w_subtype(variable weapon, variable hit_mode) begin
|
||||
variable attack_mode, type := WEAPON_TYPE_UNARMED;
|
||||
|
||||
if weapon and (hit_mode <= ATKTYPE_RWEP2) then begin
|
||||
attack_mode := (get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS));
|
||||
attack_mode := weapon_attack_mode(obj_pid(weapon), hit_mode);
|
||||
|
||||
if (hit_mode == ATKTYPE_LWEP2) or (hit_mode == ATKTYPE_RWEP2) then
|
||||
attack_mode := (attack_mode bwand 0xF0) / 16; // shift 4 bits to the right
|
||||
else
|
||||
attack_mode := (attack_mode bwand 0x0F);
|
||||
|
||||
if (attack_mode > ATKMODE_PRI_THROW) then
|
||||
type := WEAPON_TYPE_GUNS;
|
||||
else if (attack_mode == ATKMODE_PRI_THROW) then
|
||||
if (attack_mode >= ATTACK_MODE_SINGLE) then
|
||||
type := WEAPON_TYPE_RANGED;
|
||||
else if (attack_mode == ATTACK_MODE_THROW) then
|
||||
type := WEAPON_TYPE_THROWN;
|
||||
else if (attack_mode > ATKMODE_PRI_KICK) then
|
||||
else if (attack_mode >= ATTACK_MODE_SWING) then
|
||||
type := WEAPON_TYPE_MELEE;
|
||||
else if (attack_mode == ATTACK_MODE_NONE) then
|
||||
type := WEAPON_TYPE_NONE;
|
||||
end
|
||||
|
||||
return type;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Example implementation of the algorithm of how the game engine sets the explosive timer.
|
||||
*/
|
||||
|
||||
#include "..\..\scripting_docs\headers\sfall.h"
|
||||
#include "..\..\scripting_docs\headers\define_lite.h"
|
||||
|
||||
// from CONDTION.H
|
||||
#define ROLL_CRITICAL_FAILURE (0)
|
||||
#define ROLL_FAILURE (1)
|
||||
#define ROLL_SUCCESS (2)
|
||||
#define ROLL_CRITICAL_SUCCESS (3)
|
||||
|
||||
procedure start;
|
||||
|
||||
procedure start begin
|
||||
if game_loaded then begin
|
||||
register_hook(HOOK_EXPLOSIVETIMER);
|
||||
end else begin
|
||||
variable
|
||||
time := get_sfall_arg,
|
||||
result := ROLL_CRITICAL_FAILURE;
|
||||
|
||||
if has_trait(TRAIT_PERK, dude_obj, PERK_demolition_expert_perk) then
|
||||
result := ROLL_SUCCESS;
|
||||
else begin
|
||||
result := roll_vs_skill(dude_obj, SKILL_TRAPS, 0);
|
||||
end
|
||||
|
||||
if (result) then begin
|
||||
if (result == ROLL_FAILURE) then
|
||||
time /= 2;
|
||||
else begin // success or critical success
|
||||
result := ROLL_SUCCESS;
|
||||
end
|
||||
end else begin // critical failure
|
||||
time := 0;
|
||||
result := ROLL_FAILURE;
|
||||
end
|
||||
|
||||
set_sfall_return(time);
|
||||
set_sfall_return(result); // failure/success
|
||||
end
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
This script reimplements the healing skills of the original game.
|
||||
This version uses a refactored code with no less code duplication, but potentially some minor differences from vanilla.
|
||||
You can use this to make any tweaks you want to these skills.
|
||||
*/
|
||||
|
||||
#include "../../scripting/headers/define_lite.h"
|
||||
#include "../../scripting/headers/define_extra.h"
|
||||
#include "../../scripting/headers/sfall.h"
|
||||
#include "../../scripting/headers/lib.arrays.h"
|
||||
#include "../../scripting/headers/lib.math.h"
|
||||
|
||||
#define PID_FIRST_AID_KIT (47)
|
||||
#define PID_DOCTORS_BAG (91)
|
||||
#define PID_FIELD_MEDIC_KIT (408)
|
||||
#define PID_PARAMEDICS_BAG (409)
|
||||
|
||||
#define DAM_CRIP (DAM_CRIP_ARM_LEFT bwor DAM_CRIP_ARM_RIGHT bwor DAM_CRIP_LEG_LEFT bwor DAM_CRIP_LEG_RIGHT bwor DAM_BLIND)
|
||||
#define COMBAT_STATE_FLEEING (4)
|
||||
|
||||
#define critter_max_hp(cr) get_critter_stat(cr, STAT_max_hit_points)
|
||||
#define critter_cur_hp(cr) get_critter_stat(cr, STAT_current_hp)
|
||||
#define critter_has_dmg_flag(cr, flag) ((get_object_data(cr, OBJ_DATA_DAMAGE_FLAGS) bwand flag) != 0)
|
||||
|
||||
#define clear_critter_flag(cr, offset, flag) set_object_data(cr, offset, get_object_data(cr, offset) bwand bwnot(flag))
|
||||
#define clear_critter_dmg_flag(cr, flag) clear_critter_flag(cr, OBJ_DATA_DAMAGE_FLAGS, flag)
|
||||
#define clear_critter_combat_flag(cr, flag) clear_critter_flag(cr, OBJ_DATA_COMBAT_STATE, flag)
|
||||
|
||||
#define SKILLS_MAX_USES_PER_DAY (3)
|
||||
|
||||
variable times_skill_used, healable_damage_flags;
|
||||
|
||||
procedure skill_use_slot_available(variable skill) begin
|
||||
variable slot, time, hoursSinceLastUsage, timesUsed;
|
||||
|
||||
// Lazy init array
|
||||
if (not times_skill_used) then
|
||||
times_skill_used := create_array_map;
|
||||
|
||||
if (not times_skill_used[skill]) then
|
||||
times_skill_used[skill] := create_array_list(SKILLS_MAX_USES_PER_DAY);
|
||||
|
||||
timesUsed := times_skill_used[skill];
|
||||
for (slot := 0; slot < SKILLS_MAX_USES_PER_DAY; slot++) begin
|
||||
if (timesUsed[slot] == 0) then
|
||||
return slot;
|
||||
end
|
||||
time := game_time;
|
||||
hoursSinceLastUsage = (time - timesUsed[0]) / ONE_GAME_HOUR;
|
||||
if (hoursSinceLastUsage <= 24) then begin
|
||||
return -1;
|
||||
end
|
||||
return SKILLS_MAX_USES_PER_DAY - 1;
|
||||
end
|
||||
|
||||
procedure skill_use_slot_add(variable skill) begin
|
||||
variable i, timesUsed,
|
||||
slot := skill_use_slot_available(skill);
|
||||
|
||||
if (slot == -1) then
|
||||
return -1;
|
||||
|
||||
timesUsed := times_skill_used[skill];
|
||||
if (timesUsed[slot] != 0) then begin
|
||||
// Shift all earlier use times to make use for the new time.
|
||||
for (i := 0; i < slot; i++) begin
|
||||
timesUsed[i] := timesUsed[i + 1];
|
||||
end
|
||||
end
|
||||
|
||||
timesUsed[slot] = game_time;
|
||||
return 0;
|
||||
end
|
||||
|
||||
procedure critter_is_dead(variable critter) begin
|
||||
if (not critter) then
|
||||
return false;
|
||||
|
||||
if (obj_type(critter) != OBJ_TYPE_CRITTER) then
|
||||
return false;
|
||||
|
||||
if (critter_cur_hp(critter) <= 0) then
|
||||
return true;
|
||||
|
||||
if (is_critter_dead(critter) != 0) then
|
||||
return true;
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
procedure critter_body_type(variable critter) begin
|
||||
if (not critter) then begin
|
||||
debug_msg("\nError: critter_body_type: pobj was NULL!");
|
||||
return CR_BODY_BIPED;
|
||||
end
|
||||
|
||||
if (obj_type(critter) != OBJ_TYPE_CRITTER) then
|
||||
return CR_BODY_BIPED;
|
||||
|
||||
return proto_data(obj_pid(critter), cr_body_type);
|
||||
end
|
||||
|
||||
procedure critter_is_crippled(variable critter) begin
|
||||
if (not critter) then
|
||||
return false;
|
||||
|
||||
if (obj_type(critter) != OBJ_TYPE_CRITTER) then
|
||||
return false;
|
||||
|
||||
return critter_has_dmg_flag(critter, DAM_CRIP);
|
||||
end
|
||||
|
||||
procedure get_skill_xp(variable skill) begin
|
||||
switch (skill) begin
|
||||
case SKILL_FIRST_AID: return 25;
|
||||
// case SKILL_REPAIR: return 0; // no exp for repair skill in vanilla!
|
||||
case SKILL_DOCTOR: return 50;
|
||||
default: return 0;
|
||||
end
|
||||
end
|
||||
|
||||
procedure show_skill_use_messages(variable skill, variable successCount := 1) begin
|
||||
variable baseExp, xpToAdd, before, after;
|
||||
if (successCount <= 0) then return;
|
||||
|
||||
baseExp = get_skill_xp(skill);
|
||||
if (baseExp == 0) then return;
|
||||
|
||||
xpToAdd = successCount * baseExp;
|
||||
|
||||
before = get_pc_stat(PCSTAT_experience);
|
||||
|
||||
give_exp_points(xpToAdd);
|
||||
|
||||
after = get_pc_stat(PCSTAT_experience);
|
||||
display_msg(sprintf(mstr_skill(505), after - before));
|
||||
end
|
||||
|
||||
variable sfall_ini_RemoveCriticalTimelimits := -2;
|
||||
|
||||
/**
|
||||
* Exactly like FO2 roll_check function, but without returning "how_much".
|
||||
* @arg {int} rollMod
|
||||
* @arg {int} critSuccessMod
|
||||
*/
|
||||
procedure roll_check(variable rollMod, variable critSuccessMod) begin
|
||||
variable
|
||||
delta := rollMod - random(1, 100),
|
||||
roll, criticalsAllowed;
|
||||
|
||||
if (sfall_ini_RemoveCriticalTimelimits == -2) then
|
||||
sfall_ini_RemoveCriticalTimelimits := get_ini_setting("ddraw.ini|Misc|RemoveCriticalTimelimits");
|
||||
|
||||
criticalsAllowed := (sfall_ini_RemoveCriticalTimelimits > 0) or (game_time >= ONE_GAME_DAY);
|
||||
|
||||
if (delta < 0) then begin
|
||||
return ROLL_CRITICAL_FAILURE
|
||||
if (criticalsAllowed and random(1, 100) <= -delta / 10)
|
||||
else ROLL_FAILURE;
|
||||
end
|
||||
return ROLL_CRITICAL_SUCCESS
|
||||
if (criticalsAllowed and random(1, 100) <= delta / 10 + critSuccessMod)
|
||||
else ROLL_SUCCESS;
|
||||
end
|
||||
|
||||
// 530: damaged eye
|
||||
// 531: crippled left arm
|
||||
// 532: crippled right arm
|
||||
// 533: crippled right leg
|
||||
// 534: crippled left leg
|
||||
#define display_uncrippled_msg(dmgFlagIdx, prefixMsgId) display_msg(sprintf(mstr_skill(prefixMsgId), mstr_skill(530 + dmgFlagIdx)))
|
||||
|
||||
|
||||
/**
|
||||
* A refactored version of skill_use function from the engine, for use with healing skills only. Returns true if skill use was actually attempted.
|
||||
* @arg {ObjectPtr} user
|
||||
* @arg {ObjectPtr} target
|
||||
* @arg {int} skill - First Aid, Doctor or Repair
|
||||
* @arg {int} skillBonus
|
||||
*/
|
||||
procedure use_healing_skill(variable user, variable target, variable skill, variable skillBonus) begin
|
||||
variable curHp, maxHp, healingAttempts, isRobot, isRepair, isFirstAid;
|
||||
|
||||
display_msg(string_format("use_healing_skill: user = %s, target = %s, bonus = %d, skill = %d", obj_name(user), obj_name(target), skillBonus, skill));
|
||||
|
||||
isRobot := (critter_body_type(target) == CR_BODY_ROBOTIC);
|
||||
isRepair := (skill == SKILL_REPAIR);
|
||||
if (isRepair and not isRobot) then begin
|
||||
// You cannot repair that.
|
||||
display_msg(mstr_skill(553));
|
||||
return false;
|
||||
end
|
||||
if (skill_use_slot_available(skill) == -1) then begin
|
||||
// 590: You've taxed your ability with that skill. Wait a while.
|
||||
// 591: You're too tired.
|
||||
// 592: The strain might kill you.
|
||||
display_msg(mstr_skill(590 + random(0, 2)));
|
||||
return false;
|
||||
end
|
||||
if (critter_is_dead(target)) then begin
|
||||
// 512: You can't heal the dead.
|
||||
// 513: Let the dead rest in peace.
|
||||
// 514: It's dead, get over it.
|
||||
display_msg(mstr_skill(512 + random(0, 2)));
|
||||
return false;
|
||||
end
|
||||
|
||||
isFirstAid := (skill == SKILL_FIRST_AID);
|
||||
|
||||
curHp := critter_cur_hp(target);
|
||||
maxHp := critter_max_hp(target);
|
||||
healingAttempts := 1;
|
||||
if (curHp < maxHp or (not isFirstAid and critter_is_crippled(target))) then begin
|
||||
variable skillUseSlotAdded, roll, i, prefixMsg,
|
||||
critChance := get_critter_stat(user, STAT_crit_chance) + skillBonus;
|
||||
|
||||
fade_out;
|
||||
|
||||
// Heal crippled limbs.
|
||||
if (not isFirstAid and (not isRepair or not isRobot) and critter_is_crippled(target)) then begin
|
||||
// Lazy init healable flags
|
||||
if (not healable_damage_flags) then
|
||||
healable_damage_flags := array_fixed([
|
||||
DAM_BLIND,
|
||||
DAM_CRIP_ARM_LEFT,
|
||||
DAM_CRIP_ARM_RIGHT,
|
||||
DAM_CRIP_LEG_RIGHT,
|
||||
DAM_CRIP_LEG_LEFT
|
||||
]);
|
||||
|
||||
for (i := 0; i < len_array(healable_damage_flags); i++) begin
|
||||
if (not critter_has_dmg_flag(target, healable_damage_flags[i])) then
|
||||
continue;
|
||||
|
||||
healingAttempts += 1;
|
||||
roll := roll_vs_skill(user, skill, critChance);
|
||||
if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin
|
||||
clear_critter_dmg_flag(target, healable_damage_flags[i]);
|
||||
clear_critter_combat_flag(target, COMBAT_STATE_FLEEING);
|
||||
// 520: You heal your %s.
|
||||
// 521: You heal the %s.
|
||||
display_uncrippled_msg(i, 520 if (target == dude_obj) else 521);
|
||||
call skill_use_slot_add(skill);
|
||||
skillUseSlotAdded := true;
|
||||
if (user == dude_obj) then
|
||||
call show_skill_use_messages(skill);
|
||||
end else begin
|
||||
// 525: You fail to heal your %s.
|
||||
// 526: You fail to heal the %s.
|
||||
display_uncrippled_msg(i, 525 if (target == dude_obj) else 526);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Restore hit points.
|
||||
roll := (roll_vs_skill(user, skill, critChance) if isFirstAid else roll_check(has_skill(user, skill), critChance))
|
||||
if (isRepair or not isRobot)
|
||||
else ROLL_FAILURE;
|
||||
|
||||
if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin
|
||||
variable
|
||||
minHpToHeal := (1 if isFirstAid else 4),
|
||||
maxHpToHeal := (5 if isFirstAid else 10),
|
||||
hpToHeal;
|
||||
if (user == dude_obj and not isRepair) then begin
|
||||
variable healerRank := has_trait(TRAIT_PERK, user, PERK_healer);
|
||||
minHpToHeal += 4 * healerRank;
|
||||
maxHpToHeal += 10 * healerRank;
|
||||
end
|
||||
hpToHeal = random(minHpToHeal, maxHpToHeal);
|
||||
critter_heal(target, hpToHeal);
|
||||
|
||||
if (user == dude_obj) then begin
|
||||
// You heal %d hit points.
|
||||
display_msg(sprintf(mstr_skill(500), math_min(maxHp - curHp, hpToHeal)));
|
||||
end
|
||||
|
||||
if (not skillUseSlotAdded) then
|
||||
call skill_use_slot_add(skill);
|
||||
|
||||
clear_critter_combat_flag(target, COMBAT_STATE_FLEEING);
|
||||
if (user == dude_obj) then
|
||||
call show_skill_use_messages(skill);
|
||||
end else begin
|
||||
// You fail to do any healing.
|
||||
display_msg(sprintf(mstr_skill(503), how_much(0)));
|
||||
end
|
||||
|
||||
fade_in;
|
||||
end else if (user == dude_obj) then begin
|
||||
// 501: You look healty already
|
||||
// 502: %s looks healthy already
|
||||
display_msg(mstr_skill(501)
|
||||
if (target == dude_obj)
|
||||
else sprintf(mstr_skill(502), obj_name(target)));
|
||||
end
|
||||
if (user == dude_obj) then begin
|
||||
game_time_advance((ONE_GAME_HOUR if (skill == SKILL_DOCTOR) else (30 * ONE_GAME_MINUTE)) * healingAttempts);
|
||||
end
|
||||
// TODO: not sure if this is needed
|
||||
//exec_map_update_scripts
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
/**
|
||||
* A partial copy of engine's protinst_use_item_on with code pertinent to healing skills. Returns value for set_sfall_return in useobjon_hook.
|
||||
* @arg {ObjectPtr} user - item user
|
||||
* @arg {ObjectPtr} target - target
|
||||
* @arg {ObjectPtr} item - item
|
||||
* @ret {bool}
|
||||
*/
|
||||
procedure protinst_use_item_on(variable user, variable target, variable item) begin
|
||||
variable begin
|
||||
messageId := -1;
|
||||
skillBonus := 0;
|
||||
skill := -1;
|
||||
end
|
||||
switch (obj_pid(item)) begin
|
||||
case PID_DOCTORS_BAG: begin
|
||||
// The supplies in the Doctor's Bag run out.
|
||||
messageId = 900;
|
||||
skillBonus = 20;
|
||||
skill = SKILL_DOCTOR;
|
||||
end
|
||||
case PID_FIRST_AID_KIT: begin
|
||||
// The supplies in the First Aid Kit run out.
|
||||
messageId = 901;
|
||||
skillBonus = 20;
|
||||
skill = SKILL_FIRST_AID;
|
||||
end
|
||||
case PID_PARAMEDICS_BAG: begin
|
||||
// The supplies in the Paramedic's Bag run out.
|
||||
messageId = 910;
|
||||
skillBonus = 40;
|
||||
skill = SKILL_DOCTOR;
|
||||
end
|
||||
case PID_FIELD_MEDIC_KIT: begin
|
||||
// The supplies in the Field Medic First Aid Kit run out.
|
||||
messageId = 911;
|
||||
skillBonus = 40;
|
||||
skill = SKILL_FIRST_AID;
|
||||
end
|
||||
end
|
||||
if (skill == -1) then
|
||||
return -1;
|
||||
|
||||
if (combat_is_initialized) then begin
|
||||
// You cannot do that in combat.
|
||||
if (user == dude_obj) then
|
||||
display_msg(mstr_proto(902));
|
||||
return 0;
|
||||
end
|
||||
|
||||
if (not use_healing_skill(user, target, skill, skillBonus)) then
|
||||
return 0;
|
||||
|
||||
if (random(1, 10) != 1) then
|
||||
return 0;
|
||||
|
||||
if (user == dude_obj) then
|
||||
display_msg(mstr_proto(messageId));
|
||||
|
||||
return 1;
|
||||
end
|
||||
|
||||
/*
|
||||
Runs when:
|
||||
|
||||
a critter uses an object on another critter. (Or themselves)
|
||||
a critter uses an object from inventory screen AND this object does not have "Use" action flag set and it's not active flare or explosive.
|
||||
player or AI uses any drug
|
||||
This is fired before the object is used, and the relevant use_obj_on script procedures are run. You can disable default item behavior.
|
||||
|
||||
NOTE: You can't remove and/or destroy this object during the hookscript (game will crash otherwise). To remove it, return 1.
|
||||
|
||||
Critter arg0 - The target
|
||||
Critter arg1 - The user
|
||||
int arg2 - The object used
|
||||
|
||||
int ret0 - overrides hard-coded handler and selects what should happen with the item (0 - place it back, 1 - remove it, -1 - use engine handler)
|
||||
*/
|
||||
procedure useobjon_hook begin
|
||||
variable
|
||||
target := get_sfall_arg,
|
||||
user := get_sfall_arg,
|
||||
item := get_sfall_arg,
|
||||
useItemResult;
|
||||
|
||||
useItemResult := protinst_use_item_on(user, target, item);
|
||||
if (useItemResult != -1) then
|
||||
set_sfall_return(useItemResult);
|
||||
end
|
||||
|
||||
/*
|
||||
Runs when using any skill on any object.
|
||||
|
||||
This is fired before the default handlers are called, which you can override. In this case you should write your own skill use handler entirely, or otherwise nothing will happen (this includes fade in/fade out, time lapsing and messages - all of this can be scripted; to get vanilla text messages - use message_str_game along with sprintf). Suggested use - override First Aid/Doctor skills to buff/nerf them, override Steal skill to disallow observing NPCs inventories in some cases.
|
||||
|
||||
Does not run if the script of the object calls script_overrides for using the skill.
|
||||
|
||||
Critter arg0 - The user critter
|
||||
Obj arg1 - The target object
|
||||
int arg2 - skill being used
|
||||
int arg3 - skill bonus from items such as first aid kits
|
||||
|
||||
int ret0 - overrides hard-coded handler (-1 - use engine handler, any other value - override; if it is 0, there will be a 10% chance of removing the used medical item)
|
||||
*/
|
||||
procedure useskill_hook begin
|
||||
variable
|
||||
user := get_sfall_arg,
|
||||
target := get_sfall_arg,
|
||||
skill := get_sfall_arg,
|
||||
skillBonus := get_sfall_arg,
|
||||
isSuccess;
|
||||
|
||||
if (skill == SKILL_FIRST_AID or skill == SKILL_DOCTOR or skill == SKILL_REPAIR) then begin
|
||||
isSuccess := use_healing_skill(user, target, skill, skillBonus);
|
||||
set_sfall_return(0 if isSuccess else 1);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
procedure start begin
|
||||
if (game_loaded) then begin
|
||||
register_hook_proc(HOOK_USEOBJON, useobjon_hook);
|
||||
register_hook_proc(HOOK_USESKILL, useskill_hook);
|
||||
end
|
||||
end
|
||||
Binary file not shown.
@@ -1,11 +1,13 @@
|
||||
/**
|
||||
|
||||
Item Highlight mod (Lite version)
|
||||
Item Highlighting mod (Lite version)
|
||||
|
||||
A cut-down version of the mod included in sfall 4.x, offers a bit more features than the built-in function.
|
||||
A cut-down version of the mod included in sfall 4.x, offering more features than the built-in function.
|
||||
Features:
|
||||
- highlighting items, containers (optional) and lootable corpses (optional) on the ground
|
||||
- highlights items, containers (optional) and lootable corpses (optional) on the ground
|
||||
- highlights critters using the same rules as combat mode highlighting (optional)
|
||||
- configurable hotkey is used to trigger highlight
|
||||
- hotkey can be pressed and held to continuously update highlighted objects based on current position
|
||||
- only objects in direct line-of-sight of player are highlighted (optional)
|
||||
- motion scanner is required to enable highlight (optional)
|
||||
- motion scanner charges are decreased on each use (optional)
|
||||
@@ -15,7 +17,7 @@
|
||||
NOTE: this script requires compiler from sfall modderspack with -s option
|
||||
(short circuit evaluation)
|
||||
|
||||
version 1.1
|
||||
version 1.3
|
||||
|
||||
**/
|
||||
|
||||
@@ -24,6 +26,7 @@
|
||||
|
||||
#define CRITTER_IS_DEAD (1)
|
||||
#define PID_MOTION_SENSOR (59)
|
||||
#define REPEAT_FRAMES (10)
|
||||
#define NO_HIGHLIGHT(obj) (get_flags(obj) bwand FLAG_NOHIGHLIGHT)
|
||||
#define NO_STEAL(obj) (get_proto_data(obj_pid(obj), PROTO_CR_FLAGS) bwand CFLG_NOSTEAL)
|
||||
|
||||
@@ -32,36 +35,78 @@ variable highlightKey;
|
||||
variable isHighlight;
|
||||
variable alsoContainer;
|
||||
variable alsoCorpse;
|
||||
variable alsoCritter;
|
||||
variable checkLOS;
|
||||
variable outlineColor;
|
||||
variable outlineColorContainers;
|
||||
variable outlineColorCorpses;
|
||||
variable motionScanner;
|
||||
variable highlightFailMsg1;
|
||||
variable highlightFailMsg2;
|
||||
|
||||
procedure ToggleHighlightObject(variable obj, variable enable) begin
|
||||
if obj and (not enable or not checkLOS or not obj_blocking_line(dude_obj, tile_num(obj), BLOCKING_TYPE_SHOOT)) then begin
|
||||
if (alsoContainer and obj_item_subtype(obj) == item_type_container) or (not NO_HIGHLIGHT(obj)) then begin
|
||||
if (enable) then set_outline(obj, outlineColor);
|
||||
else set_outline(obj, 0);
|
||||
procedure DudeCanSee(variable obj) begin
|
||||
variable block := obj_blocking_line(dude_obj, tile_num(obj), BLOCKING_TYPE_SHOOT);
|
||||
return not block or block == obj;
|
||||
end
|
||||
|
||||
procedure DudeCanHear(variable obj) begin
|
||||
variable hearDist := dude_perception * 5;
|
||||
if (get_flags(obj) bwand FLAG_TRANSGLASS) then
|
||||
hearDist /= 2;
|
||||
|
||||
return tile_distance_objs(dude_obj, obj) <= hearDist;
|
||||
end
|
||||
|
||||
procedure GetOutlineColor(variable obj, variable isCritter) begin
|
||||
if isCritter then begin
|
||||
if get_team(obj) == get_team(dude_obj) then return OUTLINE_GREEN_GLOW;
|
||||
if not DudeCanSee(obj) then begin
|
||||
if (DudeCanHear(obj)) then return OUTLINE_DARK_YELLOW;
|
||||
return 0;
|
||||
end
|
||||
return OUTLINE_RED_GLOW;
|
||||
end
|
||||
if checkLOS and not DudeCanSee(obj) then
|
||||
return 0;
|
||||
|
||||
if obj_type(obj) == OBJ_TYPE_CRITTER then
|
||||
return outlineColorCorpses;
|
||||
|
||||
if obj_item_subtype(obj) == item_type_container then
|
||||
return outlineColorContainers;
|
||||
|
||||
return outlineColor;
|
||||
end
|
||||
|
||||
procedure ToggleHighlightObject(variable obj, variable enable, variable isCritter) begin
|
||||
if (not alsoContainer or obj_item_subtype(obj) != item_type_container) and NO_HIGHLIGHT(obj) then return;
|
||||
|
||||
set_outline(obj, GetOutlineColor(obj, isCritter) if enable else 0);
|
||||
end
|
||||
|
||||
procedure ToggleHighlight(variable enable) begin
|
||||
variable obj;
|
||||
variable obj, isCorpse;
|
||||
foreach obj in list_as_array(LIST_GROUNDITEMS) begin
|
||||
if obj != outlined_object then begin
|
||||
call ToggleHighlightObject(obj, enable);
|
||||
if obj and obj != outlined_object then begin
|
||||
call ToggleHighlightObject(obj, enable, false);
|
||||
end
|
||||
end
|
||||
if (alsoCorpse) then begin
|
||||
if (alsoCorpse or alsoCritter) then begin
|
||||
foreach obj in list_as_array(LIST_CRITTERS) begin
|
||||
if critter_state(obj) == CRITTER_IS_DEAD and not NO_STEAL(obj) then begin
|
||||
call ToggleHighlightObject(obj, enable);
|
||||
if obj and obj != dude_obj then begin
|
||||
isCorpse := critter_state(obj) == CRITTER_IS_DEAD;
|
||||
if (alsoCritter and not isCorpse) or (isCorpse and not NO_STEAL(obj)) then begin
|
||||
call ToggleHighlightObject(obj, enable, not isCorpse);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
tile_refresh_display;
|
||||
if (checkLOS or alsoCritter) and enable != isHighlight then begin
|
||||
set_global_script_repeat(REPEAT_FRAMES if enable else 0);
|
||||
end
|
||||
|
||||
isHighlight := enable;
|
||||
end
|
||||
|
||||
procedure KeyPressHandler begin
|
||||
@@ -69,9 +114,9 @@ procedure KeyPressHandler begin
|
||||
scanCode := get_sfall_arg,
|
||||
scanner, charges;
|
||||
|
||||
if scanCode == highlightKey and not(get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
||||
if scanCode == highlightKey and not(get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin
|
||||
if pressed then begin
|
||||
isHighlight := true;
|
||||
set_global_script_repeat(REPEAT_FRAMES);
|
||||
if motionScanner then begin
|
||||
scanner := obj_carrying_pid_obj(dude_obj, PID_MOTION_SENSOR);
|
||||
if scanner then begin
|
||||
@@ -94,16 +139,21 @@ procedure KeyPressHandler begin
|
||||
call ToggleHighlight(true);
|
||||
end
|
||||
end else begin
|
||||
isHighlight := false;
|
||||
call ToggleHighlight(false);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// visual glitch fix - for 3.8.29+
|
||||
// visual glitch fix, turn off highlight when entering combat - for 3.8.40+
|
||||
procedure CombatTurnHandler begin
|
||||
if isHighlight then begin
|
||||
call ToggleHighlight(false);
|
||||
end
|
||||
end
|
||||
|
||||
// visual glitch fix, turn off highlight when opening other interfaces - for 3.8.29+
|
||||
procedure GameModeChangeHandler begin
|
||||
if isHighlight and (get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
||||
isHighlight := false;
|
||||
if isHighlight and (get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin
|
||||
call ToggleHighlight(false);
|
||||
end
|
||||
end
|
||||
@@ -114,22 +164,35 @@ procedure InventoryMoveHandler begin
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if game_loaded and (sfall_ver_major < 4 and sfall_ver_build >= 12) then begin
|
||||
if game_loaded then begin
|
||||
if (sfall_ver_major >= 4 or sfall_ver_build < 12) then return;
|
||||
|
||||
call InitConfigs;
|
||||
|
||||
highlightKey := GetConfig(configSection, "Key", 0);
|
||||
alsoContainer := GetConfig(configSection, "Containers", 0);
|
||||
alsoCorpse := GetConfig(configSection, "Corpses", 0);
|
||||
alsoCritter := GetConfig(configSection, "Critters", 0);
|
||||
checkLOS := GetConfig(configSection, "CheckLOS", 0);
|
||||
outlineColor := GetConfig(configSection, "OutlineColor", 16);
|
||||
if (outlineColor < 1) then outlineColor := 64;
|
||||
outlineColorContainers := GetConfig(configSection, "OutlineColorContainers", 16);
|
||||
if (outlineColorContainers < 1) then outlineColorContainers := 64;
|
||||
outlineColorCorpses := GetConfig(configSection, "OutlineColorCorpses", 16);
|
||||
if (outlineColorCorpses < 1) then outlineColorCorpses := 64;
|
||||
motionScanner := GetConfig(configSection, "MotionScanner", 0);
|
||||
|
||||
highlightFailMsg1 := Translate("HighlightFail1", "You aren't carrying a motion sensor.");
|
||||
highlightFailMsg2 := Translate("HighlightFail2", "Your motion sensor is out of charge.");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, KeyPressHandler);
|
||||
register_hook_proc(HOOK_COMBATTURN, CombatTurnHandler);
|
||||
register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChangeHandler);
|
||||
register_hook_proc(HOOK_INVENTORYMOVE, InventoryMoveHandler);
|
||||
set_global_script_type(1);
|
||||
end else begin
|
||||
if isHighlight and not(get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin
|
||||
call ToggleHighlight(true);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,51 +12,52 @@
|
||||
#include "..\scripting\headers\lib.inven.h"
|
||||
*/
|
||||
|
||||
variable ini := "sfall-mods.ini";
|
||||
variable ini := "mods\\sfall-mods.ini";
|
||||
variable translationIni;
|
||||
|
||||
// Gets the integer value from the specified ini
|
||||
procedure GetIniConfig(variable section, variable key, variable def, variable inifile) begin
|
||||
variable val := get_ini_setting(inifile + "|" + section + "|" + key);
|
||||
if val == -1 then val := def;
|
||||
if (val == -1) then return def;
|
||||
return val;
|
||||
end
|
||||
|
||||
// Gets the string value from the specified ini
|
||||
procedure GetIniConfigStr(variable section, variable key, variable def, variable inifile) begin
|
||||
variable val := get_ini_string(inifile + "|" + section + "|" + key);
|
||||
if val == -1 orElse val == "" then val := def;
|
||||
if (val == -1 orElse val == "") then return def;
|
||||
return val;
|
||||
end
|
||||
|
||||
// Gets the integer value from sfall-mods.ini
|
||||
procedure GetConfig(variable section, variable key, variable def) begin
|
||||
variable val := get_ini_setting(ini + "|" + section + "|" + key);
|
||||
if val == -1 then val := def;
|
||||
if (val == -1) then return def;
|
||||
return val;
|
||||
end
|
||||
|
||||
// Gets the string value from sfall-mods.ini
|
||||
procedure GetConfigStr(variable section, variable key, variable def) begin
|
||||
variable val := get_ini_string(ini + "|" + section + "|" + key);
|
||||
if val == -1 orElse val == "" then val := def;
|
||||
if (val == -1 orElse val == "") then return def;
|
||||
return val;
|
||||
end
|
||||
|
||||
// Gets the value from sfall-mods.ini as a temp array of strings
|
||||
procedure GetConfigList(variable section, variable key) begin
|
||||
variable val := get_ini_string(ini + "|" + section + "|" + key);
|
||||
if val == -1 orElse val == "" then return [];
|
||||
if (val == -1 orElse val == "") then return [];
|
||||
|
||||
return string_split(val, ",");
|
||||
end
|
||||
|
||||
// Gets the value from sfall-mods.ini as a temp array of ints
|
||||
procedure GetConfigListInt(variable section, variable key) begin
|
||||
variable arr, i, item;
|
||||
variable arr, len, i, item;
|
||||
|
||||
arr := GetConfigList(section, key);
|
||||
for (i := 0; i < len_array(arr); i++) begin
|
||||
len = len_array(arr);
|
||||
for (i := 0; i < len; i++) begin
|
||||
arr[i] := atoi(arr[i]);
|
||||
end
|
||||
return arr;
|
||||
@@ -65,9 +66,7 @@ end
|
||||
// Translates given string using Translations.ini
|
||||
procedure Translate(variable id, variable def) begin
|
||||
variable str := get_ini_string(translationIni + "|Sfall|" + id);
|
||||
if (str == 0 orElse (strlen(str) == 0)) then begin
|
||||
str := def;
|
||||
end
|
||||
if (str == 0 orElse strlen(str) == 0) then return def;
|
||||
return str;
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Item Highlight mod (Lite version) for sfall 3.8.x
|
||||
-------------------------------------------------
|
||||
Item Highlighting mod (Lite version) for sfall 3.8.x
|
||||
----------------------------------------------------
|
||||
|
||||
A cut-down version of the mod included in sfall 4.x, offers a bit more features than the built-in function.
|
||||
A cut-down version of the mod included in sfall 4.x, offers more features than the built-in function.
|
||||
Features:
|
||||
- highlighting items, containers (optional) and lootable corpses (optional) on the ground
|
||||
- highlights items, containers (optional) and lootable corpses (optional) on the ground
|
||||
- configurable hotkey is used to trigger highlight
|
||||
- only objects in direct line-of-sight of player are highlighted (optional)
|
||||
- motion scanner is required to enable highlight (optional)
|
||||
@@ -12,10 +12,10 @@ Features:
|
||||
|
||||
Requires sfall 3.8.12 or higher.
|
||||
|
||||
To use, copy gl_highlighting_lite.int to your scripts folder, and copy sfall-mods.ini to the same directory as sfall.
|
||||
Also, you should disable the built-in function in ddraw.ini (ToggleItemHighlightsKey=0).
|
||||
To use, copy gl_highlighting_lite.int to your scripts folder and sfall-mods.ini to the mods folder in the same directory as sfall.
|
||||
Create the mods folder if it does not exist. Also, you should disable the built-in function in ddraw.ini (ToggleItemHighlightsKey=0).
|
||||
|
||||
Note that due to the lack of newer game hooks in sfall 3.8.x, there are some minor visual glitches in the lite version:
|
||||
- items will be kept highlighted when entering combat while holding the highlight key.
|
||||
- when you pick up items while holding the highlight key, they will be kept highlighted if you drop them on the ground (fixed for 3.8.18+).
|
||||
- items will be kept highlighted when entering combat while holding the highlight key (fixed in 3.8.40+).
|
||||
- when you pick up items while holding the highlight key, they will be kept highlighted if you drop them on the ground (fixed in 3.8.18+).
|
||||
Both glitches can bo solved by pressing and releasing the highlight key again.
|
||||
|
||||
@@ -9,10 +9,13 @@ Containers=0
|
||||
; Set to 1 to also highlight lootable corpses
|
||||
Corpses=0
|
||||
|
||||
; Set to 1 to only highlight objects in the player's line-of-sight
|
||||
CheckLOS=0
|
||||
; Set to 1 to also highlight critters, with the same rules as in combat
|
||||
Critters=0
|
||||
|
||||
; Set the color of outlines, available colors:
|
||||
; Set to 1 to only highlight objects in the player's line-of-sight
|
||||
CheckLOS=1
|
||||
|
||||
; Set the color of outlines for items; available colors:
|
||||
; 1 - glowing red
|
||||
; 2 - red
|
||||
; 4 - grey
|
||||
@@ -20,11 +23,51 @@ CheckLOS=0
|
||||
; 16 - bright yellow
|
||||
; 32 - dark yellow
|
||||
; 64 - purple
|
||||
; You can set a custom color from the game palette by multiplying the color index value by 256 (available since sfall 4.2.7)
|
||||
; You can set a custom color from the game palette by multiplying the color index value by 256 (in 3.8.27 or later)
|
||||
OutlineColor=16
|
||||
|
||||
; Set the color of outlines for containers
|
||||
OutlineColorContainers=4
|
||||
|
||||
; Set the color of outlines for corpses
|
||||
OutlineColorCorpses=4
|
||||
|
||||
; Motion Scanner mode:
|
||||
; 0 - ignored
|
||||
; 1 - requires Motion Scanner present in player inventory to activate highlighting
|
||||
; 2 - requires Motion Scanner and also requires 1 charge on every use (depleted scanner will not work anymore)
|
||||
; 1 - requires Motion Sensor to be present in the player's inventory to activate highlighting
|
||||
; 2 - requires Motion Sensor and consumes 1 charge on every use (depleted sensor will not work anymore)
|
||||
MotionScanner=0
|
||||
|
||||
|
||||
[CombatControl]
|
||||
;Allows you to control other critters directly in combat
|
||||
;Set to 0 to disable
|
||||
;Set to 1 to control all critters in combat (allowed only in sfall debugging mode)
|
||||
;Set to 2 to control all party members
|
||||
;Set to 3 to let you use the command cursor to specify targets for party members to attack in combat
|
||||
Mode=0
|
||||
;If you want to control only specific critters, uncomment the PIDList line and set a comma-delimited list of PIDs
|
||||
;PIDList=62,89,97,107,160,161
|
||||
|
||||
;Set a comma-delimited list of perk IDs for perks to be inherited from the player during the combat control
|
||||
PerksList=0,73
|
||||
|
||||
;Set to 1 to allow the player to gain a positive reputation when killing NPCs while controlling other critters
|
||||
GainReputation=0
|
||||
|
||||
;Choose a notification box to display the name of the controlled critter above the interface bar
|
||||
;Must be between 5 and (4 + the value of BoxBarCount in ddraw.ini)
|
||||
;For sfall 4.1.6+ the number for the notification box is set automatically, so just use any value
|
||||
;Set to 0 to disable
|
||||
DisplayName=0
|
||||
|
||||
;Set the color of display name, available colors:
|
||||
;0 - green
|
||||
;1 - red
|
||||
;2 - white
|
||||
;3 - yellow
|
||||
;4 - dark yellow
|
||||
;5 - blue
|
||||
;6 - purple
|
||||
;7 - dull pink
|
||||
DisplayNameColor=0
|
||||
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user