View Issue Details

IDProjectCategoryView StatusLast Update
0002870FSSCPscriptingpublic2013-05-31 21:36
ReporterAxem Assigned ToThe_E  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.7.0 RC1 
Summary0002870: Some hook variables are not always available, causing game halting errors
DescriptionIn a harmless looking scripting hook such as

$On Death:
[
    hv.Killer = theKiller
]

will work most of the time, unless a ship self destructs.

Then the game halts and brings up an error window to the tune of "Could not find index 'Killer' in type 'HookVariables'". It can be bypassed by hitting n, but it will always appear to anything that self destructs.

According to shiphit.cpp:1552, since othership is NULL, the Killer hook variable is never made. This can throw up an error for even basic checks such as "if hv.Killer then", "if hv.Killer:isValid()" or even "hv.Killer ~= nil" since hv.Killer was never made.

Perhaps an else condition could be tacked onto conditional hook variables such as hv.Killer so it could return nil if nothing actually killed it?

In the mean time, doing something like

for i=1,#hv.Globals do
   if tostring(hv.Globals[i]) == "Killer" then
       [[lua code here]]
   end
end

will indirectly check for the existence of the Killer variable, but that's a really lame work around.
TagsNo tags attached.

Activities

Axem

2013-05-11 20:32

reporter   ~0015051

Just playing around I tried just setting the killer hook variable to 0, which allows the checks with :isValid(). (Which is good enough for me)

I don't know if this a proper method or not though! I looked through for other instances where a hook variable might not be created and could find nothing else.

Axem

2013-05-11 20:32

reporter  

shiphit-hv-killer.patch (599 bytes)   
Index: shiphit.cpp
===================================================================
--- shiphit.cpp	(revision 9649)
+++ shiphit.cpp	(working copy)
@@ -1549,7 +1549,10 @@
 	Assert(ship_obj);	// Goober5000 - but not other_obj, not only for sexp but also for self-destruct
 
 	Script_system.SetHookObject("Self", ship_obj);
-	if(other_obj != NULL) Script_system.SetHookObject("Killer", other_obj);
+	if(other_obj != NULL)
+		Script_system.SetHookObject("Killer", other_obj);
+	else
+		Script_system.SetHookObject("Killer", 0);
 
 	if(Script_system.IsConditionOverride(CHA_DEATH, ship_obj))
 	{
shiphit-hv-killer.patch (599 bytes)   

Echelon9

2013-05-11 23:51

developer   ~0015052

Yes, I think the correct approach is to better utilise IsValid() - it's what it is for.

Lua scripters should keep in mind that it is not guaranteed that every object will exist at all times and utilise the validity checks like IsValid() where required.

The coding fix is to ensure that IsValid() does not throw a hard error, but gracefully reports it through to Lua for it to be handled.

The_E

2013-05-31 21:36

administrator   ~0015107

Patch committed to trunk in r9687

Issue History

Date Modified Username Field Change
2013-05-11 19:59 Axem New Issue
2013-05-11 20:32 Axem Note Added: 0015051
2013-05-11 20:32 Axem File Added: shiphit-hv-killer.patch
2013-05-11 23:51 Echelon9 Note Added: 0015052
2013-05-11 23:51 Echelon9 Status new => code review
2013-05-31 21:36 The_E Note Added: 0015107
2013-05-31 21:36 The_E Status code review => resolved
2013-05-31 21:36 The_E Resolution open => fixed
2013-05-31 21:36 The_E Assigned To => The_E