Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SM64] Combined Export Panel & Behavior Script Exporting #284

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

jesusyoshi54
Copy link
Collaborator

This PR aims to streamline exporting for SM64 all into one panel. This PR is made for C exclusively, and binary features should remain unchanged.

image

  • Move Level, Geo, and Collision exporting all into the same panel
  • Share properties for all types of exporting so that exports are more streamlined
  • Exports of collision, geo layout objects and armatures all from a single button
  • Exports of graphics data automatically write level script loads in the correct respective script.c file
  • Exports of graphics data will also create a model ID define in model_ids.h
  • Exports can have a separate defined collision and graphics object, or export from the shared selected object
  • Support for exporting multiple objects at once. All exported objects will export using the name of the blend object
  • Fixed level scripts erasing data from other scripts linked inside the existing previous level script

Along with all of the above improvements to exporting. I have also added in behavior script exporting.
Behavior scripts will be exported using the same properties as above, and they also have the option to inherit the following properties from the exported object:

  • collision name
  • model ID

Behavior scripts come with several preset behaviors and support adding, deleting and editing args of all the existing original sm64 behavior script cmds.

Copy link
Collaborator

@Lilaa3 Lilaa3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export level SHOULD NOT be in the same panel as combined object exports, especially if the name of the panel is "SM64 Combined Object Exporter", the positioning of the level prop and the fact that this will cause confusion while exporting for both actor exports and level exports.

@Lilaa3
Copy link
Collaborator

Lilaa3 commented Jan 9, 2024

I'm unsure if I like stuff like "Export behavior" and "Export collision" to be on by default
Let's say someone is just trying to do a mario export, they maybe watch a tutorial from 1 year ago for 2 minutes and then download fast64 and open up the mario blend and then oops! Behavior must have more than 0 commands?? What does that mean??? And oh no here comes 10 people asking about the same thing on discord!
You will have people exporting collision when they don´t want to on accident too. And this will happen even if you are exporting an armature. People with older files (and even with new files) will have to pay attention and turn off these toggles, it's pretty inconvenient. Just let the users toggle it themselves.

@Lilaa3
Copy link
Collaborator

Lilaa3 commented Jan 9, 2024

All behavior scripts should start with a BEGIN command, maybe don´t make the user add those manually and just add an enum for the object list? Also maybe adding a warning for when the behavior script doesn´t contain an END_LOOP, BREAK, DEACTIVATE, GOTO or RETURN could be a neat addition (only a warning because the user could have their own custom command which exits out of the behavior script). And if you are willing to step into feature creep territory, having toggles for common vanilla object flags would be very convenient. I don´t know what else could be done to help the user not mess up the behaviors.
Adding error checks for empty arguments could be another good addition but to be fair the user will just get a compilation error if they mess up their arguments so it is not really necessary

Comment on lines 2079 to 2081
prop_split(col, self, "collision_object", "Collision Obj")
if self.export_gfx and not self.export_all_selected:
prop_split(col, self, "graphics_object", "Geo Layout Obj")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to abbreviate these?
Also fast64 uses "Geolayout" instead of "Geo Layout" everywhere else

insert_line = 0
alt_insert_line = 0
match_line = 0
for j, line in enumerate(file_lines):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason you use j over i for loops? Typically you use j for a second index and i for the first index

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

habits from electrical studies no real reason


def export_group_script_load(self, script_path, props):
if not script_path.exists():
PluginError(f"could not find {script_path.stem}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of your plugin errors start with lower case, but some of yours and all others in fast64 use normal casing.

return {"CANCELLED"}

props.context_obj = None
# you've done it!~
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true

Comment on lines +1798 to +1801
if props.export_all_selected:
return
else:
raise Exception(e)
Copy link
Collaborator

@Lilaa3 Lilaa3 Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just do if not props.export_all_selected:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unresolving this, but also I personally do this in these kinds of exceptions as much as possible, in here it may seem less useful but having a full traceback is usually good, pylint warns for it

Suggested change
if props.export_all_selected:
return
else:
raise Exception(e)
except Exception as exc:
# pass on multiple export, throw on singular
if not props.export_all_selected:
raise Exception(exc) from exc

fast64_internal/sm64/sm64_level_writer.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_constants.py Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_collision.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_constants.py Show resolved Hide resolved
fast64_internal/sm64/__init__.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_geolayout_writer.py Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_level_writer.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_level_writer.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_level_writer.py Outdated Show resolved Hide resolved
@jesusyoshi54
Copy link
Collaborator Author

jesusyoshi54 commented Jan 9, 2024

All behavior scripts should start with a BEGIN command

Not necessarily true. Behaviors can exist as partial scripts that are jumped to as an immediate example, and also for objects in the default list the BEGIN cmd is redundant. If the user wants to set up a prototypical behavior quickly they can use a preset, such as a the solid object one.

add an enum for the object list?
Also maybe adding a warning for when the behavior script doesn´t contain an END_LOOP, BREAK, DEACTIVATE, GOTO or RETURN could be a neat addition (only a warning because the user could have their own custom command which exits out of the behavior script).

Good ideas I will incorporate these

And if you are willing to step into feature creep territory, having toggles for common vanilla object flags would be very convenient.

I am not sure this would work well while not bloating the UI and also being flexible.

I don´t know what else could be done to help the user not mess up the behaviors. Adding error checks for empty arguments could be another good addition but to be fair the user will just get a compilation error if they mess up their arguments so it is not really necessary

I don't believe in excessively controlling user output. It should just be what they type, otherwise it may be inflexible.

@Lilaa3
Copy link
Collaborator

Lilaa3 commented Jan 9, 2024

I am not sure this would work well while not bloating the UI and also being flexible.

The flexibility is not an issue, but I agree the ui bloat could be, up to you I guess

fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_level_writer.py Show resolved Hide resolved
@jesusyoshi54
Copy link
Collaborator Author

jesusyoshi54 commented Jan 20, 2024

I have made the following improvements:

  • Added enum for object lists in behaviors
  • Added object field enum in behaviors
  • Added checkbox to not export model ID and script load, default is False
  • Set default model ID to 0xE2, which is the first unoccupied model ID in vanilla SM64
  • Small fixes in regards to exporting multiple objects
  • Added property upgrader that works

fast64_internal/sm64/__init__.py Outdated Show resolved Hide resolved
fast64_internal/sm64/__init__.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Show resolved Hide resolved
icon="ERROR",
)

