mtasa-blue icon indicating copy to clipboard operation
mtasa-blue copied to clipboard

2DFX Effects API

Open FileEX opened this issue 1 year ago • 19 comments

This PR adds the ability to add, remove, and edit 2DFX effects. It's also possible to edit and remove 2DFX effects from existing objects without the need to edit the model.

Available effect types (relevant in MTA):

  • LIGHT
  • PARTICLE
  • SUN_GLARE
  • ROADSIGN
  • ESCALATOR

Note: The escalator effect allows for the creation of moving escalators

Elements that supports 2dfx with this PR

  • Objects
  • Buildings
  • Vehicles
  • Peds

As for limitations, the limit is the same as with normal model editing, meaning as much as your memory can handle.

[!IMPORTANT] The model must be loaded at least once by the game in order to use these functions. This is because if the model has never been loaded after joining the server, there is no information (CModelInfo) about the model in memory, making it impossible to modify its effects

[!IMPORTANT] Building-type entities created using createBuilding or those that are part of the map must be restreamed after adding a new particle effect (for example, use engineRestreamWorld)

[!CAUTION] Stopping the script does not revert changes. If you removed an effect, you need to restore it; if you changed its properties, you need to reset them... that's exactly why resetModel2DFXEffects was created. (Example is removeWorldModel & restoreWorldModel)

Available functions:

bool addModel2DFX(int model, int x, int y, int z, string type, table properties) -- create new effect
bool removeModel2DFX(int model, int index) -- remove effect from model
nil restoreModel2DFX(int model, int index) -- restore removed effect
nil resetModel2DFXEffects(model) -- reset all model 2dfx effects (remove custom & reset properties for original effects)

nil setModel2DFXPosition(int model, int index, int x, int y, int z)
bool setModel2DFXProperty(int model, int index, string property, mixed value)
nil resetModel2DFXProperty(int model, int index, string property)
nil resetModel2DFXPosition(int model, int index)

float, float, float getModel2DFXPosition(int model, int index)
mixed getModel2DFXProperty(int model, int index, string property [ , bool getFlagsAsTable = false ])
table getModel2DFXEffects(int model [, bool includeCustomEffects = true] ) -- get all model 2dfx effects data
int getModel2DFXCount(int model [, bool includeCustomEffects = true ] )
string getModel2DFXType(int model, int index)

Examples

addModel2DFX(1337, 0.1, 0.1, 0.8, 'particle', {name='fire'});

image

addModel2DFX(1337, 0.1, 0.1, 0.75, 'light', {
	drawDistance = 100,
	lightRange = 18,
	coronaSize = 2,
	shadowSize = 10,
	shadowMultiplier = 40,
	showMode = "default",
	coronaReflection = false,
	flareType = 0,
	flags = {atDay = true, atNight = true},
	shadowDistance = 0,
	offset = {0,0,0},
	color = tocolor(50, 168, 82, 255),
	coronaName = "coronamoon",
	shadowName = "shad_exp",
})

image

setModel2DFXProperty(1226, 0, 'shadowMultiplier', 150)
setModel2DFXProperty(1226, 0, 'color', tocolor(255, 0, 123, 255))

image

removeModel2DFX(3524, 0)

image

getModel2DFXEffects(8610)

--[[
Result

{
 [index] = data

 [0] = {
     position = {2048.5517, 1484.28, 16.88},
     type = "roadsign",
     properties = {
        color = {255, 255, 255, 255},
        flags = 0,
        rotation = {-90, 0, 180},
        size = {4.30, 2.68},
        text1 = "Julius_T_W_South",
        text2 = "Rockshore West__",
        text3 = "The_Mako_Span___",
        text4 = "___~___~____",
     },
 },
}

--]]

Custom features

  • Ability to set a custom text color for roadsigns
  • Ability to use special symbols in roadsigns that are normally unsupported in GTA (list below)
  • Ability to change the alpha of roadsign text (it works in a slightly strange way, but it allows achieving a different text appearance)
