StrataSource / Portal-2-Community-Edition

Task tracker for Portal 2: Community Edition
https://www.portal2communityedition.com
146 stars 3 forks source link

Redesign prop_weighted_cube model and skin system #1068

Open vrad-exe opened 1 year ago

vrad-exe commented 1 year ago

Which component should be improved?

Entity

Describe your suggestion

prop_weighted_cube is currently designed for a hardcoded list of models and skins, making customization difficult and awkward, and causing problems for P2CE with new gel types like adhesion gel. This issue will be split into two parts: how to handle gel skins and how to handle custom models. This replaces issue #311.

Gel skins

Current

Cube models are expected to have skins in specific slots used for repulsion and propulsion gels. This already causes some problems in the base game, as some specific gel skins are missing (dirty cubes, active companion cubes, and before DLC2 reflection cubes), but it's become a bigger problem for us since we have a third gel which affects cubes (adhesion gel) and plan to support custom gels in the future.

Proposal

The solution to this is to use a material proxy for painted cubes. ~Every cube material would have its detail texture set to a grayscale version of the existing paint overlays, and a GelOverlay proxy would be added, which sets $detailblendfactor to 0 or 1 depending on if the prop is painted, and $detailtint depending on the gel color.~ Instead there will be 4 skins per cube, being 0 = off, 1 = on, 2 = painted off, and 3 = painted on. When the cube is painted with any gel it switches to the painted skins, which would use a PaintOverlayColor proxy to set $detailtint only.* This allows the overlay to support an infinite number of gel types without adding more skins, as well as match any custom gel colors the user or map has set.

Notes

* This differs from the original proposed method of having the proxy set $detail directly. This new method allows models to use a non-default gel overlay texture like turrets do, while still having it work as expected with the proxy. Using a separate skin for when the cube is painted extends this by also allowing other parameters (e.g. bumpmaps) to be changed (which Valve actually does). The proxy should use resultVar so custom cube models can set other color parameters if they want. All the new cube materials I made have resultVar "$detailtint" already.

Custom models

Current

The easiest method to obtain a cube with a custom model is to set the cube type to 6 or higher, which will cause the in-code model selection to fail and fallback to whatever was set in the model keyvalue. However, this has the side effect of breaking activated and gel skins, and it always behaves like a standard cube. To fix the skins or make it behave like a reflection/sphere/schrodinger cube, AddOutput needs to be fired on map spawn to switch the cube type back to a default type. Even after all this is done, the game still expects all of the skins to be in a specific order which varies between each cube type and is difficult to remember.

Proposal

While we could just make cube type 6 properly supported, that only solves the first problem. Instead we should make use of the NewSkins keyvalue to enable a third method of selecting cube models, which would be NewSkins = 2 internally. This mode would work similarly to how Desolation handles cube models according to TeamSpen, but with a few changes.

In this mode, a new CubeBehavior* keyvalue would be used to set only the cube's behavior, with the model being based on the model keyvalue in all cases. ~The skin** keyvalue would set the cube's default skin, and a skin_active keyvalue would set the skin while on a button (allowing for active skins on custom reflection/schrodinger cube models).~ With separate gel skins this is too complicated, they'd just use a fixed order. The proxy described above would be used for gel coated variants (this differs from Desolation which still has specific gel skins).

To allow the default cubes to still work in this mode, all of the cube models would be recompiled with the new skin layout, and placed under models/props/cubes/. The default model choices would be changed to point to these instead of the original cube models, which we won't modify to preserve backwards compatibility with maps that place them directly as a prop_dynamic or the like.

In the FGD, NewSkins would be labeled "configuration mode" or the like, with a choices dropdown defaulting to mode 2 but allowing 1 to be selected as well (0 is an old beta mode used in some maps, we already hide it). CubeType and SkinType would be moved down below the other keyvalues and labeled as "old", but still be shown and editable for now.

Notes

* Desolation reuses CubeType for this, but we probably want something different since we'll still be supporting old style cubes, so it would end up doing 2 different things depending on the mode which is confusing. Note that the new keyvalue doesn't need antique or companion types, since that's just a standard cube with a different model. ** It would be good to change this as well, but we have to use skin for it to preview in Hammer. Currently we only actually use that keyvalue for the Hammer preview anyway, so it should be fine.

vrad-exe commented 1 year ago

Should probably just allow customizing the on and off skins separately, that would also allow old cubes to be internally converted to the new method using the old skin numbers.

vrad-exe commented 1 year ago

Another way it could work is each model would have 4 skins: disabled, enabled, disabled painted, enabled painted. The painted skins would have a white gel overlay and $detailtint would still be used to set the gel type, but $detailblendfactor no longer needs to be changed.