info_box = box.box()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Scutte please.. imagine
image

fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Show resolved Hide resolved
fast64_internal/sm64/sm64_objects.py Outdated Show resolved Hide resolved
@jesusyoshi54
Copy link
Collaborator Author

jesusyoshi54 commented Feb 2, 2024 via email

…Added option to filter out object type suffixes while exporting. Made behaviors added with UI operator default to expanded. Made pathing preview more accurate.
@jesusyoshi54
Copy link
Collaborator Author

The latest commit should address all the review concerns and also added extra control over object naming.

@Lilaa3
Copy link
Collaborator

Lilaa3 commented May 12, 2024

The big issue with this is hackersm64, what are your plans to address enum model ids and level scripts being included in the actors folder (was reverted for the time being but is still planned afaik, fazana said grep could be an easy solution for this one)

@jesusyoshi54
Copy link
Collaborator Author

I have no plans to address a change not yet implemented in a specific repo. All features of this panel can be enabled/disabled independently, if a specific repo does not work with a feature, they can turn it off.
If you turn off the Export Script Loads feature, there will be no model ID or level script export, and only the geo.inc.c and collision.inc.c files will be exported, as would be done with the current existing panel.

If there is support for specific repos and versions of repos I may address this but I don't believe I have any measure currently to handle this.

export_col: bpy.props.BoolProperty(
name="Export Collision",
default=False,
description="Export collision for linked or selected mesh that have collision data",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don´t add final punctuation in descriptions

)
export_col: bpy.props.BoolProperty(
name="Export Collision",
default=False,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'd remove all default=False as that is the default for that argument anyways, it doesn´t make anything more explicit as defaulting to false is the norm for booleans and other parts of this same pr don't specify it, to me it is very much just code bloat

Comment on lines +233 to +237
old_scene_props_to_new = {
"geoLevelName": "custom_export_name",
"geoExportPath": "custom_export_path",
"geoName": "object_name",
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing geoGroupName, doesn´t handle col but that is fine as there is rarely a case where someone would have a seperate file for just a collision export

rootObj.select_set(True)
bpy.context.view_layer.objects.active = rootObj
if not meshGeolayout.has_data():
raise "No gfx data to export, gfx export cancelled"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raise with no exception type?

"LOAD_MIO0_TEXTURE",
"LOAD_YAY0",
"LOAD_YAY0_TEXTURE",
"LOAD_RAW",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add in LOAD_VANILLA_OBJECTS for hackersm64


elif self.export_header_type == "Actor":
prop_split(box, self, "group_name", "Group Name")
if self.group_name == "custom":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom not custom

# level export header
level_name: bpy.props.EnumProperty(items=enumLevelNames, name="Level", default="bob")
# actor export header
group_name: bpy.props.EnumProperty(name="Group Name", default="group0", items=groups_obj_export)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just Group for the name, since this is an enum and I heavily dislike this kind of repetition personally
image

icon="ERROR",
)

info_box = box.box()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Scutte please.. imagine
image

Comment on lines +2176 to +2181
if self.export_col and not self.export_all_selected:
prop_split(box, self, "collision_object", "Collision Obj")
if self.export_gfx and not self.export_all_selected:
prop_split(box, self, "graphics_object", "Geo Layout Obj")
if self.export_gfx and self.export_script_loads:
prop_split(box, self, "model_id", "Model ID Num")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should try including these in their respective export boxes, looks really good imo

Comment on lines +2074 to +2089
split = layout.split(factor=0.333)
if self.export_col:
box = split.box()
box.prop(self, "export_col")
box.prop(self, "include_children")
box.prop(self, "export_rooms")
else:
split.prop(self, "export_col")
if self.export_gfx:
box = split.box()
box.prop(self, "export_gfx")
box.prop(self, "export_script_loads")
else:
split.prop(self, "export_gfx")
if not self.export_all_selected:
split.prop(self, "export_bhv")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another ui suggestion, have you tried a row with align and then using toggle=1 for the export_ props? I tried it and it looks very clean imo, oot does it a lot and i love it (also using .column())
image

@Lilaa3
Copy link
Collaborator

Lilaa3 commented May 31, 2024

bump #284

A lot of your plugin errors start with lower case, but some of yours and all others in fast64 use normal casing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants