Blueprint abstraction - creating two blueprints with the same behaviour but different appearance

Hi, I’m trying to figure out something fundamental about working with blueprints.
I’m trying to create a weapon system for my game, its basically a spaceship flying around and it can shoot projectiles.
There can be different weapons, each has its own fire rate and cool down speed, each weapon can has its own type of projectile that it shoots which my differentiate by its mesh, particles, speed etc.
When I look at it from a programmer’s point of view, there would be some sort of weapon abstract class and a projectile abstract class, These will have all of the shooting logic but I couldn’t instantiate them, only by using blueprints.
*I’m not sure if I need to instantiate them or extend them in blueprints.
Anyway lets consider the case where I don’t want to use C++ and only blueprints.
How can I implement this behaviour? for example each projectile is made out of a collision component, particles, mesh and projectile movement component, they are all spawned the same way but each has its own appearance and params.
Do I make a blueprint class with empty components somehow and then extend it?

I’m still not sure what’s the right way to achieve this level of abstraction using blueprints so your feedback will be highly appreciated.

The way I made it in my project is that I created a bullet or projectile blueprint, and in its construction I set up all the different options projectile can be (speed, size, mesh, effects and audio), based on variables created within the blueprint. I need only 1 bullet blueprint for all bullet types. I then set the needed variable to be “Expose on Spawn” so that my weapon can, when it spawn its bullets, send the desired params to the newly spawned bullet.

For my weapon, since my game is fairly simple for that part, I manage it all within my character blueprint itself.

You can also make a blueprint be a child of another and inherit from it, but AFAIK, you cannot make an actor that has a projectile movement be a child of something else than “actor” – Maybe it works in 4.8.