5,391
edits
(sigh) |
(yay) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 37: | Line 37: | ||
Thanks for checking the runtime '''ai_name''' and how it doesn't have any extra characters after all. I am not yet convinced that the comparison is by pointer and not by content, but if it is so, then it would mean that string arguments passed from runtime events (TRGV etc) are completely unusable - because they have their own unique pointer, which will never match anything you compare it with (unless you do something like '''BOB_string = ai_name''', but then the two strings are in fact one and the same, and there's nothing left to compare). --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 11:05, 18 May 2020 (CEST) | Thanks for checking the runtime '''ai_name''' and how it doesn't have any extra characters after all. I am not yet convinced that the comparison is by pointer and not by content, but if it is so, then it would mean that string arguments passed from runtime events (TRGV etc) are completely unusable - because they have their own unique pointer, which will never match anything you compare it with (unless you do something like '''BOB_string = ai_name''', but then the two strings are in fact one and the same, and there's nothing left to compare). --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 11:05, 18 May 2020 (CEST) | ||
I have confirmed in my own way that the strings coming from runtime events are (apparently) compared by pointer rather than by content. Suppose you define two global string vars, '''dead_name''' and '''dead_name_too'''. Then you kill '''A_t48''' twice (after force-spawning him), with '''t48_dead(string ai_name)''' performing the assignment '''dead_name = ai_name'''. Between the two deaths, do '''dead_name_too = dead_name''' from the console (this is now a redirect to the same string data, and '''dead_name_too eq dead_name''' evaluates to '''true'''). After the second A_t48 death, try '''dead_name_too eq dead_name''' again, and see that it evaluates to '''false''' now (there used to be one string, and now it's two identical strings at different addresses). --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) | |||
It should be noted, however, that "ordinary" string literals (the ones that are included in BSL scripts and allocated at level start) seem to be always compared by content even if they're changed to completely new literals at runtime (as long as it's from the console and not from OBJC events). If you have two global string vars '''testVar''' and '''testVar2''', you can set them both to "bla" from the console, and '''testVar eq testVar2''' will evaluate as '''true''' - so apparently the comparison becomes lazy (by pointer) if at least one of the strings (pointers) is in the dynamic range used by runtime events, but for new strings from the console (also dynamically allocated) it still uses the non-lazy comparison. --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) | |||
I sort of found a workaround, where I copy the value of '''ai_name''' to '''testVar''' not directly, but via Daodan's '''sprintf''' (basically you do '''testVar = sprintf("%s",ai_name)''' instead of '''testVar = ai_name'''). This fills '''testVar''' with some garbage (in my test it was "hӌ"), but it's some consistent garbage that is somehow related to '''ai_name''' - so you can use this at spawn time to initialize the "reference name" of a character, and later check against it with names that you receive from death functions, trigger volumes, etc. I didn't check this thoroughly, but I will make an illustration (probably in TCTF HQ, where many Vanilla CHARs have spawn functions). Also, I have no idea why '''sprintf''' garbles the literal like that when it comes from runtime, so that's another thing that will need to be checked. --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:56, 18 May 2020 (CEST) | |||
OK, good news and bad news. '''Bad:''' string management is fundamentally messy, including '''sprintf'''. Like, I was expecting '''sprintf'''-created strings to stay protected, but they're easily overwritten by other data, depending on the context - it's like the "string" is just a raw char* and there is nothing to keep track of the allocated memory at all. '''Good:''' the following works: | |||
func void t48_dead(string ai_name) | |||
{ | |||
var int index = d_getindex(ai_name); | |||
var int index0 = d_getindex(A_t48); | |||
if(index eq index0) | |||
dmsg("A_t48 detected!") | |||
else | |||
dmsg("No index match!") | |||
} | |||
or this, in TCTF HQ: | |||
func void striker_spawn(string ai_name) | |||
{ | |||
var int index = d_getindex(ai_name); | |||
var int index1 = d_getindex(garage_striker_01); | |||
var int index2 = d_getindex(garage_striker_02); | |||
if(index eq index1) | |||
dmsg("Striker_01 has been spawned!") | |||
if(index eq index2) | |||
dmsg("Striker_02 has been spawned!") | |||
} | |||
func void striker_die(string ai_name) | |||
{ | |||
var int index = d_getindex(ai_name); | |||
var int index1 = d_getindex(garage_striker_01); | |||
var int index2 = d_getindex(garage_striker_02); | |||
if(index eq index1) | |||
dmsg("Striker_01 has died!") | |||
if(index eq index2) | |||
dmsg("Striker_02 has died!") | |||
} | |||
func void spawnStriker1(void) | |||
{ | |||
chr_wait_animtype 0 punch | |||
ai2_spawn garage_striker_01 force | |||
sleep 60 | |||
fork spawnStriker1 | |||
} | |||
func void spawnStriker2(void) | |||
{ | |||
chr_wait_animtype 0 kick | |||
ai2_spawn garage_striker_02 force | |||
sleep 60 | |||
fork spawnStriker2 | |||
} | |||
func void main(void) | |||
{ | |||
fork spawnStriker1 | |||
fork spawnStriker2 | |||
} | |||
The same thing works just fine for a trigger volume, e.g., at the Airport: | |||
func void fire_damage(string ai_name) | |||
{ | |||
var int index = d_getindex(ai_name); | |||
var int index0 = d_getindex(char_0); | |||
var int index1 = d_getindex(LoadingBay_Thug_1); | |||
var int index2 = d_getindex(LoadingBay_Thug_2); | |||
if(index eq index0) | |||
dmsg "Konoko is burning!" | |||
if(index eq index1) | |||
dmsg "Thug 1 is burning!" | |||
if(index eq index2) | |||
dmsg "Thug 2 is burning!" | |||
} | |||
func void main(void) | |||
{ | |||
ai2_spawn LoadingBay_Thug_1 | |||
ai2_spawn LoadingBay_Thug_2 | |||
chr_location 0 134 -105 1029 | |||
} | |||
OK, then, problem solved, moving on. --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 12:39, 19 May 2020 (CEST) |