setModel2DFXProperty(8610, 0, 'color', tocolor(66, 135, 245, 255))
setModel2DFXProperty(8610, 0, 'text1', '____Hello MTA')
setModel2DFXProperty(8610, 0, 'text2', '__This is 2DFX')
setModel2DFXProperty(8610, 0, 'text3', '____FileEX_'..string.char(0x1))
setModel2DFXProperty(8610, 0, 'text4', string.char(0x4)..'_'..string.char(0xB9)..'_'..string.char(0xB6)..'_'..string.char(0xA7)..'_'..string.char(0x07)..'_'..string.char(0x02)..'_'..string.char(0xDB)..'_'..string.char(0x1E))

image

Roadsign new symbols list

  • / , |
  • scull icon
  • alien icon
  • invalid icon
  • parking icon
  • info icon
  • human icon
  • winding road (?)
  • train icon
  • hill icon (?)

image

The 2DFX documentation will be created once the PR has been merged. Possibly resolves: #3579

FileEX avatar Sep 20 '24 20:09 FileEX

what about a property for setting 2DFX dimension/interior ? also isn't the corona limit still 64 so something like Project2DFX's LOD lights still wouldn't be possible?

Meine1 avatar Sep 26 '24 15:09 Meine1

what about a property for setting 2DFX dimension/interior ?

2DFX effects do not have their own dimension and interior. They are part of the model, so they take on the same dimension and interior as the given object/building.

also isn't the corona limit still 64 so something like Project2DFX's LOD lights still wouldn't be possible?

The current limit for visible coronas is indeed 64. I already know where and what needs to be done to increase it. However, I'm wondering whether it should be done as part of this PR or as a separate feature like a 'limit adjuster'

FileEX avatar Sep 26 '24 15:09 FileEX

Is it possible to apply effect to certain MTA object, just like targetElement when applying shader?

sacr1ficez avatar Sep 26 '24 17:09 sacr1ficez

Can you create a new 2DFX class for this instead of using engine class defs?

TheNormalnij avatar Sep 26 '24 18:09 TheNormalnij

I already know where and what needs to be done to increase it. However, I'm wondering whether it should be done as part of this PR or as a separate feature like a 'limit adjuster'

if the corona limit fix is not too complex, it would be a good idea to make it part of this because a full limit adjuster with more features would be another whole beast.

Meine1 avatar Sep 26 '24 21:09 Meine1

Is it possible to apply effect to certain MTA object, just like targetElement when applying shader?

~~If I'm not mistaken, each entity has its own RwObject, so it should be possible to add an effect only for one object, and not for all with this id~~

Unfortunately not, because although each entity has its own instance of RwObject, all instances share the same geometry — the RpGeometry pointer is the same for every object with a given ID. 2DFX effects are stored in the geometry plugin, so unfortunately it's not possible. It would require changing the logic of entity creation in GTA so that each entity would have its own geometry (which would also require more memory)

FileEX avatar Sep 27 '24 18:09 FileEX

Update

Added full support for roadsign 2dfx.

  • We can create our own roadsigns and edit existing ones.

Screenshot_11 Screenshot_12

By default, GTA only allows to set the colors white, black, gray and red. However, I will try to add the ability to set custom color

FileEX avatar Oct 02 '24 20:10 FileEX

can we make changes to the grass?

delusionalismHQ avatar Oct 04 '24 13:10 delusionalismHQ

can we make changes to the grass?

What do you mean?

FileEX avatar Oct 04 '24 19:10 FileEX

can we make changes to the grass?

What do you mean?

mta-screen_2024-10-09_22-24-10 i mean plant fx's.

delusionalismHQ avatar Oct 09 '24 19:10 delusionalismHQ

Grass/plants are not a 2DFX effect. Grass is generated by a RW, and it's a completely different mechanism. Maybe, if there’s interest, I’ll create an API for plants as well, so that custom ones can be made, etc. However, I don't think this is something that the community desires

FileEX avatar Oct 11 '24 16:10 FileEX

