I'm not very familiar with coroutines, would probably be up to someone else to figure out a good way to implement them into the event-based system if it gets that far ;p
Quote:
Originally Posted by cavedude
That's the key right there, most of the problems we do have with Perl are mainly due to the way it was implemented into EQEmu, and not inherent to the language itself.
|
Again, I'm not very familiar with the Perl system, but I do see some bits and pieces of the Perl code that seem eerily similar to qst (which I'm more familiar with), so I think I might understand what you mean, at least to some extent.
I'm probably not the best person to try to write a fully fleshed-out quest parser; I don't have that much experience with Lua and mostly just make things up as they occur to me. Just for the sake of it though, a random grab bag of features in my Lua quest parser that seem significant from my point of view:
*Mobs, items, spells and timers are all treated as objects with their own methods and can be stored in variables etc. Adding new methods in either C++ or Lua is fairly straightforward.
*Two scripts are run as a zone is booting, before NPCs spawn: /quests/global/zone_init.lua and /quests/<zone shortname>/zone_init.lua; these give the opportunity to initialize variables or, more likely, to set user defined functions and/or hook extra code onto "core" functions from C++, either globally or for a particular zone (the zone-specific one runs second in case you want to redefine something from the global one). Can also use the opportunity to rename some functions if you don't like the default names. Some standard functions are defined in the global zone_init.lua by default, e.g. mob:say() is just a call to mob:text() with some pre-defined parameters, and GetDist(), IsBehind(), and InCone() are all mostly just math that Lua can handle itself, only making calls to C++ to find coords/heading.
*EVENT_SIGNAL's trigger does not go through C++ at all, letting us pass any kind of data in the signal, including tables, references to mobs/etc, and functions.
*Every EVENT call attempts to trigger two scripted functions: EVENT_<WHATEVER> and GLOBAL_<WHATEVER>. For clients the use is clear enough: GLOBAL versions of events should be defined in playerglobal.lua, while zone-specific EVENTs should be defined in a zone's player.lua. For NPCs, it's up to the user if/how to use the GLOBAL events -- they don't need to be truly global, though they easily can be. They could be used within a zone as a sort of inherited/shared behavior without clashing with normal npc-specific EVENTs, or similar. Lua is fast and can check whether an EVENT/GLOBAL exists without doing much processing, so the double check is not noticable, even if it's rarely used.
*General Lua features: every Mob is given its own environment to store its variables and functions, but these environments are ultimately just tables sitting in specific variables within the global table; we can easily peek into MobA's environment from within the environment/script of MobB. This can be questionable and messy, but there are some good uses, like defining the EVENTs for an add's "script" from within the script of the mob that spawns it (also making it easy to vary behaviors from add to add without needing to juggle multiple script files -- at the extreme end, you could redirect the adds' environments to tables within spawner's environment, completely encapsulating them). The global table can also be accessed easily, making it a convenient place to put data where multiple mobs/scripts can refer to it (and without being tied to the lifespan of any one mob). Mob environments also automatically inherit from the global table, offering another way to define default EVENTs (for example, if you wanted most of the NPCs in a city to share the same EVENT_SAY, you could just plop it straight into the global table; any NPCs given an EVENT_SAY in their own script will "overwrite" the one inherited from the global table) or take it a bit further and have some EVENT inheritance hierarchies (though that can get messy quickly).
...Some of that might not fit too well into the existing framework, though. Not sure how important keeping things familiar and hopefully easily to convert over from Perl is compared to letting it go its own way without having to bend to some possibly-questionable decisions made however many years ago.