Possible flaw in mission types?

Freeform discussion about anything related to modding Transcendence.
Post Reply
User avatar
Xephyr
Militia Captain
Militia Captain
Posts: 857
Joined: Fri Dec 14, 2007 1:52 am
Location: Orion Arm, Milky Way
Contact:

Consider the case where a mission type looks for an active station in the system in its <OnCreate> element. The mission is accepted by the player, but the player declines. If the player docks again, they'll be greeting with the briefing text and the option to accept/decline the mission until the expireTime runs out.

Now, if the active station in the system is destroyed by the player, and they return to the mission owner object, they'll again be greeted with the briefing text and accept/decline options. If they accept the mission, it will be broken because the active station is dead. Sort of like killing the BM station in Rigel before the "Rescue Katami" mission (although its not a mission type) the mission doesn't work as intended

I think we need a way to evaluate if a mission is still possible when we enter the briefing screen. Currently there's no event that runs at this screen 9to my knowledge), and the other events aren't practical to run here.
Project Renegade (Beta) : "The Poor Man's Corporate Command!"
Real programmers count from 0. And sometimes I do, too.
shanejfilomena
Fleet Officer
Fleet Officer
Posts: 1533
Joined: Tue Mar 22, 2011 8:43 pm
Location: Alaska
Contact:

Edit : I misread the post....stepping out of the Airlock now.
Last edited by shanejfilomena on Fri Mar 10, 2017 7:28 pm, edited 1 time in total.
Flying Irresponsibly In Eridani......

I don't like to kill pirates in cold blood ..I do it.. but I don't like it..
giantcabbage
Militia Lieutenant
Militia Lieutenant
Posts: 104
Joined: Thu Apr 07, 2011 9:05 pm

If you are searching for targets etc. in <OnCreate> then you should also register for their events (msnRegisterForEvents gSource targetObj). If any mission critical objects are destroyed just call msnSuccess / msnFailure and the engine should destroy the mission.
User avatar
Xephyr
Militia Captain
Militia Captain
Posts: 857
Joined: Fri Dec 14, 2007 1:52 am
Location: Orion Arm, Milky Way
Contact:

giantcabbage wrote:
Fri Mar 10, 2017 7:01 pm
If you are searching for targets etc. in <OnCreate> then you should also register for their events (msnRegisterForEvents gSource targetObj). If any mission critical objects are destroyed just call msnSuccess / msnFailure and the engine should destroy the mission.
From my understanding, msnRegisterForEvents isn't functional anymore (at least, from what I've tried). Take a look at times its used in the code, like in Benedict02.xml, objects are registered for events but that doesn't do anything and they aren't called again. Instead the object IDs are stored on the mission type with msnSetData, and the event checks for the objects by ID. This is a fairly recent change.

Otherwise that would be a good solution, but I think a better solution would be to call an event when the briefing pane inits, so we have a chance to set up the mission again rather than destroy it.
Project Renegade (Beta) : "The Poor Man's Corporate Command!"
Real programmers count from 0. And sometimes I do, too.
giantcabbage
Militia Lieutenant
Militia Lieutenant
Posts: 104
Joined: Thu Apr 07, 2011 9:05 pm

Xephyr wrote:
Sat Mar 11, 2017 1:22 am
From my understanding, msnRegisterForEvents isn't functional anymore (at least, from what I've tried). Take a look at times its used in the code, like in Benedict02.xml,
I've just created a test mission and msnRegisterForEvents works with version 1.7

Benedict02 is probably a bad example to start from as it has an empty OnCreate. Most of the setup happens in OnAccepted, and all the ships are created in a timer event (so the player has time to reach the gate). A better example would be the old msDestroyThreatToSlums, but I've also attached a cut-down version to this post:
test_mission.txt
(1.91 KiB) Downloaded 160 times
In <OnCreate> it searches for the nearest centauri warlords station, stores the object ID, and registers for events.

If the station is destroyed, then <OnObjDestroyed> gets called. This event first checks that the object destroyed matches the ID we stored (needed for for complex missions where we may have registered for events from multiple objects) and then calls msnSuccess.
If the mission is still open (i.e. player has not yet accepted) then the mission will simply be deleted and a new mission created if the player revisits the briefing screen.

