Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
efficient.
Credit to @Hello for figuring this out :)
|
|
|
|
055-1 _nodes.txt will call `destroy;` from within OnInit, that is during an
iteration of the global `ev_db`. Previously, concurrent modification
invalidated this iteration, resulting in a crash.
This still nullifes `oid`, dequeues all timers, and effectively calls
`builtin_end`.
`npc_data::deletion_pending` is extended to include a third state.
In addition to no deletion happening, and indicating when `npc_free` is
currently on the stack, it now also tracks whether the NPC is about to be
deleted by a timer.
This means that an NPC which is about to be deleted is still blocked from
triggering new events, much like an NPC actively being deleted would.
Starting or continuing an NPC dialog with an NPC that does not, or is about to
no longer exist, is now also blocked.
|
|
This is some rather impressive type safety, albeit safety that has evidently
desensitized people to warnings for rather serious problems.
|
|
PR !270 is an ongoing investigation into outstanding compiler warnings.
One such warning is `warning: format '%s' expects a matching 'char*' argument`
from `script_nullpo_end(nd, STRPRINTF("no such npc: '%s'"_fmt, name));` in
`src/map/script-fun.cpp`. No such warning is emitted from a similar line in
`src/map/atcommand.cpp`: `AString output = STRPRINTF("Jump to %s"_fmt, npc);`.
`script_nullpo_end` is a macro, rather than a function. `error` is passed in
verbatim by the preprocessor. The macro definition of `script_nullpo_end`
includes lines such as the following:
```cpp
PRINTF("script:%s: " #error " @ %s\n"_fmt, BUILTIN_NAME(), nullpo_nd->name);
```
`#<variable>` instructs the preprocessor to transform `<variable>` into a
literal string. In this case, the string literal:
```cpp
"STRPRINTF(\"no such npc: '%s'\"_fmt, name)"
```
So the entire line partly resolves to something like:
```cpp
printf("script:%s: STRPRINTF(\"no such npc: '%s'\"_fmt, name) @ %s\n"_fmt, BUILTIN_NAME(), nullpo_nd->name);
```
Once the compiler sees this, it throws out the warning seen here, because
printf is seeing three placeholders in the formatter, but is only given two
value arguments.
Checking with `gcc -E`, the full expansion is as follows:
```cpp
if (nullpo_chk("script-fun.cpp", 4885, __PRETTY_FUNCTION__, nd)) { if (st->oid) { dumb_ptr<npc_data> nullpo_nd = map_id_is_npc(st->oid); if (nullpo_nd && nullpo_nd->name) { ({ struct format_impl { constexpr static FormatString print_format() __asm__("_print_format") { return "script:%s: " "STRPRINTF(\"no such npc: '%s'\"_fmt, npc)" " @ %s\n"_fmt; } }; cxxstdio::PrintFormatter<format_impl>::print((
# 4885 "script-fun.cpp" 3 4
stdout
# 4885 "script-fun.cpp"
), (builtin_functions[st->stack->stack_datav[st->start].get_if<ScriptDataFuncRef>()->numi].name), nullpo_nd->name); }); } else if (nullpo_nd) { ({ struct format_impl { constexpr static FormatString print_format() __asm__("_print_format") { return "script:%s: " "STRPRINTF(\"no such npc: '%s'\"_fmt, npc)" " (unnamed npc)\n"_fmt; } }; cxxstdio::PrintFormatter<format_impl>::print((
# 4885 "script-fun.cpp" 3 4
stdout
# 4885 "script-fun.cpp"
), (builtin_functions[st->stack->stack_datav[st->start].get_if<ScriptDataFuncRef>()->numi].name)); }); } else { ({ struct format_impl { constexpr static FormatString print_format() __asm__("_print_format") { return "script:%s: " "STRPRINTF(\"no such npc: '%s'\"_fmt, npc)" " (no npc)\n"_fmt; } }; cxxstdio::PrintFormatter<format_impl>::print((
# 4885 "script-fun.cpp" 3 4
stdout
# 4885 "script-fun.cpp"
), (builtin_functions[st->stack->stack_datav[st->start].get_if<ScriptDataFuncRef>()->numi].name)); }); } } else { ({ struct format_impl { constexpr static FormatString print_format() __asm__("_print_format") { return "script:%s: " "STRPRINTF(\"no such npc: '%s'\"_fmt, npc)" " (no npc)\n"_fmt; } }; cxxstdio::PrintFormatter<format_impl>::print((
# 4885 "script-fun.cpp" 3 4
stdout
# 4885 "script-fun.cpp"
), (builtin_functions[st->stack->stack_datav[st->start].get_if<ScriptDataFuncRef>()->numi].name)); }); } st->state = ScriptEndState::END; return; };
```
Note the string literal: `"STRPRINTF(\"no such npc: '%s'\"_fmt, npc)"`.
`script_nullpo_end` currently can't take as its argument for `error` any
expression which, when stringified, contains something which `printf` will
interpret as its formatter expecting another argument.
This appears to have been broken since it was first introduced in
https://git.themanaworld.org/legacy/tmwa/-/commit/594eafd4f231a897cbefd
since the first revision implicitly had these requirements, and also
introduced usage which didn't meet them.
This rewrites each PRINTF line in `script_nullpo_end` from the template
```cpp
PRINTF("script:%s: " #error " @ %s\n"_fmt, BUILTIN_NAME(), nullpo_nd->name);
```
to something like
```cpp
PRINTF("script:%s: %s @ %s\n"_fmt, BUILTIN_NAME(), error, nullpo_nd->name);
```
This means that instead of an expression being stringified, error is
interpreted as an expression that resolves (or decays) to a string.
This seems consistent with all current usage of `script_nullpo_end`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* includes @mobinfo ingame command aswell as mobinfo functions for scripts
* enhanced summon script command to take a name to support spawn names
* moved @summon to where other mob related commands are
* added enchanter and koyntety cooldown symbols
* some translations
* some constants added for drops and mobs
|
|
|
|
|
|
|
|
tmwa-admin. Fixed communication from char server to login server. Added translations and comments. Minor QoL.
|
|
|
|
|
|
|
|
battle.cpp is very messy and full of bugs
|
|
|
|
|
|
issues
|
|
When an NPC called destroy; from an attached script, npc_id, and
associated state, was not properly cleared. This meant that the
server considered the PC to still be in conversation, preventing
many actions including walking, but with an invalid NPC.
This clears state for the specific case of the a PC attached to
the script instance that called destroy. It is still not safe to
call destroy; if other players may be attached to it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Implement SMSG_MAP_SET_TILES_TYPE
|
|
|
|
|
|
|
|
|
|
|
|
simplify `aggravate` builtin
|
|
override modifications
|
|
|
|
|
|
|
|
|
|
|