2DFX Effects API
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'});
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",
})
setModel2DFXProperty(1226, 0, 'shadowMultiplier', 150)
setModel2DFXProperty(1226, 0, 'color', tocolor(255, 0, 123, 255))
removeModel2DFX(3524, 0)
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))
Roadsign new symbols list
/ , |- scull icon
- alien icon
- invalid icon
- parking icon
- info icon
- human icon
- winding road (?)
- train icon
- hill icon (?)
The 2DFX documentation will be created once the PR has been merged. Possibly resolves: #3579
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?
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'
Is it possible to apply effect to certain MTA object, just like targetElement when applying shader?
Can you create a new 2DFX class for this instead of using engine class defs?
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.
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)
Update
Added full support for roadsign 2dfx.
- We can create our own roadsigns and edit existing ones.
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
can we make changes to the grass?
can we make changes to the grass?
What do you mean?
can we make changes to the grass?
What do you mean?
i mean plant fx's.
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
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.
wow, that would be really helpful, especially working on some VC-based map to SA.
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.
any update?
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
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.
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!
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 Please, resolve the conflicts.