Xephyr wrote:
Sat Mar 11, 2017 1:22 am
objects are registered for events but that doesn't do anything and they aren't called again. Instead the object IDs are stored on the mission type with msnSetData, and the event checks for the objects by ID. This is a fairly recent change.
Calling (msnRegisterForEvents gSource targetObj) means that the OnObj.. events on the mission (gSource) should be called when something happens to the targetObj. The events check the objects by ID as it is not safe to store the objects directly as they are actually pointers which become invalid if you change system or save/reload

The only recent change I recall with these events is that <OnUpdate> is called automatically - you don't need to use (msnAddRecurringTimerEvent ...) any more.

Older code from before MissionTypes were introduced might use objSetObjRefData / objGetObjRefData to store the obect references. But I think George mostly uses the ID functions now.

Xephyr wrote:
Sat Mar 11, 2017 1:22 am
Otherwise that would be a good solution, but I think a better solution would be to call an event when the briefing pane inits, so we have a chance to set up the mission again rather than destroy it.
Do you have a particular mission in mind where the extra event would help?

It may be possible to rewrite it along the lines of the simple destroy station mission. For more complex cases you can put setup code in OnAccepted / OnStarted. Or if you really need to you can put code directly into the Briefing text.
User avatar
Xephyr
Militia Captain
Militia Captain
Posts: 857
Joined: Fri Dec 14, 2007 1:52 am
Location: Orion Arm, Milky Way
Contact:

giantcabbage wrote:
Sat Mar 11, 2017 11:32 am
In <OnCreate> it searches for the nearest centauri warlords station, stores the object ID, and registers for events.

If the station is destroyed, then <OnObjDestroyed> gets called. This event first checks that the object destroyed matches the ID we stored (needed for for complex missions where we may have registered for events from multiple objects) and then calls msnSuccess.
I'm a little confused here - You don't need to register objects for events in order to call them in events. OnObjDestroyed seems to be called whenever an object is destroyed, because I can use the event to evaluate all kinds of objects when they're destroyed without ever registering an object.
giantcabbage wrote:
Sat Mar 11, 2017 11:32 am
It may be possible to rewrite it along the lines of the simple destroy station mission. For more complex cases you can put setup code in OnAccepted / OnStarted. Or if you really need to you can put code directly into the Briefing text.
I wrote a ticket here explaining what I think we need: http://ministry.kronosaur.com/record.hexm?id=70375

This would only add a few lines of code to the briefing pane, and I think handles things a bit better than adding extra code to every applicable mission
Project Renegade (Beta) : "The Poor Man's Corporate Command!"
Real programmers count from 0. And sometimes I do, too.
giantcabbage
Militia Lieutenant
Militia Lieutenant
Posts: 104
Joined: Thu Apr 07, 2011 9:05 pm

Xephyr wrote:
Sat Mar 11, 2017 4:01 pm
I'm a little confused here - You don't need to register objects for events in order to call them in events. OnObjDestroyed seems to be called whenever an object is destroyed, because I can use the event to evaluate all kinds of objects when they're destroyed without ever registering an object.
Thats odd - is the OnObjDestroyed event part of the MissionType, or is it part of a ShipClass / StationType? If I remove the msnRegisterForEvents from the example mission, then the <OnObjDestroyed> event does not get called when the station is destroyed (and it is not called when any other objects are destroyed).

Generally the OnObj... events should only get called if the mission/object where they are defined has registered for events from the object which gets destroyed (or docked / gates etc). There are the OnGlobalObj... and OnSystemObj... which work without registering for system objects, but these will be much less efficient in most cases as you have to write more code in Tlisp.

Xephyr wrote:
Sat Mar 11, 2017 4:01 pm
I wrote a ticket here explaining what I think we need: http://ministry.kronosaur.com/record.hexm?id=70375

This would only add a few lines of code to the briefing pane, and I think handles things a bit better than adding extra code to every applicable mission
Having an extra event could be useful for some complex missions, or if you wanted to display a mission no longer available message (e.g. "someone else has taken care of the problem so we don't need you any more")

But the original problem you described (target station destroyed before the player accepts the mission) could be handled by the normal mission success/failure conditions without you needing to add any extra code.
Post Reply