Grass/plants are not a 2DFX effect. Grass is generated by a RW, and it's a completely different mechanism. Maybe, if there’s interest, I’ll create an API for plants as well, so that custom ones can be made, etc. However, I don't think this is something that the community desires

Increasing grass limits would be nice.

lopezloo avatar Nov 04 '24 03:11 lopezloo

wow, that would be really helpful, especially working on some VC-based map to SA.

gta191977649 avatar Nov 16 '24 12:11 gta191977649

This draft pull request is stale because it has been open for at least 90 days with no activity. Please continue on your draft pull request or it will be closed in 30 days automatically.

github-actions[bot] avatar Feb 15 '25 01:02 github-actions[bot]

any update?

delusionalismHQ avatar Feb 19 '25 22:02 delusionalismHQ

any update?

I need to think about this because when an object streams in, all its effects reset to default since the object is reloaded from the .dff file. I solved this with hooks, but it causes random crashes when using functions like engineRestreamWorld. I already have a potential solution that is 99% likely to work correctly, but at the moment, I have several other PRs in progress. I'll get back to this once I finish what I've already started

FileEX avatar Feb 24 '25 14:02 FileEX

Finally update

First post has been updated!

Well, after half a year of inactivity on this PR, I finally managed to bring it to a finished state. I’ve been working on it over the past three weeks, during which I encountered several bugs related to the parser, but fortunately, thanks to collaboration (special thanks to @tederis and @sbx320 ), we were able to patch them along the way. All the code was written from scratch, completely new. Over this half-year, I gained a lot of new knowledge and experience, and now I can confidently say that the previous code was not of good quality and was causing crashes. The current version is free of any crashes, and based on my tests, I haven’t found any bugs. I have tested all functions, a lot of variants, and all effect types, including escalator.

I can see how much interest this PR has generated, and that gave me the motivation to finish it instead of abandoning it for years.

In my opinion, the PR is ready for review, and I’m eagerly looking forward to its merge, so I can start preparing full documentation related to the functions, 2DFX, flags, properties, etc. I just want to mention that the video "2DFX Explain" by Tut contains a mistake when it claims that some flags don't work in MTA — all flags that work in SP also work in MTA, although some require specific conditions. Everything will be explained in the documentation.

And for now… I'm waiting for the review and hopefully the merge.

FileEX avatar Apr 27 '25 02:04 FileEX

Hi, looking at the API, you cannot add 2DFX effects without affecting the models right? For example, adding 2DFX text in the world without it being attached to an element or model.

Furthermore, you also can't edit just the 2DFX effects of a single element instead of editing the whole thing, right?

I still think this is cool AF... but I wouldn't find an use for it unless i can use the effects standalone or per element... but I could see other scripters using it. Thanks for your work!

PlatinMTA avatar May 10 '25 22:05 PlatinMTA

Hi, looking at the API, you cannot add 2DFX effects without affecting the models right? For example, adding 2DFX text in the world without it being attached to an element or model.

Furthermore, you also can't edit just the 2DFX effects of a single element instead of editing the whole thing, right?

I still think this is cool AF... but I wouldn't find an use for it unless i can use the effects standalone or per element... but I could see other scripters using it. Thanks for your work!

This is how the 2DFX plugin works in GTA SA and how it was implemented. It stems from the nature of the RenderWare engine itself. The 2DFX plugin is added to the geometry of a model. When GTA loads a model, it creates an instance of a specific model - in particular, an instance of RwObject and each instance uses the same pointer to the RpGeometry. To save memory, GTA loads the geometry only once and shares a single instance of that geometry across all model/object instances. As a result, the 2DFX effect is also allocated only once along with the geometry.

This does not mean, however, that adding support for per-element 2DFX effects is impossible but it would only be feasible for elements created by MTA through internal processing of such effects, for example with CClientObject.

FileEX avatar May 10 '25 23:05 FileEX

@FileEX Please, resolve the conflicts.

tederis avatar Sep 24 '25 06:09 tederis