DavidJCobb / ReachVariantEditor

A tool for editing Halo: Reach game variants.
23 stars 9 forks source link

Using object types outside of current list #9

Open noble-ux opened 3 years ago

noble-ux commented 3 years ago

From my understanding the compiler checks objects in the script to a predefined list to grab it's tag location.

Is there any way for users to add on to this list or place other types of items that are not already predefined such as street_cone or even ff_plat_2x1_flat?

If not I wouldn't getting a list together of some objects and their tags if I could provide those to be added.

DavidJCobb commented 3 years ago

Apologies for the delayed reply.

The list of objects available to Megalo is defined in the motl tag on each *.map file. Compiled scripts refer to entries in that list by their numeric index within the list, notably not by the actual list item names. ReachVariantTool therefore has a hardcoded list that maps names (and in some cases, extra information like descriptions) to these numeric indices. Notably, it does not open *.map files and so does not care what names are used in the motl tag (in fact, for several list items I chose to use different names because they were more intuitive).

As such:

It must also be noted that while it may be possible to extend the motl list with new entries at its end, ReachVariantTool will reject numbers that are past the "official" list end. This is because invalid values will crash the game.

DavidJCobb commented 3 years ago

Addendum: I could in theory add a feature to allow people to override or replace the object type names for the compiler, but that would have to be opt-in on a per-script basis (rather than a program-wide setting) for the following reasons:

We could set up OpcodeArgValueObjectType to be able to hold a pointer to a DetailedEnum to use as an override for the built-in one, and then have some kind of facility whereby you can define an object type list in a text file and we can load that into a DetailedEnum on request. (Perhaps it's time to add #pragmas to the compiler?) We're somewhat fortunate in this regard in that OpcodeArgTypeinfo::imported_names is a struct which holds a DetailedEnum pointer: we can overwrite that if need be. (Actually, in that case, it'd be better for the logic for ObjectArgValueObjectType to just refer to the imported_names enum member directly.)

If I add this feature, I would need to validate names in the new list to enforce the usual rules against shadowing built-ins and keywords, with the additional caveat that I have to let you shadow built-ins that belong to OpcodeArgValueObjectType because you're replacing its list of built-ins in the first place.

Ideal syntax, then, would probably be something like this with some syntax for the object names:

pragma replace_imported_names(_object_type):
   imports/my_cool_map_objects.txt
end

Alternatively, we could allow this either inline in a script or in a secondary file:

pragma replace_imported_names(_object_type):
   object_0
   object_1
   object_2
   -- ...
end

And then we could allow imports of secondary files with another pragma (using paths relative to the application directory):

pragma import(imports/my_cool_map_objects.txt)

The overall syntax for pragma directives, then, would be:

pragma name -- no arguments or body
pragma name(arguments) -- no body
pragma name:
   -- body
end
pragma name(arguments):
   -- body
end
DavidJCobb commented 3 years ago

Additional considerations: