mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba3ad33587 | ||
|
|
6e74c3166a | ||
|
|
e320acce0b | ||
|
|
4f48926105 | ||
|
|
5611931063 | ||
|
|
f00022fed6 | ||
|
|
78815425e2 | ||
|
|
9ddddcc120 | ||
|
|
11c15cec93 | ||
|
|
f36bd6fb61 | ||
|
|
26ab38c6c3 | ||
|
|
9b50e6be1e | ||
|
|
2427634ee8 | ||
|
|
36d1d0a5fc | ||
|
|
486f00cdf4 | ||
|
|
b6fd424665 | ||
|
|
3d679db758 | ||
|
|
92e1f919d9 | ||
|
|
d259e8c903 | ||
|
|
dea0e596c3 | ||
|
|
90b39f3dde | ||
|
|
c80224f661 | ||
|
|
d7d8de5e1a | ||
|
|
0a21e4abfa | ||
|
|
1340eeb0d3 | ||
|
|
a350fed4d1 | ||
|
|
402d4f40f2 | ||
|
|
0f49c7f68d | ||
|
|
deb0299776 | ||
|
|
4bb3fa0275 | ||
|
|
da31455cef | ||
|
|
4da10e2fdb | ||
|
|
5426d043c1 | ||
|
|
719cec74d1 | ||
|
|
627fe11c29 | ||
|
|
dcca405b89 | ||
|
|
cce9437d19 | ||
|
|
09b3bf3aed | ||
|
|
08a891a0fc | ||
|
|
e9df81ac78 | ||
|
|
3e982be4b6 | ||
|
|
8a888f387d | ||
|
|
712b4de5f7 | ||
|
|
a3b456cf0a | ||
|
|
9f689863d7 | ||
|
|
b5306406b3 | ||
|
|
ce3b9c172c | ||
|
|
b8a77d77fb | ||
|
|
a01da656c7 | ||
|
|
5eda8dd7a0 | ||
|
|
c05babeda7 | ||
|
|
cc2b95d64e | ||
|
|
fb62bd51b5 | ||
|
|
f4d7ccef40 | ||
|
|
85bb34377c | ||
|
|
af24c6eae4 | ||
|
|
930f463000 | ||
|
|
e1aefcc1ed | ||
|
|
25554ff0b2 | ||
|
|
dad0860d6e | ||
|
|
a7e492a80f | ||
|
|
d9b748c261 | ||
|
|
0aad511e3e | ||
|
|
d117296990 | ||
|
|
e672db53c7 | ||
|
|
25bbd91fc5 | ||
|
|
8db528330b | ||
|
|
f761f7834e | ||
|
|
f6c4e5133c | ||
|
|
2e30c86467 | ||
|
|
1679f7c59d | ||
|
|
9a4cbd4fa9 | ||
|
|
0c561ba677 | ||
|
|
20ccdacee8 | ||
|
|
d44663ce76 |
@@ -7,8 +7,8 @@
|
||||
; have an additional NoHardcode option in this file which can
|
||||
; be used to remove their hardcoded effects, and add new stat/skill effects
|
||||
|
||||
;Name=The name of the perk
|
||||
;Desc=The description of the perk
|
||||
;Name=The name of the perk (max 63 characters)
|
||||
;Desc=The description of the perk (max 1023 characters)
|
||||
;Image=The line number (0-indexed) of the corresponding FRM in skilldex.lst
|
||||
;Ranks=The number of perk levels
|
||||
;Level=The minimum required level
|
||||
|
||||
@@ -7,6 +7,9 @@ HighlightFail2=Your motion sensor is out of charge.
|
||||
SuperStimExploitMsg=You cannot use a super stim on someone who is not injured!
|
||||
BlockedCombat=You cannot enter combat at this time.
|
||||
SaveSfallDataFail=ERROR saving extended savegame information! Check if other programs interfere with savegame files/folders and try again.
|
||||
PartyLvlMsg=Lvl:
|
||||
PartyACMsg=AC:
|
||||
PartyAddictMsg=Addict
|
||||
|
||||
[AppearanceMod]
|
||||
RaceText=Race
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
;Controls the elevators
|
||||
;Image must match up with the image of an existing elevator
|
||||
;Image must match up with the image of an existing elevator (can be overrided in sfall 4.1.4/3.8.14 or newer)
|
||||
;Make sure you specify the correct number of exit targets
|
||||
;The maximum number of elevators is currently capped at 50
|
||||
;Use the line number (0-indexed) of the corresponding FRM in intrface.lst to set the appearance of the elevator
|
||||
|
||||
;Override elevator 0
|
||||
[000]
|
||||
;This elevator uses the frm of the original forth elevator
|
||||
[0]
|
||||
;This elevator will use the settings of the original forth elevator
|
||||
Image=4
|
||||
|
||||
;Set up the first exit point
|
||||
@@ -23,4 +24,23 @@ ID3=50
|
||||
Elevation3=0
|
||||
Tile3=12944
|
||||
|
||||
;No forth exit point
|
||||
;No forth exit point
|
||||
|
||||
;Override FRM images of elevator 0. Set ButtonsFrm to -1 to use default buttons from MainFrm
|
||||
MainFrm=143
|
||||
ButtonsFrm=-1
|
||||
|
||||
|
||||
;An example of a new elevator
|
||||
[24]
|
||||
;Set Image to 24 to create a new elevator type (0-23 are the original elevator types)
|
||||
Image=24
|
||||
|
||||
;Set the number of buttons
|
||||
ButtonCount=3
|
||||
|
||||
;Set the appearance of the elevator
|
||||
MainFrm=148
|
||||
ButtonsFrm=151
|
||||
|
||||
;Set up the exit points for all three buttons (see examples above)
|
||||
|
||||
+69
-18
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v3.8.11
|
||||
;v3.8.14
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -17,7 +17,8 @@ NumSoundBuffers=0
|
||||
;Set to 1 to allow attaching sound files to combat float messages
|
||||
AllowSoundForFloats=1
|
||||
|
||||
;Set to 1 to automatically search for alternative formats when Fallout tries to play an acm
|
||||
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an acm
|
||||
;Set to 2 to play alternative music files even if original acm files are not present in the music folder
|
||||
;This does not effect the play_sfall_sound and stop_sfall_sound script functions
|
||||
AllowDShowSound=0
|
||||
|
||||
@@ -70,6 +71,14 @@ GPUBlt=0
|
||||
;Requires graphics mode 4 or 5, and GPUBlt set to 1
|
||||
Use32BitHeadGraphics=0
|
||||
|
||||
;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies
|
||||
;Requires graphics mode 4 or 5
|
||||
AllowDShowMovies=0
|
||||
|
||||
;Fade effect time percentage modifier
|
||||
;Default is 100. Decrease/increase this value to speed up/slow down fade effects
|
||||
FadeMultiplier=100
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Input]
|
||||
;Set to 1 to enable the mouse scroll wheel to scroll through inventory, barter, and loot screens
|
||||
@@ -132,7 +141,7 @@ WindowScrollKey=0
|
||||
ToggleItemHighlightsKey=42
|
||||
|
||||
;Set to 1 to also highlight containers
|
||||
HighlightContainers=0
|
||||
HighlightContainers=1
|
||||
|
||||
;Set the color of outlines, available colors:
|
||||
;0x01 - glowing red
|
||||
@@ -150,10 +159,15 @@ ReloadWeaponKey=0
|
||||
|
||||
;A key to hold down to let you move/drop a whole stack of items at once without the 'Move Items' window
|
||||
;Set to 0 if you don't want to use a modifier key, or a DX scancode otherwise
|
||||
ItemFastMoveKey=0x1d
|
||||
ItemFastMoveKey=29
|
||||
|
||||
;A key to press to open a debug game editor (requires FalloutClient.exe from the modders pack)
|
||||
;Set to 1 to skip the 'Move Items' window when taking items from containers or corpses and not holding down ItemFastMoveKey
|
||||
;Requires ItemFastMoveKey to be enabled
|
||||
FastMoveFromContainer=0
|
||||
|
||||
;A key to press to open a debug game editor
|
||||
;Set to 0 to disable, or a DX scancode otherwise
|
||||
;Requires sfall debugging mode and FalloutClient.exe from the modders pack
|
||||
DebugEditorKey=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -351,14 +365,19 @@ CorpseLineOfFireFix=0
|
||||
;Set to 1 (or some higher number if needed, the maximum is 127) to prevent 100% CPU use
|
||||
ProcessorIdle=-1
|
||||
|
||||
;Set a number of how many protos per type can be loaded into memory at once (valid range: 512..4096)
|
||||
;Set to -1 to let set_proto_data script function automatically increase the limit when needed
|
||||
LoadProtoMaxLimit=-1
|
||||
|
||||
;Set to 1 if using the hero appearance mod
|
||||
;You can add AppChCrt.frm and AppChEdt.frm files to art/intrface/ to set a custom background for the character screen
|
||||
EnableHeroAppearanceMod=0
|
||||
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
SkipOpeningMovies=0
|
||||
|
||||
;Causes NPCs who complete their combat turn with ap left over will try and find other ways to spend it.
|
||||
;Only NPCs with ap left equal to or greater than the value given here will be considered.
|
||||
;Causes NPCs who complete their combat turn with AP left over will try and find other ways to spend it.
|
||||
;Only NPCs with AP left equal to or greater than the value given here will be considered.
|
||||
;Set to 0 to disable
|
||||
NPCsTryToSpendExtraAP=0
|
||||
|
||||
@@ -366,6 +385,9 @@ NPCsTryToSpendExtraAP=0
|
||||
;Note that enabling this option can significantly affect the weapon choice of some NPCs in combat
|
||||
AIBestWeaponFix=0
|
||||
|
||||
;Set to 1 to fix NPCs not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
AIDrugUsePerfFix=0
|
||||
|
||||
;Allows the use of tiles over 80*36 in size. sfall will just split and resave them at startup
|
||||
;Set to 1 to check all tiles on started (slow)
|
||||
;Set to 2 if you provide a XLtiles.lst file in art/tiles/ containing a list of the tile ids that need checking
|
||||
@@ -384,12 +406,15 @@ Doctor=293
|
||||
Science=293
|
||||
Repair=293
|
||||
|
||||
;Remove window position rounding
|
||||
RemoveWindowRounding=0
|
||||
|
||||
;Set to 1 to add scroll buttons to the pipboy quest list, and remove the quests per area limit
|
||||
;Set to 2 to use a different set of scroll buttons
|
||||
UseScrollingQuestsList=1
|
||||
|
||||
;To change the location of quest list scroll buttons, uncomment the next two lines
|
||||
;Defaults are 140 for the X-axis and 334 for the Y-axis
|
||||
;QuestsScrollButtonsX=140
|
||||
;QuestsScrollButtonsY=334
|
||||
|
||||
;Uncomment these lines to control the premade characters offered when starting a new game
|
||||
;Multiple options should be separated by commas, and there must be the same number of entries in both lines
|
||||
;PremadePaths=combat,diplomat,stealth
|
||||
@@ -408,6 +433,7 @@ ExtraSaveSlots=0
|
||||
|
||||
;Set to 1 to speed up the HP/AC counter animations
|
||||
;Set to 2 to update the HP/AC counters instantly
|
||||
;Set to 3 to update the AC counter instantly when switching to other controlled critters in combat
|
||||
SpeedInterfaceCounterAnims=0
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
@@ -424,7 +450,7 @@ ScienceOnCritters=0
|
||||
SpeedInventoryPCRotation=166
|
||||
|
||||
;Uncomment to set the text colour of the extra 5 interface boxes
|
||||
;The line must contain a 5 digits, each either a 0 for green or 1 for red
|
||||
;The line must contain 5 digits, each either a 0 for green or 1 for red
|
||||
;BoxBarColours=00000
|
||||
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
@@ -468,10 +494,11 @@ BoostScriptDialogLimit=0
|
||||
|
||||
;These options modify the checks to see if a critter can carry an additional item, changing which items are counted towards the weight limit and adding an additional size check
|
||||
;Set the mode to 0 to disable the size check, 1 to apply to the PC only, 2 to apply to the PC and party members, or 3 to apply to all critters
|
||||
;Only the PC uses CritterInvSizeLimit. Other critters will use the extra unused stat (STAT_unused = 10)
|
||||
;Only the PC uses CritterInvSizeLimit. Other critters will use the unused stat (STAT_unused = 10) or have the size limit of 100 if the stat is not set
|
||||
;Add 4 to the mode to limit the weight check to used items only
|
||||
;You can use line number 542/543 in proto.msg and line number 35 in inventry.msg to set up custom messages for item size
|
||||
CritterInvSizeLimitMode=0
|
||||
CritterInvSizeLimit=200
|
||||
CritterInvSizeLimit=100
|
||||
|
||||
;Some bit flags to alter behaviour of the motion sensor
|
||||
;1 - Allow sensor use on automap when motion sensor is in pack rather than hands
|
||||
@@ -499,9 +526,17 @@ SuperStimExploitFix=0
|
||||
InventoryApCost=4
|
||||
QuickPocketsApCostReduction=2
|
||||
|
||||
;Set to 1 to allow objects seeing through other objects with their ShootThru flag set
|
||||
;Set to 1 to allow objects seeing through other objects that have their ShootThru flag set
|
||||
;Note that enabling this option can cause unexpected NPC behavior in some situations
|
||||
ObjCanSeeObj_ShootThru_Fix=0
|
||||
|
||||
;Set to 1 to fix the broken obj_can_hear_obj script function
|
||||
ObjCanHearObjFix=0
|
||||
|
||||
;Set to 1 to enable the mood argument of start_gdialog script function to be available for talking heads
|
||||
;If the argument value is -1, the mood will be determined by the local variable 0 of the script (vanilla behavior)
|
||||
StartGDialogFix=0
|
||||
|
||||
;Set to 1 to enable the balanced bullet distribution formula for burst attacks
|
||||
ComputeSprayMod=0
|
||||
|
||||
@@ -579,6 +614,10 @@ EnableMusicInDialogue=0
|
||||
;Set to 1 to prevent the player from running while sneaking without Silent Running perk
|
||||
DontTurnOffSneakIfYouRun=0
|
||||
|
||||
;Changes the distance at which the player will switch to walking when trying to use objects (valid range: 0..3)
|
||||
;Set to 0 to disable switching. (Default is 3)
|
||||
UseWalkDistance=3
|
||||
|
||||
;Set to 1 to fix the bug that unable to sell used geiger counters or stealth boys
|
||||
CanSellUsedGeiger=1
|
||||
|
||||
@@ -599,6 +638,18 @@ NumbersInDialogue=0
|
||||
;Set to 1 to use Fallout's normal text font instead of DOS-like font on the world map
|
||||
WorldMapFontPatch=0
|
||||
|
||||
;Set to 1 to display full item description for weapon/ammo in barter screen
|
||||
FullItemDescInBarter=0
|
||||
|
||||
;Set to 1 to display experience points with the bonus from Swift Learner perk when gained from non-scripted situations
|
||||
DisplaySwiftLearnerExp=1
|
||||
|
||||
;Set to 1 to display party member's current level/AC/addict flag on the combat control panel
|
||||
PartyMemberExtraInfo=0
|
||||
|
||||
;Set to 1 to prevent the inventory/loot/automap interfaces from being placed on top of other script-created windows
|
||||
InterfaceDontMoveOnTop=0
|
||||
|
||||
;Set to 1 to display sfall built-in credits at the bottom of credits.txt contents instead of at the top
|
||||
CreditsAtBottom=0
|
||||
|
||||
@@ -611,8 +662,8 @@ CreditsAtBottom=0
|
||||
Enable=0
|
||||
|
||||
;Fallout 2 Debug Patch
|
||||
;Set to 1 to enable debugging output to screen or 2 to create a debug.log file
|
||||
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg
|
||||
;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and a debug.log file
|
||||
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg:
|
||||
;-------
|
||||
;[debug]
|
||||
;mode=environment
|
||||
@@ -630,12 +681,12 @@ DebugMode=0
|
||||
SkipCompatModeCheck=0
|
||||
|
||||
;Set to 1 to skip the executable file size check
|
||||
;Does not require enabling sfall debugging mode
|
||||
;Does not require sfall debugging mode
|
||||
SkipSizeCheck=0
|
||||
|
||||
;If you're testing changes to the Fallout exe, you can override the CRC that sfall looks for here
|
||||
;You can use several hex values, separated by commas
|
||||
;Does not require enabling sfall debugging mode
|
||||
;Does not require sfall debugging mode
|
||||
;ExtraCRC=0x00000000,0x00000000
|
||||
|
||||
;Set to 1 to stop Fallout from deleting non readonly protos at startup
|
||||
|
||||
@@ -9,21 +9,21 @@ Array elements are accessed by index or key. For example:
|
||||
|
||||
// this code puts some string in array "list" at index 5:
|
||||
list[5] := "Value";
|
||||
|
||||
|
||||
|
||||
There are 2 different types of arrays currently available:
|
||||
1) Lists - a set of values with specific size (number of elements), where all elements have numeric indexes starting from zero (0) up to array length minus one.
|
||||
For example:
|
||||
|
||||
|
||||
// this creates list with 3 elements. Element "A" has index 0, element "B" has index 1, element "C" - 2
|
||||
list := ["A", "B", "C"];
|
||||
|
||||
|
||||
Limitations:
|
||||
- all indexes are numeric, starting from 0;
|
||||
- to assign value to a specific index, you must first resize array to contain this index
|
||||
(for example, if list is of size 3 (indexes from 0 to 2), you can't assign value to index 4 unless you change list size to 5 first).
|
||||
|
||||
|
||||
|
||||
2) Maps (or associative arrays) - a set of key=>value pairs, where all elements (values) are accessed by corresponding keys.
|
||||
Differences from list:
|
||||
- maps don't have specific size (to assign values, you don't need to resize array first);
|
||||
@@ -37,24 +37,24 @@ Both array types have their pros and cons and are suited for different tasks.
|
||||
Basically arrays are implemented using number of new operators (scripting functions). But for ease of use, there are some new syntax elements:
|
||||
|
||||
1) Accessing elements. Use square brackets:
|
||||
|
||||
|
||||
display_msg(arr[5]);
|
||||
mymap["price"] := 515.23;
|
||||
|
||||
|
||||
2) Alternative accessing for maps. Use dot:
|
||||
|
||||
display_msg(mymap.name);
|
||||
mymap.price := 232.23;
|
||||
|
||||
|
||||
3) Array expressions. Create and fill arrays with just one expression:
|
||||
|
||||
// create list with 5 values
|
||||
[5, 777, 0, 3.14, "Cool Value"]
|
||||
|
||||
|
||||
// create map:
|
||||
{5: "Five", "health": 50, "speed": 0.252}
|
||||
|
||||
NOTES:
|
||||
|
||||
NOTES:
|
||||
- make sure to call "fix_array" if you want new array to be available in the next frame or "save_array" if you want to use it for a longer period
|
||||
(see next section for details)
|
||||
|
||||
@@ -64,16 +64,16 @@ NOTES:
|
||||
foreach (item in myarray) begin
|
||||
// this block is executed for each array element, where "item" contains current value on each step
|
||||
end
|
||||
|
||||
|
||||
// alternative syntax:
|
||||
foreach (key: item in myarray) begin
|
||||
// "key" will contain current key (or numeric index, for lists)
|
||||
end
|
||||
|
||||
See "Script editor\docs\sslc readme.txt" file for full information on new SSL syntax features.
|
||||
|
||||
|
||||
>>> STORING ARRAYS <<<
|
||||
|
||||
|
||||
Apart from lists/maps arrays are divided by how they are stored.
|
||||
There a 3 types of arrays:
|
||||
|
||||
@@ -85,21 +85,21 @@ where you create temp_array, it will not be available next time your global scri
|
||||
This type of arrays are always available (by their ID) until you start a new game or load a saved game (at which point they are deleted).
|
||||
|
||||
3) Saved. If you want your array to really stay for a while, use function "save_array" to make any array "saved". However, they are, like permanent arrays,
|
||||
"deleted" from memory when loading game. In order to use them properly, you must load them from the savegame using "load_array" whenever you want to use them.
|
||||
"deleted" from memory when loading game. In order to use them properly, you must load them from the savegame using "load_array" whenever you want to use them.
|
||||
Example:
|
||||
|
||||
|
||||
variable savedArray;
|
||||
procedure start begin
|
||||
if game_loaded then begin
|
||||
savedArray := load_array("traps");
|
||||
end else begin
|
||||
foreach trap in traps begin
|
||||
....
|
||||
....
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
>>> PRACTICAL EXAMPLES <<<
|
||||
|
||||
@@ -114,8 +114,8 @@ Example:
|
||||
|
||||
// call it:
|
||||
call give_item(dude_obj, {PID_SHOTGUN: 1, PID_SHOTGUN_SHELLS: 4, PID_STIMPAK: 3});
|
||||
|
||||
|
||||
|
||||
|
||||
> Create arrays of objects (maps) for advanced scripting:
|
||||
|
||||
variable traps;
|
||||
@@ -130,14 +130,14 @@ Example:
|
||||
traps[k] := load_array("trap_"+k); // each object is stored separately
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
procedure add_trap(variable trapArray) begin
|
||||
variable index;
|
||||
index := len_array(traps);
|
||||
save_array("trap_"+k, trapArray);
|
||||
array_push(traps, trapArray);
|
||||
end
|
||||
|
||||
|
||||
// use them:
|
||||
foreach trap in traps begin
|
||||
if (self_elevation == trap["elev"] and tile_distance(self_tile, trap["tile"]) < trap["radius"]) then
|
||||
@@ -151,14 +151,16 @@ Example:
|
||||
|
||||
*mixed means any type
|
||||
|
||||
> int create_array(int size, int nothing):
|
||||
> int create_array(int size, int flags):
|
||||
- creates permanent array (but not "saved")
|
||||
- if size is >= 0, creates list with given size
|
||||
- if size == -1, creates map (associative array)
|
||||
- second argument is not used yet, just use 0
|
||||
- if size == -1 and flags == 2, creates a "lookup" map in which the values of existing keys are read-only and can't be updated.
|
||||
This type of array allows you to store a zero (0) key value
|
||||
- NOTE: in earlier versions (up to 4.1.3/3.8.13) the second argument is not used, just use 0
|
||||
- returns arrayID (valid until array is deleted)
|
||||
|
||||
> int temp_array(int size, int nothing):
|
||||
> int temp_array(int size, int flags):
|
||||
- works exactly like "create_array", only created array becomes "temporary"
|
||||
|
||||
> void fix_array(int arrayID):
|
||||
@@ -169,6 +171,7 @@ Example:
|
||||
- if used on list, "key" must be numeric and within valid index range (0..size-1)
|
||||
- if used on map, key can be of any type
|
||||
- to "unset" a value from map, just set it to zero (0)
|
||||
- NOTE: to add a value of 0 for the key, use the float value of 0.0
|
||||
- this works exactly like statement:
|
||||
arrayID[key] := value;
|
||||
|
||||
@@ -182,7 +185,7 @@ Example:
|
||||
- changes array size
|
||||
- applicable to maps too, but only to reduce elements
|
||||
- there are number of special negative values of "size" which perform various operations on the array,
|
||||
use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header
|
||||
use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header
|
||||
|
||||
> void free_array(int arrayID):
|
||||
- deletes any array
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
#define OBJ_TYPE_MISC (5)
|
||||
#define OBJ_TYPE_SPATIAL (6)
|
||||
|
||||
#define WEAPON_TYPE_NONE (0)
|
||||
#define WEAPON_TYPE_UNARMED (1)
|
||||
#define WEAPON_TYPE_MELEE (2)
|
||||
#define WEAPON_TYPE_THROWN (3)
|
||||
#define WEAPON_TYPE_GUNS (4)
|
||||
|
||||
/* Item Common Flags */
|
||||
#define HIDDEN_ITEM 134217728 // 0x08000000 - Hidden Item
|
||||
|
||||
@@ -21,14 +27,14 @@
|
||||
#define WEAPON_2HAND 512 // 0x00000200 - 2Hnd (weapon is two-handed)
|
||||
|
||||
#define ATKMODE_PRI_NONE 0
|
||||
#define ATKMODE_PRI_PUNCH 1
|
||||
#define ATKMODE_PRI_KICK 2
|
||||
#define ATKMODE_PRI_SWING 3
|
||||
#define ATKMODE_PRI_THRUST 4
|
||||
#define ATKMODE_PRI_THROW 5
|
||||
#define ATKMODE_PRI_SINGLE 6
|
||||
#define ATKMODE_PRI_BURST 7
|
||||
#define ATKMODE_PRI_FLAME 8
|
||||
#define ATKMODE_PRI_PUNCH 1 // 0001
|
||||
#define ATKMODE_PRI_KICK 2 // 0010
|
||||
#define ATKMODE_PRI_SWING 3 // 0011
|
||||
#define ATKMODE_PRI_THRUST 4 // 0100
|
||||
#define ATKMODE_PRI_THROW 5 // 0101
|
||||
#define ATKMODE_PRI_SINGLE 6 // 0110
|
||||
#define ATKMODE_PRI_BURST 7 // 0111
|
||||
#define ATKMODE_PRI_FLAME 8 // 1000
|
||||
#define ATKMODE_SEC_NONE 0
|
||||
#define ATKMODE_SEC_PUNCH 16 // 0x00000010
|
||||
#define ATKMODE_SEC_KICK 32 // 0x00000020
|
||||
@@ -39,6 +45,32 @@
|
||||
#define ATKMODE_SEC_BURST 112 // 0x00000070
|
||||
#define ATKMODE_SEC_FLAME 128 // 0x00000080
|
||||
|
||||
/* Object flags for get/set_flags */
|
||||
#define FLAG_MOUSE_3D (0x1)
|
||||
#define FLAG_WALKTHRU (0x4)
|
||||
#define FLAG_FLAT (0x8)
|
||||
#define FLAG_NOBLOCK (0x10)
|
||||
#define FLAG_LIGHTING (0x20)
|
||||
#define FLAG_TEMP (0x400)
|
||||
#define FLAG_MULTIHEX (0x800)
|
||||
#define FLAG_NOHIGHLIGHT (0x1000)
|
||||
#define FLAG_USED (0x2000)
|
||||
#define FLAG_TRANSRED (0x4000)
|
||||
#define FLAG_TRANSNONE (0x8000)
|
||||
#define FLAG_TRANSWALL (0x10000)
|
||||
#define FLAG_TRANSGLASS (0x20000)
|
||||
#define FLAG_TRANSSTEAM (0x40000)
|
||||
#define FLAG_TRANSENERGY (0x80000)
|
||||
#define FLAG_LEFT_HAND (0x1000000)
|
||||
#define FLAG_RIGHT_HAND (0x2000000)
|
||||
#define FLAG_WORN (0x4000000)
|
||||
#define FLAG_HIDDENITEM (0x8000000)
|
||||
#define FLAG_WALLTRANSEND (0x10000000)
|
||||
#define FLAG_LIGHTTHRU (0x20000000)
|
||||
#define FLAG_SEEN (0x40000000)
|
||||
#define FLAG_SHOOTTHRU (0x80000000)
|
||||
|
||||
|
||||
/* Critter Flags */
|
||||
#define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with)
|
||||
#define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from)
|
||||
@@ -75,15 +107,21 @@
|
||||
// offsets for get_proto_data
|
||||
#define PROTO_PID (1)
|
||||
#define PROTO_TEXTID (4)
|
||||
#define PROTO_FID (8)
|
||||
|
||||
// items
|
||||
#define PROTO_IT_LDIST (12)
|
||||
#define PROTO_IT_LINT (16)
|
||||
#define PROTO_IT_FLAG (20)
|
||||
#define PROTO_IT_FLAGS (24)
|
||||
#define PROTO_IT_SCRIPTID (28)
|
||||
#define PROTO_IT_TYPE (32)
|
||||
#define PROTO_IT_MATERIAL (108)
|
||||
#define PROTO_IT_SIZE (112)
|
||||
#define PROTO_IT_WEIGHT (116)
|
||||
#define PROTO_IT_COST (120)
|
||||
#define PROTO_IT_INV_FID (124)
|
||||
#define PROTO_IT_SOUND (128) // byte
|
||||
|
||||
// weapons
|
||||
#define PROTO_WP_ANIM (36)
|
||||
@@ -161,7 +199,11 @@
|
||||
#define PROTO_DR_ADDICT_DELAY (100)
|
||||
|
||||
// critters
|
||||
#define PROTO_CR_FLAGS (32)
|
||||
#define PROTO_CR_LDIST (20)
|
||||
#define PROTO_CR_LINT (24)
|
||||
#define PROTO_CR_FLAG (28)
|
||||
#define PROTO_CR_FLAGS (32) // Critter Flags
|
||||
#define PROTO_CR_SCRIPTID (36)
|
||||
#define PROTO_CR_HEAD_FID (40)
|
||||
#define PROTO_CR_AI_PACKET (44)
|
||||
#define PROTO_CR_TEAM_NUM (48)
|
||||
@@ -192,26 +234,26 @@
|
||||
#define CALIBER_7_62MM (18)
|
||||
|
||||
// hidden perks
|
||||
#define PERK_add_nuka (53)
|
||||
#define PERK_add_buffout (54)
|
||||
#define PERK_add_mentats (55)
|
||||
#define PERK_add_psycho (56)
|
||||
#define PERK_add_radaway (57)
|
||||
#define PERK_weapon_long_range (58)
|
||||
#define PERK_weapon_accurate (59)
|
||||
#define PERK_weapon_penetrate (60)
|
||||
#define PERK_weapon_knockback (61)
|
||||
#define PERK_armor_powered (62)
|
||||
#define PERK_armor_combat (63)
|
||||
#define PERK_weapon_scope_range (64)
|
||||
#define PERK_weapon_fast_reload (65)
|
||||
#define PERK_weapon_night_sight (66)
|
||||
#define PERK_weapon_flameboy (67)
|
||||
#define PERK_armor_advanced_1 (68)
|
||||
#define PERK_armor_advanced_2 (69)
|
||||
#define PERK_add_jet (70)
|
||||
#define PERK_add_tragic (71)
|
||||
#define PERK_armor_charisma (72)
|
||||
#define PERK_add_nuka (53)
|
||||
#define PERK_add_buffout (54)
|
||||
#define PERK_add_mentats (55)
|
||||
#define PERK_add_psycho (56)
|
||||
#define PERK_add_radaway (57)
|
||||
#define PERK_weapon_long_range (58)
|
||||
#define PERK_weapon_accurate (59)
|
||||
#define PERK_weapon_penetrate (60)
|
||||
#define PERK_weapon_knockback (61)
|
||||
#define PERK_armor_powered (62)
|
||||
#define PERK_armor_combat (63)
|
||||
#define PERK_weapon_scope_range (64)
|
||||
#define PERK_weapon_fast_reload (65)
|
||||
#define PERK_weapon_night_sight (66)
|
||||
#define PERK_weapon_flameboy (67)
|
||||
#define PERK_armor_advanced_1 (68)
|
||||
#define PERK_armor_advanced_2 (69)
|
||||
#define PERK_add_jet (70)
|
||||
#define PERK_add_tragic (71)
|
||||
#define PERK_armor_charisma (72)
|
||||
|
||||
#define WPN_ANIM_NONE (0x00) // (A)
|
||||
#define WPN_ANIM_KNIFE (0x01) // (D)
|
||||
@@ -225,4 +267,21 @@
|
||||
#define WPN_ANIM_MINIGUN (0x09) // (L)
|
||||
#define WPN_ANIM_ROCKET_LAUNCHER (0x0A) // (M)
|
||||
|
||||
// common object data offsets
|
||||
#define OBJ_DATA_TILENUM (0x04)
|
||||
#define OBJ_DATA_CUR_FRM (0x18) // current frame number
|
||||
#define OBJ_DATA_ROTATION (0x1C)
|
||||
#define OBJ_DATA_FID (0x20)
|
||||
#define OBJ_DATA_ELEVATION (0x28)
|
||||
#define OBJ_DATA_PID (0x64)
|
||||
#define OBJ_DATA_CID (0x68)
|
||||
#define OBJ_DATA_SID (0x78)
|
||||
// items
|
||||
#define OBJ_DATA_CUR_CHARGES (0x3C)
|
||||
// critters
|
||||
#define OBJ_DATA_COMBAT_STATE (0x3C) // flags: 1 - combat, 2 - target is out of range, 4 - flee
|
||||
#define OBJ_DATA_CUR_ACTION_POINT (0x40)
|
||||
#define OBJ_DATA_DAMAGE_LAST_TURN (0x48)
|
||||
#define OBJ_DATA_WHO_HIT_ME (0x54)
|
||||
|
||||
#endif // DEFINE_EXTRA_H
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
/*
|
||||
Generic array functions
|
||||
*/
|
||||
// returns True if the specified key exists in the associative array
|
||||
procedure map_contains_key(variable arrayMap, variable key);
|
||||
|
||||
// push new item at the end of array, returns array
|
||||
procedure array_push(variable array, variable item);
|
||||
|
||||
@@ -151,6 +154,14 @@ procedure load_collection(variable name);
|
||||
|
||||
#define ARRAY_SET_BLOCK_SIZE (10)
|
||||
|
||||
procedure map_contains_key(variable arrayMap, variable key) begin
|
||||
variable i;
|
||||
for (i := 0; i < len_array(arrayMap); i++) begin
|
||||
if (array_key(arrayMap, i) == key) then return true;
|
||||
end
|
||||
return false;
|
||||
end
|
||||
|
||||
/**
|
||||
* Returns first index of zero value
|
||||
*/
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
//Recognised modes for set_shader_mode and get_game_mode
|
||||
#define WORLDMAP (0x1)
|
||||
#define LOCALMAP (0x2) //No point hooking this: would always be 1 at any point at which scripts are running
|
||||
#define DIALOG (0x4)
|
||||
#define ESCMENU (0x8)
|
||||
#define SAVEGAME (0x10)
|
||||
#define LOADGAME (0x20)
|
||||
#define COMBAT (0x40)
|
||||
#define OPTIONS (0x80)
|
||||
#define HELP (0x100)
|
||||
#define CHARSCREEN (0x200)
|
||||
#define PIPBOY (0x400)
|
||||
#define PCOMBAT (0x800)
|
||||
#define INVENTORY (0x1000)
|
||||
#define AUTOMAP (0x2000)
|
||||
#define SKILLDEX (0x4000)
|
||||
#define WORLDMAP (0x1)
|
||||
#define LOCALMAP (0x2) //No point hooking this: would always be 1 at any point at which scripts are running
|
||||
#define DIALOG (0x4)
|
||||
#define ESCMENU (0x8)
|
||||
#define SAVEGAME (0x10)
|
||||
#define LOADGAME (0x20)
|
||||
#define COMBAT (0x40)
|
||||
#define OPTIONS (0x80)
|
||||
#define HELP (0x100)
|
||||
#define CHARSCREEN (0x200)
|
||||
#define PIPBOY (0x400)
|
||||
#define PCOMBAT (0x800)
|
||||
#define INVENTORY (0x1000)
|
||||
#define AUTOMAP (0x2000)
|
||||
#define SKILLDEX (0x4000)
|
||||
#define INTFACEUSE (0x8000)
|
||||
#define INTFACELOOT (0x10000)
|
||||
#define BARTER (0x20000)
|
||||
|
||||
//Valid arguments to register_hook
|
||||
#define HOOK_TOHIT (0)
|
||||
@@ -99,6 +102,10 @@
|
||||
#define create_array_map (create_array(-1, 0))
|
||||
// create temporary map
|
||||
#define temp_array_map (temp_array(-1, 0))
|
||||
// create persistent lookup map (see arrays.txt for details)
|
||||
#define create_lookup_map (create_array(-1, 2))
|
||||
// create temporary lookup map
|
||||
#define temp_lookup_map (temp_array(-1, 2))
|
||||
// true if array is map, false otherwise
|
||||
#define array_is_map(x) (array_key(x, -1) == 1)
|
||||
// returns temp list with names of all arrays saved with save_array() in alphabetical order
|
||||
@@ -111,14 +118,18 @@
|
||||
#define array_exists(array) (len_array(array) != -1)
|
||||
// remove all elements from array
|
||||
#define clear_array(array) resize_array(array, 0)
|
||||
// sort array in ascending order
|
||||
// sort array or map by key in ascending order
|
||||
#define sort_array(array) resize_array(array, -2)
|
||||
// sort array in descending order
|
||||
// sort array or map by key in descending order
|
||||
#define sort_array_reverse(array) resize_array(array, -3)
|
||||
// reverse elements in list
|
||||
// reverse elements in list/map
|
||||
#define reverse_array(array) resize_array(array, -4)
|
||||
// randomly shuffle elements in list
|
||||
// randomly shuffle elements in list/map
|
||||
#define shuffle_array(array) resize_array(array, -5)
|
||||
// sort map in ascending order by value
|
||||
#define sort_map_value(array) resize_array(array, -6)
|
||||
// sort map in descending order by value
|
||||
#define sort_map_value_desc(array) resize_array(array, -7)
|
||||
// remove element from map or just replace value with 0 for list
|
||||
#define unset_array(array, item) set_array(array, item, 0)
|
||||
// same as "key_pressed" but checks VK codes instead of DX codes
|
||||
@@ -129,6 +140,7 @@
|
||||
#define set_attack_explosion_radius(x) metarule2_explosions(3, x, 0)
|
||||
#define set_attack_is_explosion(x) metarule2_explosions(4, x, 0)
|
||||
#define set_attack_is_explosion_fire set_attack_is_explosion(DMG_fire)
|
||||
#define set_explosion_radius(grenade, rocket) metarule2_explosions(5, grenade, rocket)
|
||||
|
||||
|
||||
#define GAME_MSG_COMBAT (0)
|
||||
@@ -158,6 +170,19 @@
|
||||
#define GAME_MSG_PRO_TILE (0x1004)
|
||||
#define GAME_MSG_PRO_MISC (0x1005)
|
||||
|
||||
#define OUTLINE_NONE (0)
|
||||
#define OUTLINE_RED_GLOW (0x01)
|
||||
#define OUTLINE_RED (0x02)
|
||||
#define OUTLINE_GREY (0x04)
|
||||
#define OUTLINE_GREEN_GLOW (0x08)
|
||||
#define OUTLINE_YELLOW (0x10)
|
||||
#define OUTLINE_DARK_YELLOW (0x20)
|
||||
#define OUTLINE_PURPLE (0x40)
|
||||
|
||||
#define CURSOR_MOVEMENT (0)
|
||||
#define CURSOR_COMMAND (1)
|
||||
#define CURSOR_TARGETING (2)
|
||||
|
||||
#define mstr_combat(x) (message_str_game(GAME_MSG_COMBAT, x))
|
||||
#define mstr_ai(x) (message_str_game(GAME_MSG_AI, x))
|
||||
#define mstr_scrname(x) (message_str_game(GAME_MSG_SCRNAME, x))
|
||||
@@ -189,12 +214,34 @@
|
||||
#define party_member_list_all party_member_list(1)
|
||||
|
||||
|
||||
#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type)
|
||||
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
|
||||
#define floor2(value) sfall_func1("floor2", value)
|
||||
#define intface_hide sfall_func0("intface_hide")
|
||||
#define intface_is_hidden sfall_func0("intface_is_hidden")
|
||||
#define intface_redraw sfall_func0("intface_redraw")
|
||||
#define intface_show sfall_func0("intface_show")
|
||||
#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value)
|
||||
#define spatial_radius(obj) sfall_func1("spatial_radius", obj)
|
||||
#define attack_is_aimed sfall_func0("attack_is_aimed")
|
||||
#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
|
||||
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
|
||||
#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type)
|
||||
#define display_stats sfall_func0("display_stats")
|
||||
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
|
||||
#define floor2(value) sfall_func1("floor2", value)
|
||||
#define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj)
|
||||
#define get_cursor_mode sfall_func0("get_cursor_mode")
|
||||
#define get_flags(obj) sfall_func1("get_flags", obj)
|
||||
#define get_map_enter_position sfall_func0("get_map_enter_position")
|
||||
#define get_object_data(obj, offset) sfall_func2("get_object_data", obj, offset)
|
||||
#define get_outline(obj) sfall_func1("get_outline", obj)
|
||||
#define intface_hide sfall_func0("intface_hide")
|
||||
#define intface_is_hidden sfall_func0("intface_is_hidden")
|
||||
#define intface_redraw sfall_func0("intface_redraw")
|
||||
#define intface_show sfall_func0("intface_show")
|
||||
#define inventory_redraw(invSide) sfall_func1("inventory_redraw", invSide)
|
||||
#define item_weight(obj) sfall_func1("item_weight", obj)
|
||||
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
||||
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
||||
#define outlined_object sfall_func0("outlined_object")
|
||||
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
|
||||
#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags)
|
||||
#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value)
|
||||
#define set_map_enter_position(tile, elev, rot) sfall_func3("set_map_enter_position", tile, elev, rot)
|
||||
#define set_object_data(obj, offset, value) sfall_func3("set_object_data", obj, offset, value)
|
||||
#define set_outline(obj, color) sfall_func2("set_outline", obj, color)
|
||||
#define spatial_radius(obj) sfall_func1("spatial_radius", obj)
|
||||
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
||||
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
|
||||
|
||||
@@ -111,7 +111,7 @@ critter ret3 - Override the target of the attack
|
||||
HOOK_CALCAPCOST (hs_calcapcost.int)
|
||||
|
||||
Runs whenever Fallout is calculating the AP cost of using the weapon (or unarmed attack). Doesn't run for using other item types or moving.
|
||||
Note that the first time a game is loaded, this script doesn't run before the initial interface is drawn, so if the script effects the AP cost of whatever is in the players hands at the time the wrong AP cost will be shown. It will be fixed the next time the interface is redrawn.
|
||||
Note that the first time a game is loaded, this script doesn't run before the initial interface is drawn, so if the script effects the AP cost of whatever is in the player's hands at the time the wrong AP cost will be shown. It will be fixed the next time the interface is redrawn.
|
||||
You can get the weapon object by checking item slot based on attack type (ATKTYPE_LWEP1, ATKTYPE_LWEP2, etc) and then calling critter_inven_obj().
|
||||
|
||||
critter arg1 - The critter performing the action
|
||||
@@ -162,11 +162,11 @@ critter arg1 - The target
|
||||
critter arg2 - The attacker
|
||||
int arg3 - The amount of damage to the target
|
||||
int arg4 - The amount of damage to the attacker
|
||||
int arg5 - The special effect flags for the target
|
||||
int arg6 - The special effect flags for the attacker
|
||||
int arg5 - The special effect flags for the target (use bwand DAM_* to check specific flags)
|
||||
int arg6 - The special effect flags for the attacker (use bwand DAM_* to check specific flags)
|
||||
int arg7 - The weapon used in the attack
|
||||
int arg8 - The bodypart that was struck
|
||||
int arg9 - 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, but with Silent Death perk and the corresponding attack conditions, it's 4; for critical hits, the value is taken from the critical table)
|
||||
int arg9 - 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 arg10 - Number of bullets actually hit the target (1 for melee attacks)
|
||||
int arg11 - The amount of knockback to the target
|
||||
int arg12 - Attack Type (see ATKTYPE_* constants)
|
||||
@@ -189,7 +189,7 @@ Critter arg1 - The critter that just died
|
||||
|
||||
HOOK_FINDTARGET (hs_findtarget.int)
|
||||
|
||||
Runs when the ai is trying to pick a target in combat. Fallout first chooses a list of 4 likely suspects, then normally sorts them in order of weakness/distance/etc depending on the ai caps of the attacker. This hook replaces that sorting function, allowing you to sort the targets in some arbitrary way. Use sfall_return to give the 4 targets, in order of preference. All 4 must be given if you want to override normal sorting; if you want to specify less than 4 targets fill in the extra spaces with 0's. If you do not give 4 targets, the NPCs normal sorting mechanism will be used.
|
||||
Runs when the ai is trying to pick a target in combat. Fallout first chooses a list of 4 likely suspects, then normally sorts them in order of weakness/distance/etc depending on the ai caps of the attacker. This hook replaces that sorting function, allowing you to sort the targets in some arbitrary way. Use sfall_return to give the 4 targets, in order of preference. All 4 must be given if you want to override normal sorting; if you want to specify less than 4 targets, fill in the extra spaces with 0's. If you do not give 4 targets, the NPCs normal sorting mechanism will be used.
|
||||
|
||||
The return values can include critters that weren't in the list of possible targets, but the additional targets may still be discarded later on in the combat turn if they are out of the attackers perception or the chance of a successful hit is too low. The list of possible targets often includes duplicated entries.
|
||||
|
||||
@@ -305,7 +305,7 @@ object* ret1 - 0 if the hex doesn't block, or any sort of object pointer if it d
|
||||
|
||||
HOOK_ITEMDAMAGE (hs_itemdamage.int)
|
||||
|
||||
Runs when retrieving the damage rating of the players used weapon. (Which may be their fists.)
|
||||
Runs when retrieving the damage rating of the player's used weapon. (Which may be their fists.)
|
||||
|
||||
int arg1 - The default min damage
|
||||
int arg2 - The default max damage
|
||||
@@ -340,11 +340,14 @@ HOOK_KEYPRESS (hs_keypress.int)
|
||||
Runs once every time when any key was pressed or released.
|
||||
DX codes: (see dik.h header)
|
||||
VK codes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx
|
||||
NOTE: if you want to override a key, the new key DX scancode should be the same for both pressed and released events.
|
||||
|
||||
int arg1 - event type: 1 - pressed, 0 - released
|
||||
int arg2 - key DX scancode
|
||||
int arg3 - key VK code (very similar to ASCII codes)
|
||||
|
||||
int ret1 - overrides the pressed key (a new key DX scancode or 0 for no override)
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
HOOK_MOUSECLICK (hs_mouseclick.int)
|
||||
@@ -429,7 +432,7 @@ HOOK_INVENWIELD (hs_invenwield.int)
|
||||
Runs before wielding or unwielding an armor or a weapon by a critter (except when using inventory by PC).
|
||||
An example usage would be to change critter art depending on armor being used or to dynamically customize weapon animations.
|
||||
NOTE: when replacing a previously wielded armor or weapon, the unwielding hook will not be executed.
|
||||
If you need to rely on this, try checking if armor/weapon already equipped when wielding hook is executed.
|
||||
If you need to rely on this, try checking if armor/weapon is already equipped when wielding hook is executed.
|
||||
|
||||
Critter arg1 - critter
|
||||
Obj arg2 - item being wielded or unwielded (weapon/armor), may be 0 when unwielding (object is valid only if the item is unwielded by move_obj_inven_to_obj() or rm_obj_from_inven())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
---------- GLOBAL SCRIPTS -----------
|
||||
-------------------------------------
|
||||
|
||||
As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with 'gl' and contains a procedure called 'start'. This procedure will be executed once when the player loads a saved game or starts a new game. If you wish the script to be executed repeatedly, call set_global_script_repeat on this first run using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.)
|
||||
As well as the new functions, sfall also adds global scripts. These run independent of any loaded maps, but do not have an attached object. (i.e. using self_obj without using set_self first will crash the script.) To use a global script, the script must have a name which begins with 'gl' and contains a procedure called 'start', 'map_enter_p_proc', 'map_exit_p_proc', or 'map_update_p_proc'. The start procedure will be executed once when the player loads a saved game or starts a new game. The map_*_p_proc procedures will be executed once when a map is being entered/left/updated. If you wish the script to be executed repeatedly, call set_global_script_repeat on the first run of the start procedure using the number of frames between each run as the argument. (0 disables the script, 1 runs it every frame, 2 runs it every other frame etc.)
|
||||
|
||||
Global scripts have multiple modes, which can be set using the set_global_script_type function. In the default mode (i.e. mode 0) their execution is linked to the local map game loop, so the script will not run in dialogs or on the world map. In mode 1 their execution is linked to the player input, and so they will run whenever the mouse cursor is visible on screen, including the world map, character dialogs etc. In mode 2, execution is linked to the world map loop, so the script will only be executed on the world map and not on the local map or in any dialog windows. Mode 3 is a combination of modes 0 and 2, so scripts will be executed on both local maps and the world map, but not in dialog windows. Using mode 1 requires the input wrapper to be enabled. Use available_global_script_types to check what is available.
|
||||
|
||||
@@ -48,9 +48,9 @@ set_fake_trait and set_fake_perk can be used to add additional traits and perks
|
||||
|
||||
has_fake_trait and has_fake_perk return the number of levels the player has of the perks/traits with the given name.
|
||||
|
||||
perk_add_mode, set_selectable_perk, set_perkbox_title, hide_real_perks, show_real_perks and clear_selectable_perks control the behaviour of the select a perk box. set_selectable_perk can be used to add additional items by setting the 'active' parameter to 1, and to remove them again by setting it to 0. set_perkbox_title can be used to change the title of the box, or by using "" it will be set back to the default. hide and show_real_perks can be used to prevent the dialog from displaying any of the original 119 perks. perk_add_mode modifies what happens when a fake perk is selected from the perks dialog. It is treated as a set of flags - if bit 1 is set then it is added to the players traits, if bit 2 is set it is added to the players perks, and if bit 3 is set it is removed from the list of selectable perks. The default is 0x2. clear_selectable_perks restores the dialog to it's default state.
|
||||
perk_add_mode, set_selectable_perk, set_perkbox_title, hide_real_perks, show_real_perks and clear_selectable_perks control the behaviour of the select a perk box. set_selectable_perk can be used to add additional items by setting the 'active' parameter to 1, and to remove them again by setting it to 0. set_perkbox_title can be used to change the title of the box, or by using "" it will be set back to the default. hide and show_real_perks can be used to prevent the dialog from displaying any of the original 119 perks. perk_add_mode modifies what happens when a fake perk is selected from the perks dialog. It is treated as a set of flags - if bit 1 is set then it is added to the players traits, if bit 2 is set it is added to the players perks, and if bit 3 is set it is removed from the list of selectable perks. The default is 0x2. clear_selectable_perks restores the dialog to its default state.
|
||||
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to 9 for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes.
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to 9 for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes. Starting from sfall 3.8.12, is_iface_tag_active can also be used to check 0 for SNEAK, 1 for POISONED, and 2 for RADIATED.
|
||||
|
||||
get/set_bodypart_hit_modifier alter the hit percentage modifiers for aiming at specific bodyparts. Valid bodypart id's are from 0 to 8. Changes are not saved, and will reset to the defaults (or to the values specified in ddraw.ini if they exist) at each reload.
|
||||
|
||||
@@ -98,7 +98,7 @@ array - array ID to be used with array-related functions (actually an integer)
|
||||
----------------------------------------------
|
||||
|
||||
> int game_loaded()
|
||||
- returns 1 the first time it is called after a new game or game load, and 0 any time after. It works on an individual basis for each script, so one script wont interfere with others. It's primary use is for global scripts, so that they know when to call set_global_script_repeat, but it can be called from normal scripts too.
|
||||
- returns 1 the first time it is called after a new game or game load, and 0 any time after. It works on an individual basis for each script, so one script wont interfere with others. Its primary use is for global scripts, so that they know when to call set_global_script_repeat, but it can be called from normal scripts too.
|
||||
|
||||
> void inc_npc_level(string npc)
|
||||
- takes an NPC name as an argument. The NPC must be in your party. This function ignores player level requirements and the minimum 3 player level delay between NPC level gains. It also ignores the random element, regardless of sfall's NPCAutoLevel setting.
|
||||
@@ -141,7 +141,7 @@ array - array ID to be used with array-related functions (actually an integer)
|
||||
- In this case use force_encounter_with_flags with the ENCOUNTER_FLAG_NO_CAR flag set.
|
||||
|
||||
> int get_light_level()
|
||||
- ambient light level in range 0..65535
|
||||
- ambient light level in range 0..65536
|
||||
- The value returned by get_light_level may not exactly match that set by set_light_level, as set_light_level applies modifiers from the night vision perk.
|
||||
|
||||
> void set_map_time_multi(float multi)
|
||||
@@ -216,20 +216,24 @@ Some additional reg_anim_* functions were introduced. They all work in the same
|
||||
> void reg_anim_turn_towards(object, tile/target, delay)
|
||||
- makes object change its direction to face given tile num or target object.
|
||||
|
||||
> int metarule2_explosions(int arg1, int arg2)
|
||||
> int metarule2_explosions(int arg1, int arg2, int arg3)
|
||||
was made as a dirty easy hack to allow dynamically change some explosion parameters (ranged attack). All changed parameters are reset to vanilla state automatically after each attack action. Following macros are available in sfall.h:
|
||||
|
||||
> void set_attack_explosion_pattern(x, y)
|
||||
- currently y is not used and x means: 1 - reduced explosion pattern (3 effects are spawned instead of 7), 0 - full pattern
|
||||
|
||||
> void set_attack_explosion_art(x, y)
|
||||
- y not used and x is a misc frame ID (last 3 bytes, without object type) to use for the next explosion.
|
||||
- y is not used and x is a misc frame ID (last 3 bytes, without object type) to use for the next explosion.
|
||||
|
||||
> void set_attack_explosion_radius(x)
|
||||
- changes radius at which explosion will hit secondary targets for the next attack (from the experiments it is limited to something around 8 by the engine)
|
||||
|
||||
> void set_attack_is_explosion_fire
|
||||
- if you call this right before using a weapon with fire damage type, it will produce explosion effects (and radius damage) just like "explosion" type, but all targets will still receive fire damage.
|
||||
- if you call this right before using a weapon with fire damage type (e.g. in HOOK_AFTERHITROLL), it will produce explosion effects (and radius damage) just like "explosion" type, but all targets will still receive fire damage.
|
||||
|
||||
> void set_explosion_radius(grenade, rocket)
|
||||
- sets a permanent radius of the explosion for grenades and/or rockets. Passing 0 means not changing the corresponding radius.
|
||||
- changed radius will be reset each time the player reloads the game.
|
||||
|
||||
|
||||
Some utility/math functions are available:
|
||||
@@ -306,7 +310,7 @@ Some utility/math functions are available:
|
||||
- this calls an internal engine function which is used to determine the perception range of critters (which you can override using HOOK_WITHINPERCEPTION)
|
||||
|
||||
> int tile_light(int elevation, int tileNum)
|
||||
- returns light intensity at the given tile in range from 0 to 65535
|
||||
- returns light intensity at the given tile in range from 0 to 65536
|
||||
|
||||
> object obj_blocking_line(object objFrom, int tileTo, int blockingType)
|
||||
- returns first object which blocks direct linear path from objFrom to tileTo using selected blocking function (see BLOCKING_TYPE_* constants in sfall.h)
|
||||
@@ -385,6 +389,84 @@ Some utility/math functions are available:
|
||||
- works just like vanilla floor function, but returns correct integers for negative values
|
||||
- vanilla floor function works exactly the same as ceil for negative values, much like trunc in C/C++
|
||||
|
||||
> int sfall_func1("item_weight", object)
|
||||
- gets the current weight of an object
|
||||
|
||||
> int sfall_func1("get_outline", object)
|
||||
- gets the current outline color for an object
|
||||
|
||||
> void sfall_func2("set_outline", object, int color)
|
||||
- sets the outline color of an object
|
||||
- 0 means or any value above 0x00FFFFFF disables the outline
|
||||
- call "tile_refresh_display" after changing outline of objects to properly redraw the scene
|
||||
|
||||
> int sfall_func1("get_flags", object)
|
||||
- gets the current value of object flags (see define_extra.h for available flags)
|
||||
|
||||
> void sfall_func2("set_flags", object, int flags)
|
||||
- sets the current flags of an object
|
||||
- all flags are rewritten with given integer, so first get current flags with "get_flags" and use bwor/bwand to set/remove specific flag
|
||||
|
||||
> void sfall_func0("tile_refresh_display")
|
||||
- redraws the game scene (tiles, walls, objects, etc.)
|
||||
|
||||
> object sfall_func0("outlined_object")
|
||||
- returns an object that is currently highlighted by hovering the mouse above it
|
||||
|
||||
> int sfall_func0("get_cursor_mode")
|
||||
- returns the current cursor mode (0 - movement cursor, 1 - command cursor, 2 - targeting cursor)
|
||||
- mode 4 to 10 are Skilldex skills (yellow targeting cursor)
|
||||
|
||||
> void sfall_func1("set_cursor_mode", int mode)
|
||||
- sets the current cursor mode
|
||||
|
||||
> void sfall_func0("display_stats")
|
||||
- displays player stats in the inventory screen display window
|
||||
- works only in opened inventory
|
||||
|
||||
> int sfall_func1("lock_is_jammed", object)
|
||||
- returns 1 if the lock (container or scenery) is currently jammed, 0 otherwise
|
||||
|
||||
> void sfall_func1("unjam_lock", object)
|
||||
- unjams a lock immediately without having to wait until the next day, or leave the map and then return after 24 hours
|
||||
- does not work in use_skill_on_p_proc procedure
|
||||
|
||||
> array sfall_func0("get_map_enter_position")
|
||||
- returns an array of the player's position data (index 0 - tile, 1 - elevation, 2 - rotation) when entering the map through exit grids
|
||||
- if entering from the world map, the tile value will be -1
|
||||
- should be called in map_enter_p_proc procedure to get the correct position data
|
||||
|
||||
> void sfall_func3("set_map_enter_position", int tile, int elevation, int rotation)
|
||||
- overrides the player's entry position when entering the map through exit grids
|
||||
- setting the tile to 0 will put the player on the start hex (default tile and elevation) of the map
|
||||
- works only in map_enter_p_proc procedure
|
||||
|
||||
> int sfall_func0("attack_is_aimed")
|
||||
- returns 1 if the aimed attack mode is selected, 0 otherwise
|
||||
|
||||
> void sfall_func1("inventory_redraw", int invSide)
|
||||
- redraws inventory list in the inventory/use inventory item on/loot/barter screens
|
||||
- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens)
|
||||
|
||||
> int sfall_func1("get_current_inven_size", object)
|
||||
- returns the current inventory size of the container or the critter
|
||||
|
||||
> void sfall_func5("create_win", string winName, int x, int y, int width, int height)
|
||||
> void sfall_func6("create_win", string winName, int x, int y, int width, int height, int flags)
|
||||
- works just like vanilla CreateWin function, but creates a window with MoveOnTop flag if the flags argument is not specified, and allows to set additional flags for the created window
|
||||
- MoveOnTop flag allows the created window to be placed on top of the game interface
|
||||
|
||||
> object sfall_func2("obj_under_cursor", bool crSwitch, bool inclDude)
|
||||
- returns the object under the cursor on the main game screen
|
||||
- crSwitch: True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.), False - checks all objects (can't check critters under objects)
|
||||
- passing False to the inclDude argument will ignore dude_obj
|
||||
|
||||
> int sfall_func2("get_object_data", object, int offset)
|
||||
- returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets)
|
||||
|
||||
> void sfall_func3("set_object_data", object, int offset, int data)
|
||||
- sets the data at the specified offset of an object
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
*0x8156 - int read_byte(int address)
|
||||
*0x8157 - int read_short(int address)
|
||||
*0x8158 - int read_int(int address)
|
||||
*0x8159 - string read_string(int address)
|
||||
0x8156 - int read_byte(int address)
|
||||
0x8157 - int read_short(int address)
|
||||
0x8158 - int read_int(int address)
|
||||
0x8159 - string read_string(int address)
|
||||
|
||||
*0x81cf - void write_byte(int address, int value)
|
||||
*0x81d0 - void write_short(int address, int value)
|
||||
@@ -132,13 +132,13 @@
|
||||
0x819d - void set_sfall_global(string/int varname, int/float value)
|
||||
0x819e - int get_sfall_global_int(string/int varname)
|
||||
0x819f - float get_sfall_global_float(string/int varname)
|
||||
0x822d - int create_array(int elementcount, int elementsize)
|
||||
0x822d - int create_array(int elementcount, int flags)
|
||||
0x822e - void set_array(int array, any element, any value)
|
||||
0x822f - any get_array(int array, any element)
|
||||
0x8230 - void free_array(int array)
|
||||
0x8231 - int len_array(int array)
|
||||
0x8232 - void resize_array(int array, int newelementcount)
|
||||
0x8233 - int temp_array(int elementcount, int elementsize)
|
||||
0x8233 - int temp_array(int elementcount, int flags)
|
||||
0x8234 - void fix_array(int array)
|
||||
0x8239 - int scan_array(int array, int/float var)
|
||||
0x8256 - int array_key(int array, int index)
|
||||
|
||||
+10
-7
@@ -40,19 +40,22 @@ DWORD _stdcall AIGetLastTarget(DWORD source) {
|
||||
else return itr->second;
|
||||
}
|
||||
|
||||
static void _stdcall CombatAttackHook(DWORD source, DWORD target) {
|
||||
sources[target]=source;
|
||||
targets[source]=target;
|
||||
static void __fastcall CombatAttackHook(DWORD source, DWORD target) {
|
||||
sources[target] = source;
|
||||
targets[source] = target;
|
||||
}
|
||||
|
||||
static void __declspec(naked) combat_attack_hook() {
|
||||
_asm {
|
||||
pushad;
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call CombatAttackHook;
|
||||
popad;
|
||||
jmp combat_attack_;
|
||||
mov ecx, eax; // source
|
||||
call CombatAttackHook; // edx - target
|
||||
pop eax;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
jmp combat_attack_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+372
-682
File diff suppressed because it is too large
Load Diff
@@ -162,7 +162,7 @@ skip:
|
||||
call combat_anim_finished_;
|
||||
end:
|
||||
mov [edi][esi], ebx;
|
||||
push 0x415DF2;
|
||||
xor dl, dl; // goto 0x415DF2;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,8 @@ static DWORD __fastcall CheckSetSad(BYTE openFlag, DWORD valueMul) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static const DWORD object_move_back0 = 0x417611;
|
||||
static const DWORD object_move_back1 = 0x417616;
|
||||
static void __declspec(naked) object_move_hack() {
|
||||
__asm {
|
||||
mov ecx, ds:[ecx + 0x3C]; // openFlag
|
||||
@@ -188,11 +190,9 @@ static void __declspec(naked) object_move_hack() {
|
||||
call CheckSetSad;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
push 0x417611; // fixed jump
|
||||
retn;
|
||||
jmp object_move_back0; // fixed jump
|
||||
end:
|
||||
push 0x417616; // default
|
||||
retn;
|
||||
jmp object_move_back1; // default
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ void ApplyAnimationsAtOncePatches(signed char aniMax) {
|
||||
SafeWrite32(animMaxSizeCheck[i], animRecordSize * aniMax);
|
||||
}
|
||||
|
||||
//divert old animation structure list pointers to newly alocated memory
|
||||
//divert old animation structure list pointers to newly allocated memory
|
||||
|
||||
//struct array 1///////////////////
|
||||
|
||||
@@ -356,7 +356,7 @@ void AnimationsAtOnceInit() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
// Fix for calling anim() functions in combat
|
||||
MakeJump(0x415DE2, anim_set_end_hack);
|
||||
MakeCall(0x415DE2, anim_set_end_hack, 1);
|
||||
|
||||
// Fix crash when the critter goes through a door with animation trigger
|
||||
MakeJump(0x41755E, object_move_hack);
|
||||
|
||||
+135
-61
@@ -2,6 +2,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "Arrays.h"
|
||||
#include "FalloutEngine.h"
|
||||
#include "ScriptExtender.h"
|
||||
|
||||
/*
|
||||
@@ -11,7 +12,7 @@ DWORD arraysBehavior = 1; // 0 - backward compatible with pre-3.4, 1 - permanent
|
||||
// arrays map: arrayId => arrayVar
|
||||
ArraysMap arrays;
|
||||
// auto-incremented ID
|
||||
DWORD nextarrayid=1;
|
||||
DWORD nextarrayid = 1;
|
||||
// temp arrays: set of arrayId
|
||||
std::set<DWORD> tempArrays;
|
||||
// saved arrays: arrayKey => arrayId
|
||||
@@ -101,7 +102,7 @@ DWORD sArrayElement::getHashStatic(DWORD value, DWORD type) {
|
||||
str = (const char*)value;
|
||||
int i;
|
||||
DWORD res;
|
||||
for (i=0, res=0; str[i]!='\0'; i++) {
|
||||
for (i = 0, res = 0; str[i] != '\0'; i++) {
|
||||
res = ((res << 5) + res) + str[i];
|
||||
}
|
||||
return res;
|
||||
@@ -189,28 +190,28 @@ void LoadArraysOld(HANDLE h) {
|
||||
dlogr("Loading arrays (old fmt)", DL_MAIN);
|
||||
DWORD count, unused, id, j;
|
||||
ReadFile(h, &count, 4, &unused, 0);
|
||||
if(unused!=4) return;
|
||||
if (unused != 4) return;
|
||||
sArrayVarOld var;
|
||||
sArrayVar varN;
|
||||
for(DWORD i=0;i<count;i++) {
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
ReadFile(h, &id, 4, &unused, 0);
|
||||
ReadFile(h, &var, 8, &unused, 0);
|
||||
var.types=new DWORD[var.len];
|
||||
var.data=new char[var.len*var.datalen];
|
||||
ReadFile(h, var.types, 4*var.len, &unused, 0);
|
||||
var.types = new DWORD[var.len];
|
||||
var.data = new char[var.len * var.datalen];
|
||||
ReadFile(h, var.types, 4 * var.len, &unused, 0);
|
||||
ReadFile(h, var.data, var.len*var.datalen, &unused, 0);
|
||||
varN.flags = 0;
|
||||
varN.val.resize(var.len);
|
||||
for (j=0; j<var.len; j++) {
|
||||
for (j = 0; j < var.len; j++) {
|
||||
switch (var.types[j]) {
|
||||
case DATATYPE_INT:
|
||||
varN.val[j].set(*(long*)(&var.data[var.datalen*j]));
|
||||
varN.val[j].set(*(long*)(&var.data[var.datalen * j]));
|
||||
break;
|
||||
case DATATYPE_FLOAT:
|
||||
varN.val[j].set(*(float*)(&var.data[var.datalen*j]));
|
||||
varN.val[j].set(*(float*)(&var.data[var.datalen * j]));
|
||||
break;
|
||||
case DATATYPE_STR:
|
||||
varN.val[j].set(&var.data[var.datalen*j], var.datalen - 1);
|
||||
varN.val[j].set(&var.data[var.datalen * j], var.datalen - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -230,7 +231,7 @@ void LoadArrays(HANDLE h) {
|
||||
if (unused != 4) return;
|
||||
sArrayVar arrayVar;
|
||||
nextarrayid = 1;
|
||||
for (DWORD i=0; i<count; i++) {
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
LoadArrayElement(&arrayVar.key, h);
|
||||
if (arrayVar.key.type > 4 || arrayVar.key.intVal == 0) { // partial compatibility with 3.4
|
||||
arrayVar.key.intVal = arrayVar.key.type;
|
||||
@@ -240,7 +241,7 @@ void LoadArrays(HANDLE h) {
|
||||
ReadFile(h, &elCount, 4, &unused, 0); // actual number of elements: keys+values
|
||||
bool isAssoc = arrayVar.isAssoc();
|
||||
arrayVar.val.resize(elCount);
|
||||
for (j=0; j<elCount; j++) { // normal and associative arrays stored and loaded equally
|
||||
for (j = 0; j < elCount; j++) { // normal and associative arrays stored and loaded equally
|
||||
LoadArrayElement(&arrayVar.val[j], h);
|
||||
if (isAssoc && (j % 2) == 0) { // only difference is that keyHash is filled with appropriate indexes
|
||||
arrayVar.keyHash[arrayVar.val[j]] = j;
|
||||
@@ -288,27 +289,29 @@ void SaveArrays(HANDLE h) {
|
||||
int GetNumArrays() {
|
||||
return arrays.size();
|
||||
}
|
||||
|
||||
void GetArrays(int* _arrays) {
|
||||
int pos=0;
|
||||
array_citr itr=arrays.begin();
|
||||
while(itr!=arrays.end()) {
|
||||
_arrays[pos++]=itr->first;
|
||||
_arrays[pos++]=itr->second.size();
|
||||
_arrays[pos++]=itr->second.flags;
|
||||
int pos = 0;
|
||||
array_citr itr = arrays.begin();
|
||||
while (itr != arrays.end()) {
|
||||
_arrays[pos++] = itr->first;
|
||||
_arrays[pos++] = itr->second.size();
|
||||
_arrays[pos++] = itr->second.flags;
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
// those too are not really used yet in FalloutClient (AFAIK) -- phobos2077
|
||||
void DEGetArray(int id, DWORD* types, void* data) {
|
||||
//memcpy(types, arrays[id].types, arrays[id].len*4);
|
||||
//memcpy(data, arrays[id].data, arrays[id].len*arrays[id].datalen);
|
||||
}
|
||||
|
||||
void DESetArray(int id, const DWORD* types, const void* data) {
|
||||
//if(types) memcpy(arrays[id].types, types, arrays[id].len*4);
|
||||
//if (types) memcpy(arrays[id].types, types, arrays[id].len * 4);
|
||||
//memcpy(arrays[id].data, data, arrays[id].len*arrays[id].datalen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Array manipulation functions for script operators
|
||||
TODO: move somewhere else
|
||||
@@ -355,28 +358,34 @@ DWORD _stdcall getScriptTypeBySfallType(DWORD dataType) {
|
||||
}
|
||||
}
|
||||
|
||||
DWORD _stdcall CreateArray(int len, DWORD nothing) {
|
||||
DWORD _stdcall CreateArray(int len, DWORD flags) {
|
||||
sArrayVar var;
|
||||
if (len < 0) var.flags |= ARRAYFLAG_ASSOC;
|
||||
else if (len > ARRAY_MAX_SIZE) len = ARRAY_MAX_SIZE; // safecheck
|
||||
var.flags = (flags & 0xFFFFFFFE); // reset 1 bit
|
||||
if (len < 0) {
|
||||
var.flags |= ARRAYFLAG_ASSOC;
|
||||
} else if (len > ARRAY_MAX_SIZE) {
|
||||
len = ARRAY_MAX_SIZE; // safecheck
|
||||
}
|
||||
if (!var.isAssoc()) {
|
||||
var.val.resize(len);
|
||||
}
|
||||
while(arrays.find(nextarrayid)!=arrays.end()) nextarrayid++;
|
||||
while (arrays.find(nextarrayid) != arrays.end()) nextarrayid++;
|
||||
if (nextarrayid == 0) nextarrayid++;
|
||||
if (arraysBehavior == 0) {
|
||||
var.key = sArrayElement(nextarrayid, DATATYPE_INT);
|
||||
savedArrays[var.key] = nextarrayid;
|
||||
}
|
||||
stackArrayId = nextarrayid;
|
||||
arrays[nextarrayid]=var;
|
||||
arrays[nextarrayid] = var;
|
||||
return nextarrayid++;
|
||||
}
|
||||
DWORD _stdcall TempArray(DWORD len, DWORD nothing) {
|
||||
DWORD id=CreateArray(len, nothing);
|
||||
|
||||
DWORD _stdcall TempArray(DWORD len, DWORD flags) {
|
||||
DWORD id = CreateArray(len, flags);
|
||||
tempArrays.insert(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void _stdcall FreeArray(DWORD id) {
|
||||
array_itr it = arrays.find(id);
|
||||
if (it != arrays.end()) {
|
||||
@@ -415,7 +424,7 @@ DWORD _stdcall GetArrayKey(DWORD id, int index, DWORD* resultType) {
|
||||
|
||||
DWORD _stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType) {
|
||||
*resultType = VAR_TYPE_INT;
|
||||
if(arrays.find(id)==arrays.end()) return 0;
|
||||
if (arrays.find(id) == arrays.end()) return 0;
|
||||
int el;
|
||||
sArrayVar &arr = arrays[id];
|
||||
if (arr.isAssoc()) {
|
||||
@@ -429,7 +438,7 @@ DWORD _stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType) {
|
||||
// check for invalid index
|
||||
if (el < 0 || el >= arr.size()) return 0;
|
||||
}
|
||||
switch(arr.val[el].type) {
|
||||
switch (arr.val[el].type) {
|
||||
case DATATYPE_NONE: return 0;
|
||||
case DATATYPE_INT:
|
||||
return *(DWORD *)&arr.val[el].intVal;
|
||||
@@ -442,17 +451,24 @@ DWORD _stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _stdcall SetArray(DWORD id, DWORD key, DWORD keyType, DWORD val, DWORD valType, DWORD allowUnset) {
|
||||
keyType = getSfallTypeByScriptType(keyType);
|
||||
valType = getSfallTypeByScriptType(valType);
|
||||
if(arrays.find(id)==arrays.end()) return;
|
||||
if (arrays.find(id) == arrays.end()) return;
|
||||
int el;
|
||||
sArrayVar &arr = arrays[id];
|
||||
if (arrays[id].isAssoc()) {
|
||||
sArrayElement sEl(key, keyType);
|
||||
ArrayKeysMap::iterator elIter = arr.keyHash.find(sEl);
|
||||
el = (elIter != arr.keyHash.end()) ? elIter->second : -1;
|
||||
if (valType == DATATYPE_INT && val == 0 && allowUnset) {
|
||||
el = (elIter != arr.keyHash.end())
|
||||
? elIter->second
|
||||
: -1;
|
||||
|
||||
bool lookupMap = (arr.flags & ARRAYFLAG_CONSTVAL) != 0;
|
||||
if (lookupMap && el != -1) return; // don't update value of key
|
||||
|
||||
if (allowUnset && !lookupMap && (valType == DATATYPE_INT && val == 0)) {
|
||||
// after assigning zero to a key, no need to store it, because "get_array" returns 0 for non-existent keys: try unset
|
||||
if (el >= 0) {
|
||||
// remove from hashtable
|
||||
@@ -486,25 +502,89 @@ void _stdcall SetArray(DWORD id, DWORD key, DWORD keyType, DWORD val, DWORD valT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _stdcall LenArray(DWORD id) {
|
||||
if(arrays.find(id)==arrays.end()) return -1;
|
||||
if (arrays.find(id)==arrays.end()) return -1;
|
||||
else return arrays[id].size();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void ListSort(std::vector<T> &arr, int type) {
|
||||
switch (type) {
|
||||
case ARRAY_ACTION_SORT: // sort ascending
|
||||
std::sort(arr.begin(), arr.end());
|
||||
break;
|
||||
case ARRAY_ACTION_RSORT: // sort descending
|
||||
std::sort(arr.rbegin(), arr.rend());
|
||||
break;
|
||||
case ARRAY_ACTION_REVERSE: // reverse elements
|
||||
std::reverse(arr.rbegin(), arr.rend());
|
||||
break;
|
||||
case ARRAY_ACTION_SHUFFLE: // shuffle elements
|
||||
std::random_shuffle(arr.rbegin(), arr.rend());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MapSort(sArrayVar& arr, int type) {
|
||||
std::vector<std::pair<sArrayElement, sArrayElement>> map;
|
||||
map.reserve(arr.val.size());
|
||||
|
||||
bool sortByValue = false;
|
||||
if (type < ARRAY_ACTION_SHUFFLE) {
|
||||
type += 4;
|
||||
sortByValue = true;
|
||||
}
|
||||
|
||||
sArrayElement key, val;
|
||||
for (size_t i = 0; i < arr.val.size(); ++i) {
|
||||
if (sortByValue) {
|
||||
val = arr.val[i++]; // map key > value
|
||||
key = arr.val[i]; // map value > key
|
||||
} else {
|
||||
key = arr.val[i]; // key
|
||||
val = arr.val[++i]; // value
|
||||
}
|
||||
map.push_back(std::make_pair(key, val));
|
||||
}
|
||||
ListSort(map, type);
|
||||
|
||||
arr.val.clear();
|
||||
arr.keyHash.clear();
|
||||
for (size_t i = 0; i < map.size(); ++i) {
|
||||
size_t el = arr.val.size();
|
||||
if (sortByValue) {
|
||||
arr.val.push_back(map[i].second); // map value > key
|
||||
arr.val.push_back(map[i].first); // map key > value
|
||||
} else {
|
||||
arr.val.push_back(map[i].first);
|
||||
arr.val.push_back(map[i].second);
|
||||
}
|
||||
arr.keyHash[arr.val[el]] = el;
|
||||
}
|
||||
}
|
||||
|
||||
void _stdcall ResizeArray(DWORD id, int newlen) {
|
||||
if (arrays.find(id) == arrays.end() || arrays[id].size() == newlen) return;
|
||||
if (newlen == -1 || arrays.find(id) == arrays.end() || arrays[id].size() == newlen) return;
|
||||
sArrayVar &arr = arrays[id];
|
||||
if (arr.isAssoc()) {
|
||||
// only allow to reduce number of elements (adding range of elements is meaningless for maps)
|
||||
if (newlen < arrays[id].size()) {
|
||||
if (newlen >= 0 && newlen < arrays[id].size()) {
|
||||
ArrayKeysMap::iterator itHash;
|
||||
std::vector<sArrayElement>::iterator itVal;
|
||||
int actualLen = newlen*2;
|
||||
int actualLen = newlen * 2;
|
||||
for (itVal = arr.val.begin() + actualLen; itVal != arr.val.end(); itVal += 2) {
|
||||
if ((itHash = arr.keyHash.find(*itVal)) != arr.keyHash.end())
|
||||
arr.keyHash.erase(itHash);
|
||||
}
|
||||
arr.clearRange(actualLen);
|
||||
arr.val.resize(actualLen);
|
||||
} else if (newlen < 0) {
|
||||
if (newlen < (ARRAY_ACTION_SHUFFLE - 2)) {
|
||||
DebugPrintf("\nOPCODE ERROR: resize_array() - array sorting error.");
|
||||
return;
|
||||
}
|
||||
MapSort(arr, newlen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -515,25 +595,18 @@ void _stdcall ResizeArray(DWORD id, int newlen) {
|
||||
arr.clearRange(newlen);
|
||||
arr.val.resize(newlen);
|
||||
} else { // special functions for lists...
|
||||
switch (newlen) {
|
||||
case ARRAY_ACTION_SORT: // sort ascending
|
||||
std::sort(arr.val.begin(), arr.val.end());
|
||||
break;
|
||||
case ARRAY_ACTION_RSORT: // sort descending
|
||||
std::sort(arr.val.rbegin(), arr.val.rend());
|
||||
break;
|
||||
case ARRAY_ACTION_REVERSE: // reverse elements
|
||||
std::reverse(arr.val.rbegin(), arr.val.rend());
|
||||
break;
|
||||
case ARRAY_ACTION_SHUFFLE: // shuffle elements
|
||||
std::random_shuffle(arr.val.rbegin(), arr.val.rend());
|
||||
break;
|
||||
if (newlen < ARRAY_ACTION_SHUFFLE) {
|
||||
DebugPrintf("\nOPCODE ERROR: resize_array() - array sorting error.");
|
||||
return;
|
||||
}
|
||||
ListSort(arr.val, newlen);
|
||||
}
|
||||
}
|
||||
|
||||
void _stdcall FixArray(DWORD id) {
|
||||
tempArrays.erase(id);
|
||||
}
|
||||
|
||||
int _stdcall ScanArray(DWORD id, DWORD val, DWORD datatype, DWORD* resultType) {
|
||||
*resultType = VAR_TYPE_INT;
|
||||
datatype = getSfallTypeByScriptType(datatype);
|
||||
@@ -542,15 +615,15 @@ int _stdcall ScanArray(DWORD id, DWORD val, DWORD datatype, DWORD* resultType) {
|
||||
for (DWORD i = 0; i < arrays[id].val.size(); i += step) {
|
||||
sArrayElement &el = arrays[id].val[i + step - 1];
|
||||
if (el.type == datatype) {
|
||||
if ((datatype != DATATYPE_STR && *(DWORD*)&(el.intVal) == val) ||
|
||||
(datatype == DATATYPE_STR && strcmp(el.strVal, (char*)val) == 0)) {
|
||||
if (arrays[id].isAssoc()) { // return key instead of index for associative arrays
|
||||
*resultType = getScriptTypeBySfallType(arrays[id].val[i].type);
|
||||
return *(DWORD *)&arrays[id].val[i].intVal;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if ((datatype != DATATYPE_STR && *(DWORD*)&(el.intVal) == val) ||
|
||||
(datatype == DATATYPE_STR && strcmp(el.strVal, (char*)val) == 0)) {
|
||||
if (arrays[id].isAssoc()) { // return key instead of index for associative arrays
|
||||
*resultType = getScriptTypeBySfallType(arrays[id].val[i].type);
|
||||
return *(DWORD *)&arrays[id].val[i].intVal;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -574,8 +647,9 @@ DWORD _stdcall LoadArray(DWORD key, DWORD keyType) {
|
||||
}
|
||||
} else {
|
||||
ArrayKeysMap::iterator it = savedArrays.find(keyEl);
|
||||
if (it != savedArrays.end())
|
||||
if (it != savedArrays.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // not found
|
||||
@@ -621,4 +695,4 @@ DWORD _stdcall StackArray(DWORD key, DWORD keyType, DWORD val, DWORD valType) {
|
||||
}
|
||||
SetArray(id, key, keyType, val, valType, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -74,6 +74,7 @@ struct sArrayVarOld
|
||||
};
|
||||
|
||||
#define ARRAYFLAG_ASSOC (1) // is map
|
||||
#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
|
||||
|
||||
typedef std::tr1::unordered_map<sArrayElement, DWORD, sArrayElement_HashFunc, sArrayElement_EqualFunc> ArrayKeysMap;
|
||||
|
||||
@@ -87,13 +88,14 @@ class sArrayVar
|
||||
{
|
||||
public:
|
||||
DWORD flags;
|
||||
sArrayElement key; // array associated key, if it was saved
|
||||
sArrayElement key; // array associated key, if it was saved
|
||||
ArrayKeysMap keyHash; // key element => element index, for faster lookup
|
||||
std::vector<sArrayElement> val; // list of values or key=>value pairs (even - keys, odd - values)
|
||||
|
||||
bool isAssoc() const {
|
||||
return (flags & ARRAYFLAG_ASSOC);
|
||||
}
|
||||
|
||||
// logical array size (number of elements for normal arrays; number of key=>value pairs for associative)
|
||||
int size() const {
|
||||
return isAssoc()
|
||||
@@ -109,6 +111,7 @@ public:
|
||||
}
|
||||
|
||||
sArrayVar() : flags(0), key() {}
|
||||
|
||||
// free memory used by strings
|
||||
void clear() {
|
||||
clearRange(0);
|
||||
@@ -146,9 +149,9 @@ const char* _stdcall GetSfallTypeName(DWORD dataType);
|
||||
DWORD _stdcall getSfallTypeByScriptType(DWORD varType);
|
||||
DWORD _stdcall getScriptTypeBySfallType(DWORD dataType);
|
||||
// creates new normal (persistent) array. len == -1 specifies associative array (map)
|
||||
DWORD _stdcall CreateArray(int len, DWORD nothing);
|
||||
DWORD _stdcall CreateArray(int len, DWORD flags);
|
||||
// same as CreateArray, but creates temporary array instead (will die at the end of the frame)
|
||||
DWORD _stdcall TempArray(DWORD len, DWORD nothing);
|
||||
DWORD _stdcall TempArray(DWORD len, DWORD flags);
|
||||
// destroys array
|
||||
void _stdcall FreeArray(DWORD id);
|
||||
/*
|
||||
|
||||
+7
-5
@@ -88,17 +88,19 @@ void BarBoxesInit() {
|
||||
}
|
||||
}
|
||||
|
||||
int _stdcall GetBox(int i) {
|
||||
if (i < 5 || i > 9) return 0;
|
||||
return boxesEnabled[i - 5];
|
||||
bool GetBox(int i) {
|
||||
if (i < 5 || i > 9) return false;
|
||||
return (boxesEnabled[i - 5] != 0);
|
||||
}
|
||||
|
||||
void _stdcall AddBox(int i) {
|
||||
void AddBox(int i) {
|
||||
if (i < 5 || i > 9) return;
|
||||
boxesEnabled[i - 5] = 1;
|
||||
__asm call refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
void _stdcall RemoveBox(int i) {
|
||||
void RemoveBox(int i) {
|
||||
if (i < 5 || i > 9) return;
|
||||
boxesEnabled[i - 5] = 0;
|
||||
__asm call refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
void BarBoxesInit();
|
||||
int _stdcall GetBox(int i);
|
||||
void _stdcall AddBox(int i);
|
||||
void _stdcall RemoveBox(int i);
|
||||
bool GetBox(int i);
|
||||
void AddBox(int i);
|
||||
void RemoveBox(int i);
|
||||
|
||||
+705
-91
File diff suppressed because it is too large
Load Diff
+5
-2
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
extern DWORD WeightOnBody;
|
||||
|
||||
void BugsInit();
|
||||
|
||||
void ResetBodyState();
|
||||
void GameInitialization();
|
||||
|
||||
extern int tagSkill4LevelBase;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user