mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Changed string_pos to return -1 on arg error
Added a check to PartyControl::OrderAttackPatch(). Updated function documents.
This commit is contained in:
@@ -1098,7 +1098,7 @@
|
||||
detail: string substr(string text, int start, int length)
|
||||
doc: |
|
||||
Cuts a substring from a string starting at "start" up to "length" characters. The first character position is 0 (zero).
|
||||
- If start is negative - it indicates starting position from the end of the string (for example `substr("test", -2, 2)` will return last 2 charactes: "st").
|
||||
- If start is negative - it indicates a position starting from the end of the string (for example `substr("test", -2, 2)` will return last 2 charactes: "st").
|
||||
- If length is negative - it means so many characters will be omitted from the end of string (example: `substr("test", 0, -2)` will return string without last 2 characters: "te").
|
||||
- If length is zero - it will return a string from the starting position to the end of the string. **New behavior** for sfall 4.2.2/3.8.22
|
||||
opcode: 0x824e
|
||||
@@ -1117,14 +1117,14 @@
|
||||
- __NOTE:__ this function is intended for use only in `HOOK_DESCRIPTIONOBJ`. Starting from sfall 4.4/3.8.40, you can return normal strings directly in the hook without calling the function
|
||||
macro: sfall.h
|
||||
- name: string_pos
|
||||
detail: string string_pos(string haystack, string needle)
|
||||
doc: Returns position of a first occurance of a needle string in a haystack string, or -1 if not found.
|
||||
detail: int string_pos(string haystack, string needle)
|
||||
doc: Returns the position of the first occurrence of a `needle` string in a `haystack` string, or -1 if not found. The first character position is 0 (zero).
|
||||
macro: sfall.h
|
||||
- name: string_pos_from
|
||||
detail: string string_pos_from(string haystack, string needle, int pos)
|
||||
detail: int string_pos_from(string haystack, string needle, int pos)
|
||||
doc: |
|
||||
Returns position of a first occurance of a needle string in a haystack string (starting from a given 0-based position), or -1 if not found.
|
||||
- If pos is negative - it indicates starting position from the end of the string, similar to substr().
|
||||
Works the same as `string_pos`, except you can specify the position to start the search.
|
||||
- If `pos` is negative - it indicates a position starting from the end of the string, similar to `substr()`.
|
||||
macro: sfall.h
|
||||
- name: string_format
|
||||
detail: string string_format(string format, any val1, any val2, ...)
|
||||
|
||||
@@ -327,11 +327,11 @@ FUNCTION REFERENCE
|
||||
- You can use this to search for a substring in a string like this: `strlen(get_array(string_split(haystack, needle), 0))`
|
||||
|
||||
-----
|
||||
##### `string substr(string text, start, length)`
|
||||
##### `string substr(string text, int start, int length)`
|
||||
- Cuts a substring from a string starting at `start` up to `length` characters. The first character position is 0 (zero).
|
||||
- If `start` is negative - it indicates starting position from the end of the string (for example, `substr("test", -2, 2)` will return last 2 charactes: "st").
|
||||
- If `start` is negative - it indicates a position starting from the end of the string (for example, `substr("test", -2, 2)` will return last 2 charactes: "st").
|
||||
- If `length` is negative - it means so many characters will be omitted from the end of string (example: `substr("test", 0, -2)` will return string without last 2 characters: "te").
|
||||
- If `length` is zero - it will return a string from the starting position to the end of the string (new behavior for sfall 4.2.2/3.8.22).
|
||||
- If `length` is zero - it will return a string from the starting position to the end of the string (**new behavior** since sfall 4.2.2/3.8.22).
|
||||
|
||||
-----
|
||||
##### `int strlen(string text)`
|
||||
@@ -1107,6 +1107,7 @@ sfall_funcX metarule functions
|
||||
- Allows changing "bonus move" points (yellow lights on the interface bar) that can only be used for movement, not attacking
|
||||
- Can be called from `HOOK_COMBATTURN` at the start of the turn (will not work on `dude_obj`)
|
||||
- Can be called from `HOOK_STDPROCEDURE` with `combat_proc` event (will work on both NPCs and `dude_obj`)
|
||||
|
||||
----
|
||||
#### get_ini_config
|
||||
`array sfall_func2("get_ini_config", string file, bool searchDB)`
|
||||
@@ -1116,6 +1117,16 @@ sfall_funcX metarule functions
|
||||
True - searches the file in database (DAT) files. If not found, then it will try the regular file system
|
||||
- Subsequent calls for the same file will return the same array, unless it was disposed using `free_array`
|
||||
|
||||
----
|
||||
#### string_pos
|
||||
`int sfall_func2("string_pos", string haystack, string needle)`
|
||||
`int sfall_func3("string_pos", string haystack, string needle, int pos)`
|
||||
|
||||
- Returns the position of the first occurrence of a `needle` string in a `haystack` string, or -1 if not found. The first character position is 0 (zero)
|
||||
|
||||
**Optional argument:**
|
||||
- `pos`: the position at which to start the search. If negative, it indicates a position starting from the end of the string
|
||||
|
||||
|
||||
****
|
||||
_See other documentation files (arrays.md, hookscripts.md) for related functions reference._
|
||||
|
||||
@@ -158,14 +158,14 @@ static void SetStatValue(long* proto, long offset, long amount) {
|
||||
static void ModifyAllStats(const itProtoMem &mem) {
|
||||
if (!mem->second.proto && !fo::util::CritterCopyProto(mem->second.pid, mem->second.proto)) return; // proto error
|
||||
|
||||
for (auto itBonus = s_bonusStatProto.begin(); itBonus != s_bonusStatProto.end(); itBonus++) {
|
||||
for (auto itBonus = s_bonusStatProto.begin(); itBonus != s_bonusStatProto.end(); ++itBonus) {
|
||||
if (itBonus->objID == mem->first && itBonus->objPID == mem->second.pid) {
|
||||
itBonus->s_proto = mem->second.proto;
|
||||
SetBonusStatValue(itBonus->s_proto, itBonus->stat, itBonus->amount);
|
||||
mem->second.sharedCount++;
|
||||
}
|
||||
}
|
||||
for (auto itBase = s_baseStatProto.begin(); itBase != s_baseStatProto.end(); itBase++) {
|
||||
for (auto itBase = s_baseStatProto.begin(); itBase != s_baseStatProto.end(); ++itBase) {
|
||||
if (itBase->objID == mem->first && itBase->objPID == mem->second.pid) {
|
||||
itBase->s_proto = mem->second.proto;
|
||||
SetBaseStatValue(itBase->s_proto, itBase->stat, itBase->amount);
|
||||
@@ -189,7 +189,7 @@ static void AddStat(long stat, fo::GameObject* critter, long amount, long* defau
|
||||
fo::func::dev_printf("[SFALL] Set bonus:%d stat:%d, to NPC pid: %d, saved:%d\n", (offset == OffsetStat::bonus), stat, (critter->protoId & 0xFFFF), isSaved);
|
||||
|
||||
offset += stat;
|
||||
for (auto itStat = vec.begin(); itStat != vec.end(); itStat++) {
|
||||
for (auto itStat = vec.begin(); itStat != vec.end(); ++itStat) {
|
||||
if (itStat->objID == critter->id && itStat->objPID == critter->protoId && itStat->stat == stat) {
|
||||
fo::func::dev_printf("[SFALL] Modify stat value old: %d to new: %d, ID: %d\n", itStat->s_proto[offset], amount, itStat->objID);
|
||||
if (amount == itStat->defVal) { // set value and value in regular prototype are matched
|
||||
@@ -222,7 +222,7 @@ static void __fastcall SetStatToProto(long stat, fo::GameObject* critter, long a
|
||||
}
|
||||
|
||||
static void UpdateDefValue(std::vector<StatModify> &vec, long stat, long pid, long amount) {
|
||||
for (auto itStat = vec.begin(); itStat != vec.end(); itStat++) {
|
||||
for (auto itStat = vec.begin(); itStat != vec.end(); ++itStat) {
|
||||
if (itStat->objPID == pid && itStat->stat == stat) {
|
||||
fo::func::dev_printf("[SFALL] Replace stat default value: %d to: %d, NPC ID: %d\n", itStat->defVal, amount, itStat->objID);
|
||||
itStat->defVal = amount;
|
||||
@@ -387,10 +387,10 @@ static void ClearAllStats() {
|
||||
}
|
||||
|
||||
static void FlushAllProtos() {
|
||||
for (auto itBonus = s_bonusStatProto.begin(); itBonus != s_bonusStatProto.end(); itBonus++) {
|
||||
for (auto itBonus = s_bonusStatProto.begin(); itBonus != s_bonusStatProto.end(); ++itBonus) {
|
||||
itBonus->s_proto = nullptr;
|
||||
}
|
||||
for (auto itBase = s_baseStatProto.begin(); itBase != s_baseStatProto.end(); itBase++) {
|
||||
for (auto itBase = s_baseStatProto.begin(); itBase != s_baseStatProto.end(); ++itBase) {
|
||||
itBase->s_proto = nullptr;
|
||||
}
|
||||
for (auto& mem : protoMem) {
|
||||
|
||||
@@ -822,6 +822,9 @@ static void __declspec(naked) combat_ai_hook_target() {
|
||||
}
|
||||
|
||||
void PartyControl::OrderAttackPatch() {
|
||||
static bool orderAttackPatch = false;
|
||||
if (orderAttackPatch) return;
|
||||
|
||||
MakeCall(0x44C4A7, gmouse_handle_event_hack, 2);
|
||||
HookCall(0x44C75F, gmouse_handle_event_hook);
|
||||
HookCall(0x44C69A, gmouse_handle_event_hook_restore);
|
||||
@@ -831,6 +834,7 @@ void PartyControl::OrderAttackPatch() {
|
||||
LoadGameHook::OnCombatEnd() += []() {
|
||||
partyOrderAttackTarget.clear();
|
||||
};
|
||||
orderAttackPatch = true;
|
||||
}
|
||||
|
||||
static void NpcAutoLevelPatch() {
|
||||
|
||||
@@ -160,7 +160,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"show_window", mf_show_window, 0, 1, -1, {ARG_STRING}},
|
||||
{"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}},
|
||||
{"string_compare", mf_string_compare, 2, 3, 0, {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{"string_pos", mf_string_pos, 2, 3, 0, {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{"string_pos", mf_string_pos, 2, 3, -1, {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{"string_format", mf_string_format, 2, 8, 0, {ARG_STRING, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY}},
|
||||
{"string_to_case", mf_string_to_case, 2, 2, -1, {ARG_STRING, ARG_INT}},
|
||||
{"tile_by_position", mf_tile_by_position, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
|
||||
@@ -200,20 +200,16 @@ void mf_string_compare(OpcodeContext& ctx) {
|
||||
|
||||
void mf_string_pos(OpcodeContext& ctx) {
|
||||
const char* const haystack = ctx.arg(0).strValue();
|
||||
int pos;
|
||||
int pos = 0;
|
||||
if (ctx.numArgs() > 2) {
|
||||
int len = strlen(haystack);
|
||||
pos = ctx.arg(2).intValue();
|
||||
if (pos >= len) {
|
||||
ctx.setReturn(-1);
|
||||
return;
|
||||
} else if (pos < 0) {
|
||||
pos += len;
|
||||
}
|
||||
else if (pos < 0) {
|
||||
pos = len + pos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pos = 0;
|
||||
}
|
||||
const char* needle = strstr(haystack + pos, ctx.arg(1).strValue());
|
||||
ctx.setReturn(
|
||||
|
||||
Reference in New Issue
Block a user