Merge branch 'develop'

This commit is contained in:
NovaRain
2020-08-22 13:15:50 +08:00
91 changed files with 2387 additions and 1104 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ Image=24
ButtonCount=3
;Set the appearance of the elevator
MainFrm=148
ButtonsFrm=151
MainFrm=148 ; EL_VAULT.FRM
ButtonsFrm=151 ; EL_MIL3.FRM
;Set up the exit points for all three buttons (see examples above)
+1
View File
@@ -21,6 +21,7 @@ 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)
OutlineColor=16
; Motion Scanner mode:
+18 -13
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v4.2.6
;v4.2.7
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
@@ -85,6 +85,7 @@ GPUBlt=0
Use32BitHeadGraphics=0
;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies
;Set to 2 to force avi videos to fit the screen width
;Requires DX9 graphics mode
AllowDShowMovies=0
@@ -132,8 +133,8 @@ AllowSoundForFloats=0
;This does not effect the play_sfall_sound and stop_sfall_sound script functions
AllowDShowSound=0
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
;Set to 2 to overwrite all occurances of the music path
;Set to 1 to override the default music path with data\sound\music\ if music_path is not present in the cfg
;Set to 2 to overwrite all occurrences of the music path
OverrideMusicDir=1
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -284,7 +285,8 @@ DialogGenderWords=0
;FemaleDefaultModel=hfjmps
;To change the various ingame movies, modify the next 17 lines
;Most of these can also be changed ingame via script.
;You can also define additional movies by adding Movie18 - Movie32 lines
;Most of these can also be changed ingame via script
Movie1=iplogo.mve
Movie2=intro.mve
Movie3=elder.mve
@@ -340,7 +342,7 @@ DialogueFix=1
;Prevents you from using number keys to enter unvisited areas on a town map
TownMapHotkeysFix=1
;Set to 1 to disable the horrigan encounter
;Set to 1 to disable the Horrigan encounter
DisableHorrigan=0
;Set to 1 to disable the random element in NPC levelling.
@@ -404,7 +406,7 @@ AlwaysReloadMsgs=0
PlayIdleAnimOnReload=0
;Changes the timer (in days) for deleting corpses on a map after you leave (valid range: 0..13)
;The corpses of critters with 'Ages' flag or on maps with 'dead_bodies_age=No' set in maps.txt will not disappear
;The corpses of critters with 'Ages' flag set or on maps with 'dead_bodies_age=No' set in maps.txt will not disappear
;Default is 6. Set to 0 for a 12-hour timer
CorpseDeleteTime=6
@@ -574,8 +576,8 @@ SuperStimExploitFix=0
InventoryApCost=4
QuickPocketsApCostReduction=2
;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
;Set to 1 to fix obj_can_see_obj script function to allow critters to see through objects with 'ShootThru' flag set and other critters in front of them
;Note that enabling this option can cause unexpected NPC behavior in some cases, e.g. initiating combat or dialogue when the player is behind certain obstacles
ObjCanSeeObj_ShootThru_Fix=0
;Set to 1 to fix the broken obj_can_hear_obj script function
@@ -585,11 +587,10 @@ ObjCanHearObjFix=0
;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 fix and repurpose the unused called_shot/num_attacks arguments of attack_complex script function
;This also changes the behavior of the result flags arguments
;called_shot - additional damage, when the damage received by the target is above the specified minimum damage
;Set to 1 to fix attacker_results/target_results arguments and repurpose the unused called_shot/num_attacks arguments of attack_complex script function
;New behavior of the arguments:
;called_shot - additional damage when hitting the target
;num_attacks - the number of free action points on the first turn only
;attacker_results - unused, must be 0 or not equal to the target_results argument when specifying result flags for the target
AttackComplexFix=0
;Set to 1 to fix the issue with the division operator treating negative integers as unsigned
@@ -696,6 +697,10 @@ 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 use Fallout's normal text font for death screen subtitles
;Requires changing the color of subtitles in death.pal palette to white color (index 220) to display the text correctly
DeathScreenFontPatch=0
;Set to 1 to keep the selected attack mode when moving the weapon between active item slots
KeepWeaponSelectMode=1
@@ -831,7 +836,7 @@ DontDeleteProtos=0
;Set to 1 to force sfall to inject all hooks code into the game, even if corresponding hook scripts don't exist
InjectAllGameHooks=0
;Set to 1 to force sfall to search for global scripts every time the game loads rather than only once on the first game start
;Set to 1 to force sfall to search for global/hook scripts every time the game loads rather than only the first time
AlwaysFindScripts=0
;Set to 1 to force critters to display combat float messages
+208 -74
View File
@@ -1,4 +1,23 @@
// Status: WIP
///////////////////////////////////////////////////////////////////////////////
// Blur filter setting
//
// min: blurFalloff 8, sharpness 10/8
// mid: blurFalloff 6, sharpness 8
// max: blurFalloff 4, sharpness 6
///////////////////////////////////////////////////////////////////////////////
#define blurFalloff 4.0
#define sharpness 6.0
///////////////////////////////////////////////////////////////////////////////
// Sharpen filter setting
//
// min: Sharpen 0.5, EdgeSharpen 1.0
// mid: Sharpen 1.0, EdgeSharpen -0.25
// max: Sharpen 1.75, EdgeSharpen -0.5 (1.5, -0.25)
///////////////////////////////////////////////////////////////////////////////
#define Sharpen 0.5
#define EdgeSharpen 1.0
texture bloomMap;
sampler s0;
@@ -12,6 +31,88 @@ sampler BloomSampler : samplerstate
AddressV = Clamp;
};
// Variables that set the width and height of the current game resolution from sfall
float w;
float h;
static const float2 resolution = float2(w, h);
static const float2 wPass = float2(1, 0);
static const float2 hPass = float2(0, 1);
float Brightness(float3 color)
{
return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
}
float3 BlurFunction(float2 uv, float brightness, inout float totalWeight)
{
float3 pointColor = (tex2Dlod(s0, float4(uv, 0, 0)).rgb);
float diff = abs(brightness - Brightness(pointColor));
float weight = exp2((-0.25 * blurFalloff) - (diff * sharpness));
totalWeight += weight;
return pointColor * weight;
}
float4 BlurDeltaPassPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
{
float3 sumColor = (tex2D(s0, uv).rgb);
float brightness = Brightness(sumColor);
delta *= (1 / resolution);
float totalWeight = 1;
float2 pointUV = uv + delta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - delta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight), 1);
}
static const float2 wDelta = float2(1, 0) * (1 / resolution);
static const float2 hDelta = float2(0, 1) * (1 / resolution);
float4 BlurPS(float4 color : COLOR0, float2 uv : TEXCOORD0) : COLOR0
{
float totalWeight = 1;
float3 sumColor = (tex2D(s0, uv).rgb);
float brightness = Brightness(sumColor);
float2 pointUV = uv + wDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - wDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv + hDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - hDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight), 1);
}
///////////////////////////////////////////////////////////////////////////////
// Bloom effect setting
//
// min: BloomIntensity .8
// mid: BloomIntensity .85
// max: BloomIntensity .9
///////////////////////////////////////////////////////////////////////////////
#define BaseIntensity 1.2
#define BaseSaturation 1.0
#define BloomIntensity 0.8
#define BloomSaturation 0.35
#define BloomThreshold 0.35
#define BlurPower 0.002
// pseudo gauss blur
static const float2 offsets[12] = {
-0.326212, -0.405805,
@@ -28,89 +129,122 @@ static const float2 offsets[12] = {
-0.791559, -0.597705,
};
float w;
float h;
static const float2 resolution = float2(w, h);
// blur setting
static const float blurFalloff = 8;
static const float sharpness = 4;
float4 AdjustSaturation(float4 color, float saturation) {
float4 AdjustSaturation(float4 color, float saturation)
{
float grey = dot(color, float3(0.3, 0.59, 0.11));
return lerp(grey, color, saturation);
}
float Brightness(float3 color)
float4 BloomPS(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
return color.r * color.g - 0.75 * color.b;
}
float3 BlurFunction(float2 uv, float brightness, inout float totalWeight)
{
float3 pointColor =(tex2Dlod(s0, float4(uv, 0, 0)).rgb);
float diff = abs(brightness - Brightness(pointColor));
float weight = exp2(-0.25 * blurFalloff - diff * sharpness);
totalWeight += weight;
return pointColor * weight;
}
float4 BlurPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
{
float3 sumColor = (tex2D(s0, uv).rgb);
float totalWeight = 1;
float brightness = Brightness(sumColor);
delta *= (1 / resolution);
float radius = 1;
float2 pointUV = uv + delta * radius;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - delta * radius;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight),1);
// return AdjustSaturation(Color, 0.5);
}
float4 BloomT(float2 texCoord : TEXCOORD0) : COLOR0 {
float4 c = tex2D(s0, texCoord);
float BloomThreshold = 0.2;
return saturate((c - BloomThreshold) / (1 - BloomThreshold));
}
float4 Bloom(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 {
float BaseIntensity = 1.0;
float BaseSaturation = 1;
float BloomIntensity = 1; // 0.4
float BloomSaturation = 0.5;
float BlurPower = 0.01;
float BloomThreshold = 0.5;
float4 original = tex2D(s0, texCoord);
// blur
float4 sum = tex2D(s0, texCoord);
for(int i = 0; i < 12; i++){
sum += tex2D(s0, texCoord + BlurPower * offsets[i]);
}
sum /= 13;
original = AdjustSaturation(original, BaseSaturation) * BaseIntensity;
sum = AdjustSaturation(sum, BloomSaturation) * BloomIntensity;
float sum = (original.r + original.g + original.b) * 0.333;
if (sum >= 0.95) return original;
sum = saturate((sum - BloomThreshold) / (1 - BloomThreshold));
// bloom blur
float4 bloomBlur = tex2D(s0, texCoord);
for(int i = 0; i < 12; i++)
{
bloomBlur += tex2D(s0, texCoord + BlurPower * offsets[i]);
}
bloomBlur *= 0.085;
return sum + original;
// return sum;
float intensity = BloomIntensity - lerp(0.0, 0.2, sum);
bloomBlur = AdjustSaturation(bloomBlur, BloomSaturation) * intensity;
bloomBlur = saturate((bloomBlur - BloomThreshold) / (1 - BloomThreshold));
return bloomBlur + original;
}
technique Blur
static const float CoefBlur = (Sharpen * 0.5);
static const float CoefOrig = (1 + CoefBlur);
// for the sharpen edge
#define SharpenEdge 0.4
static const float sharpenVal0 = (Sharpen * (1.5 + EdgeSharpen));
static const float sharpenVal1 = ((sharpenVal0 - 1) / 8.0);
// pixel "width"
static const float px = (1.0 / w);
static const float py = (1.0 / h);
// for the blur filter
#define mean 1.0
static const float dx = (mean * px);
static const float dy = (mean * py);
float4 SharpenComplexPS(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// pass P2 { PixelShader = compile ps_2_0 BloomT(); }
// pass P3 { PixelShader = compile ps_2_0 Bloom(); }
Pass P0 { PixelShader = compile ps_3_0 BlurPS(float2(1, 0)); }
Pass P1 { PixelShader = compile ps_3_0 BlurPS(float2(0, 1)); }
float4 c0 = tex2D(s0, texCoord); // get original pixel
// edge detection
// Get neighbor points
// [ c1, c2, c3 ]
// [ c4, c0, c5 ]
// [ c6, c7, c8 ]
float4 c1 = tex2D(s0, texCoord + float2(-px, -py));
float4 c2 = tex2D(s0, texCoord + float2( 0, -py));
float4 c3 = tex2D(s0, texCoord + float2( px, -py));
float4 c4 = tex2D(s0, texCoord + float2(-px, 0));
float4 c5 = tex2D(s0, texCoord + float2( px, 0));
float4 c6 = tex2D(s0, texCoord + float2(-px, py));
float4 c7 = tex2D(s0, texCoord + float2( 0, py));
float4 c8 = tex2D(s0, texCoord + float2( px, py));
// using Sobel filter
// horizontal gradient
// [ -1, 0, 1 ]
// [ -2, 0, 2 ]
// [ -1, 0, 1 ]
float delta1 = (c3 + 2 * c5 + c8) - (c1 + 2 * c4 + c6);
// vertical gradient
// [ -1, - 2, -1 ]
// [ 0, 0, 0 ]
// [ 1, 2, 1 ]
float4 c13 = c1 + c3;
float4 c68 = c6 + c8;
float delta2 = (c68 + 2 * c7) - (c13 + 2 * c2);
// computation
if (sqrt(mul(delta1, delta1) + mul(delta2, delta2)) > SharpenEdge) {
// if we have an edge, use sharpen
return c0 * sharpenVal0 - (c13 + c2 + c4 + c5 + c68 + c7) * sharpenVal1;
// Display edges in red...
//return float4( 1.0, 0.0, 0.0, 0.0 );
} else {
// else return corrected image
// compute blurred image (gaussian filter)
c1 = tex2D(s0, texCoord + float2(-dx, -dy));
c2 = tex2D(s0, texCoord + float2( 0, -dy));
c3 = tex2D(s0, texCoord + float2( dx, -dy));
c4 = tex2D(s0, texCoord + float2(-dx, 0));
c5 = tex2D(s0, texCoord + float2( dx, 0));
c6 = tex2D(s0, texCoord + float2(-dx, dy));
c7 = tex2D(s0, texCoord + float2( 0, dy));
c8 = tex2D(s0, texCoord + float2( dx, dy));
// gaussian filter
// [ 1, 2, 1 ]
// [ 2, 4, 2 ]
// [ 1, 2, 1 ]
// to normalize the values, we need to divide by the coeff sum
float4 flou = (c1 + c3 + c6 + c8 + 2 * (c2 + c4 + c5 + c7) + 4 * c0) * 0.0625; // 1 / (1+2+1+2+4+2+1+2+1) = 1 / 16 = 0.0625
// substract blurred image from original image
return (CoefOrig * c0 - CoefBlur * flou);
}
}
technique BlurBloom
{
//pass P0 { PixelShader = compile ps_3_0 BlurDeltaPassPS(wPass); }
//pass P1 { PixelShader = compile ps_3_0 BlurDeltaPassPS(hPass); }
pass P0 { PixelShader = compile ps_3_0 BlurPS(); }
pass P3 { PixelShader = compile ps_2_0 BloomPS(); }
pass P2 { PixelShader = compile ps_2_0 SharpenComplexPS(); }
}
@@ -1,7 +1,5 @@
/*
Example implementation of the algorithm of how the game engine checks if one critter sees another critter.
NOTE: the AllowUnsafeScripting option must be enabled.
*/
#include "..\headers\define.h"
@@ -9,10 +7,8 @@
#include "..\headers\sfall\sfall.h"
#include "..\headers\sfall\define_extra.h"
#define can_see_(source, target) call_offset_r2(0x412BEC, source, target)
#define obj_dist_(target, source) call_offset_r2(0x48BBD4, target, source)
procedure start;
procedure can_see(variable obj1, variable obj2);
procedure start begin
if game_loaded then begin
@@ -21,40 +17,50 @@ procedure start begin
variable
source := get_sfall_arg,
target := get_sfall_arg,
original := get_sfall_arg,
hookType := get_sfall_arg, /* new arg */
engine := get_sfall_arg,
type := get_sfall_arg, /* new arg */
result := 0,
distance;
distance, seeDistance, seeText;
if target then begin
distance := get_critter_stat(source, STAT_pe);
seeDistance := get_critter_stat(source, STAT_pe);
if can_see_(source, target) then begin
distance *= 5;
if (get_flags(target) bwand FLAG_TRANSGLASS) then distance /= 2;
if can_see(source, target) then begin
seeDistance *= 5;
if (get_flags(target) bwand FLAG_TRANSGLASS) then seeDistance /= 2;
end else if combat_is_initialized then begin
distance *= 2;
seeDistance *= 2;
end
if (target == dude_obj) then begin
if sneak_success then begin
distance /= 4;
if has_skill(target, SKILL_SNEAK) > 120 then distance -= 1;
seeDistance /= 4;
if has_skill(target, SKILL_SNEAK) > 120 then seeDistance -= 1;
end else if dude_is_sneaking then begin
distance := distance * 2 / 3;
seeDistance := (seeDistance * 2) / 3; // distance div 1.5
end
end
if obj_dist_(target, source) <= distance then result := 1;
distance := tile_distance_objs(source, target);
if (get_flags(source) bwand FLAG_MULTIHEX) then distance--;
if (get_flags(target) bwand FLAG_MULTIHEX) then distance--;
// example
if (result) then begin
display_msg("hs_withinperception: " + obj_name(source) + " sees " + obj_name(target) + " [original: " + original + " script: " + result + "]");
end else begin
display_msg("hs_withinperception: " + obj_name(source) + " does not see " + obj_name(target) + " [original: " + original + " script: " + result + "]");
end
if (distance <= seeDistance) then result := 1;
seeText = " does not see > ";
if (result) then seeText = " sees > ";
// Example
display_msg("hs_withinperception: " + obj_name(source) + seeText + obj_name(target) + " [engine: " + engine + ", script: " + result + "]");
/* override engine result */
//set_sfall_return(result);
end
//set_sfall_return(result);
end
end
procedure can_see(variable obj1, variable obj2) begin
variable dir = obj_get_rot(obj1) - rotation_to_tile(tile_num(obj1), tile_num(obj2));
if (dir < 0) then dir = -dir;
return (dir <= 1) or (dir == 5);
end
@@ -340,6 +340,9 @@ There are several changes in this version of sslc which may result in problems f
=== Changelog ===
=================
> sfall 4.2.7
- added ability to declare local variables anywhere in the procedure body
> sfall 4.2.3
- fixed compiler giving "assignment operator expected" error when a variable-like macro is not being defined properly
- added new logical operators "AndAlso", "OrElse" for short-circuit evaluation of logical expressions
@@ -2,6 +2,9 @@
#ifndef DEFINE_EXTRA_H
#define DEFINE_EXTRA_H
/* Combat Flags */
#define DAM_PRESERVE_FLAGS 0x80000000 // keep the existing result flags when setting new flags in attack_complex (for sfall)
#define BODY_HIT_HEAD (0)
#define BODY_HIT_LEFT_ARM (1)
#define BODY_HIT_RIGHT_ARM (2)
+14 -6
View File
@@ -262,8 +262,8 @@
#define party_member_list_all party_member_list(1)
// fake perks/traits add mode flags
#define ADD_PERK_MODE_TRAIT (1) // add to the player's traits
#define ADD_PERK_MODE_PERK (2) // add to the player's perks
#define ADD_PERK_MODE_TRAIT (1) // add to the player's traits list
#define ADD_PERK_MODE_PERK (2) // add to the player's perks list
#define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks (after added to the player)
// instantly apply the item to dude_obj (w/o animation)
@@ -273,11 +273,19 @@
set_self(0)
// returns the corrected tile distance between two objects to the distance variable (return value >= 9996 is an error when getting the distance)
#define distance_objs(distance, obj1, obj2) distance := tile_distance_objs(obj1, obj2) - 1; \
if (get_flags(obj1) bwand FLAG_MULTIHEX) distance--; \
if (get_flags(obj2) bwand FLAG_MULTIHEX) distance--
#define distance_objs(distance, obj1, obj2) distance := tile_distance_objs(obj1, obj2) - 1; \
if (get_flags(obj1) bwand FLAG_MULTIHEX) then distance--; \
if (get_flags(obj2) bwand FLAG_MULTIHEX) then distance--
// sfall_funcX macros
/* sfall metarule3 function macros */
// sets the number of days (range 1...127) for the Frank Horrigan encounter, or disable the encounter if days is set to 0
#define set_horrigan_days(day) metarule3(200, day, 0, 0)
// clears the keyboard input buffer, use it in the HOOK_KEYPRESS hook to clear keyboard events before calling functions that are waiting for keyboard input
#define clear_keyboard_buffer metarule3(201, 0, 0, 0)
/* sfall_funcX macros */
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
#define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam)
#define add_iface_tag sfall_func0("add_iface_tag")
+3 -2
View File
@@ -432,8 +432,9 @@ Some utility/math functions are available:
- 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
- sets the outline color of an object (see OUTLINE_* constants in sfall.h)
- can also set a custom color from the game palette by shifting the color index value left by 8 bits: 0xCC00 where CC is the palette index (available since sfall 4.2.7/3.8.27)
- passing 0 will disable the outline
- call "tile_refresh_display" after changing outline of objects to properly redraw the scene
> int sfall_func1("get_flags", object)
+18
View File
@@ -0,0 +1,18 @@
[sfall]
SaveInCombat=目前不能存档。
KarmaGain=你获得了%d点道德。
KarmaLoss=你失去了%d点道德。
HighlightFail1=你没有携带动态感应器。
HighlightFail2=你的动态感应器没电了。
SuperStimExploitMsg=你不能对没受伤的人使用超级治疗针!
BlockedCombat=你现在不能进入战斗。
SaveSfallDataFail=储存存档延展信息时发生错误!检查是否有其他程序占用存档文件/文件夾之后再试一次。
PartyLvlMsg=等级:
PartyACMsg=AC:
PartyAddictMsg=上瘾
NPCPickupFail=%s无法将东西捡起来。
[AppearanceMod]
RaceText=种族
StyleText=风格
DoneBtn=完成
+18
View File
@@ -0,0 +1,18 @@
[sfall]
SaveInCombat=目前不能存檔。
KarmaGain=你獲得了%d點道德。
KarmaLoss=你失去了%d點道德。
HighlightFail1=你沒有攜帶動態感應器。
HighlightFail2=你的動態感應器沒電了。
SuperStimExploitMsg=你不能對沒受傷的角色使用超級治療針!
BlockedCombat=你現在不能進入戰鬥。
SaveSfallDataFail=儲存存檔延伸資訊時發生錯誤!檢查是否有其他程式占用存檔檔案/資料夾之後再試一次。
PartyLvlMsg=等級:
PartyACMsg=AC:
PartyAddictMsg=上癮
NPCPickupFail=%s無法將東西撿起來。
[AppearanceMod]
RaceText=種族
StyleText=風格
DoneBtn=完成
+18
View File
@@ -0,0 +1,18 @@
[sfall]
SaveInCombat=Tu ne peux pas sauvegarder en ce moment.
KarmaGain=Tu gagnes %d Karma.
KarmaLoss=Tu perds %d Karma.
HighlightFail1=Tu n'as pas de détecteur de mouvement.
HighlightFail2=Ton détecteur de mouvement n'a plus de charges.
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=Suiv:
PartyACMsg=TA:
PartyAddictMsg=Dependance
NPCPickupFail=%s ne peut pas ramasser l'objet.
[AppearanceMod]
RaceText=Race
StyleText=Style
DoneBtn=Fait
+18
View File
@@ -0,0 +1,18 @@
[sfall]
SaveInCombat=Momentan kein Speichern möglich.
KarmaGain=Du erhältst %d Karma.
KarmaLoss=Du verlierst %d Karma.
HighlightFail1=Du trägst keinen Bewegungssensor.
HighlightFail2=Dein Bewegungssensor ist entladen.
SuperStimExploitMsg=Du kannst einem Unverletzten kein Super-Stimpak verabreichen!
BlockedCombat=Kampfmodus momentan nicht verfügbar.
SaveSfallDataFail=FEHLER beim Speichern des Spielstandes! Prüfe, ob andere Programme darauf zugreifen und probiere es erneut.
PartyLvlMsg=Lvl:
PartyACMsg=RÜ:
PartyAddictMsg=Abhäng
NPCPickupFail=%s kann das Objekt nicht nehmen.
[AppearanceMod]
RaceText=Geschlecht
StyleText=Stil
DoneBtn=OK
+18
View File
@@ -0,0 +1,18 @@
[sfall]
SaveInCombat=Сохранение в данный момент невозможно.
KarmaGain=Вы получаете %d единиц кармы.
KarmaLoss=Вы теряете %d единиц кармы.
HighlightFail1=Сенсор движения недоступен.
HighlightFail2=Сенсор движения разряжен.
SuperStimExploitMsg=Вы не можете использовать суперстимулятор на здоровом персонаже!
BlockedCombat=Вы не можете сейчас начать бой.
SaveSfallDataFail=ОШИБКА записи расширенной информации! Убедитесь что другие программы не обращаются к файлам/каталогам сохраняемой игры и попробуйте еще раз.
PartyLvlMsg=Ур.:
PartyACMsg=КБ:
PartyAddictMsg=Зависимость
NPCPickupFail=%s не может подобрать предмет.
[AppearanceMod]
RaceText=Раса
StyleText=Стиль
DoneBtn=Закрыть
+4 -3
View File
@@ -10,11 +10,12 @@ namespace sfall
std::multimap<long, long> writeAddress;
static std::vector<long> excludeWarning = {
0x44E949, 0x44E94A, 0x44E937, 0x4F5F40, 0x4CB850, // from movies.cpp
0x44E949, 0x44E94A, 0x44E937, 0x4F5F40, // from movies.cpp
};
static std::vector<long> excludeConflict = {
0x42A0F8, // bugfixes.cpp
0x42A0F8, // bugfixes.cpp
0x461495, // BarBoxes.cpp
};
struct HackPair {
@@ -76,7 +77,7 @@ static std::vector<HackPair> hackAddr = {
{0x484B18, 1}, {0x484B19, 4}, // hookcall
// module: Movies
{0x44E937, 1}, {0x44E938, 4}, {0x44E949, 1}, {0x44E94A, 4}, // hookcalls
{0x4F5F40, 1}, {0x4CB850, 1},
{0x4F5F40, 1},
// module: Objects
{0x4A364A, 5}, {0x4831D9, 1}, {0x4831DA, 1},
{0x4841D6, 1}, {0x4841D7, 4}, // hookcall
+30 -3
View File
@@ -68,7 +68,7 @@ bool CritterCopyProto(long pid, long* &proto_dst) {
proto_dst = nullptr;
return false;
}
proto_dst = reinterpret_cast<long*>(new int32_t[104]);
proto_dst = reinterpret_cast<long*>(new long[104]);
memcpy(proto_dst, protoPtr, 416);
return true;
}
@@ -194,7 +194,7 @@ long GetScriptLocalVars(long sid) {
// Returns window ID by x/y coordinate (hidden windows are ignored)
long __fastcall GetTopWindowID(long xPos, long yPos) {
fo::Window* win = nullptr;
long countWin = *(DWORD*)FO_VAR_num_windows - 1;
long countWin = fo::var::num_windows - 1;
for (int n = countWin; n >= 0; n--) {
win = fo::var::window[n];
if (xPos >= win->wRect.left && xPos <= win->wRect.right && yPos >= win->wRect.top && yPos <= win->wRect.bottom) {
@@ -393,6 +393,24 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
}
}
// Fills the specified non-scripted interface window with black color
void ClearWindow(DWORD winID, bool refresh) {
__asm {
xor ebx, ebx;
push ebx;
mov eax, winID;
call fo::funcoffs::win_height_;
push eax;
mov eax, winID;
call fo::funcoffs::win_width_;
mov ecx, eax;
mov edx, ebx;
mov eax, winID;
call fo::funcoffs::win_fill_;
}
if (refresh) fo::func::win_draw(winID);
}
//---------------------------------------------------------
// print text to surface
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) {
@@ -505,7 +523,16 @@ void RedrawObject(GameObject* obj) {
func::tile_refresh_rect(&rect, obj->elevation);
}
/////////////////////////////////////////////////////////////////UNLISTED FRM FUNCTIONS////////////////////////////////////////////////////////////////////////
// Redraws all interface windows
void RefreshGNW() {
*(DWORD*)FO_VAR_doing_refresh_all = 1;
for (size_t i = 0; i < fo::var::num_windows; i++) {
func::GNW_win_refresh(fo::var::window[i], &fo::var::scr_size, 0);
}
*(DWORD*)FO_VAR_doing_refresh_all = 0;
}
/////////////////////////////////////////////////////////////////UNLISTED FRM FUNCTIONS//////////////////////////////////////////////////////////////
static bool LoadFrmHeader(UnlistedFrm *frmHeader, fo::DbFile* frmStream) {
if (fo::func::db_freadInt(frmStream, &frmHeader->version) == -1)
+7
View File
@@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
@@ -103,6 +104,9 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf);
// Fills the specified non-scripted interface window with black color
void ClearWindow(DWORD winID, bool refresh = true);
// Print text to surface
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
void PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
@@ -130,6 +134,9 @@ DWORD GetMaxCharWidth();
// Redraw the given object on screen (does not always redraws the whole object)
void RedrawObject(GameObject* obj);
// Redraws all interface windows
void RefreshGNW();
UnlistedFrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef);
}
+34 -33
View File
@@ -117,50 +117,51 @@ enum CritterFlags : long
NoKnockBack = 0x4000, // Can't be knocked back
};
enum DamageFlag : long
enum DamageFlag : unsigned long
{
DAM_KNOCKED_OUT = 0x1,
DAM_KNOCKED_DOWN = 0x2,
DAM_CRIP_LEG_LEFT = 0x4,
DAM_CRIP_LEG_RIGHT = 0x8,
DAM_CRIP_ARM_LEFT = 0x10,
DAM_CRIP_ARM_RIGHT = 0x20,
DAM_BLIND = 0x40,
DAM_DEAD = 0x80,
DAM_HIT = 0x100,
DAM_CRITICAL = 0x200,
DAM_ON_FIRE = 0x400,
DAM_BYPASS = 0x800,
DAM_EXPLODE = 0x1000,
DAM_DESTROY = 0x2000,
DAM_DROP = 0x4000,
DAM_LOSE_TURN = 0x8000,
DAM_HIT_SELF = 0x10000,
DAM_LOSE_AMMO = 0x20000,
DAM_DUD = 0x40000,
DAM_HURT_SELF = 0x80000,
DAM_RANDOM_HIT = 0x100000,
DAM_CRIP_RANDOM = 0x200000,
DAM_BACKWASH = 0x400000,
DAM_KNOCKED_OUT = 0x1,
DAM_KNOCKED_DOWN = 0x2,
DAM_CRIP_LEG_LEFT = 0x4,
DAM_CRIP_LEG_RIGHT = 0x8,
DAM_CRIP_ARM_LEFT = 0x10,
DAM_CRIP_ARM_RIGHT = 0x20,
DAM_BLIND = 0x40,
DAM_DEAD = 0x80,
DAM_HIT = 0x100,
DAM_CRITICAL = 0x200,
DAM_ON_FIRE = 0x400,
DAM_BYPASS = 0x800,
DAM_EXPLODE = 0x1000,
DAM_DESTROY = 0x2000,
DAM_DROP = 0x4000,
DAM_LOSE_TURN = 0x8000,
DAM_HIT_SELF = 0x10000,
DAM_LOSE_AMMO = 0x20000,
DAM_DUD = 0x40000,
DAM_HURT_SELF = 0x80000,
DAM_RANDOM_HIT = 0x100000,
DAM_CRIP_RANDOM = 0x200000,
DAM_BACKWASH = 0x400000,
DAM_PERFORM_REVERSE = 0x800000,
DAM_PRESERVE_FLAGS = 0x80000000 // sfall, used for attack_complex
};
enum DamageType
{
DMG_normal = 0,
DMG_laser = 1,
DMG_fire = 2,
DMG_plasma = 3,
DMG_electrical = 4,
DMG_emp = 5,
DMG_explosion = 6,
DMG_normal = 0,
DMG_laser = 1,
DMG_fire = 2,
DMG_plasma = 3,
DMG_electrical = 4,
DMG_emp = 5,
DMG_explosion = 6,
DMG_BYPASS_ARMOR = 256,
DMG_NOANIMATE = 512,
DMG_NOANIMATE = 512,
};
enum Gender
{
GENDER_MALE = 0,
GENDER_MALE = 0,
GENDER_FEMALE = 1,
};
+1 -1
View File
@@ -26,7 +26,7 @@ namespace fo
namespace func
{
// Prints debug message to debug.log file for develop build
// Prints debug message to game debug.log file for develop build
#ifndef NDEBUG
void __declspec(naked) dev_printf(const char* fmt, ...) {
__asm jmp fo::funcoffs::debug_printf_;
+1 -1
View File
@@ -29,8 +29,8 @@ namespace fo
namespace func
{
// Prints debug message to debug.log file for develop build
#ifndef NDEBUG
// Prints debug message to game debug.log file for develop build
void dev_printf(const char* fmt, ...);
#else
void dev_printf(...);

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