The best and tried / true method:
- Make an educated guess at how many rockets you *think* will be airborn, on average, at any given time.
- Create a dynamic array to store all rockets.
- Create x number of slots using a loop, instancing rocket objects, and providing the relevant info for the slot in the form of a UDT (rocketObj, x#,y#,z#, ox#,oy#,oz#, launchtime#, active). X = the guessed number from step 1.
- Once all of the initial rocket data has been loaded, create a free_rocket() function that goes through the entire array, checking to see if a rocket's active flag is set to 0. If true, return the free index found. If there are no free rockets (they're all active), create a new entry in the array at the top or bottom, whichever you prefer, and set it's data. You'll want a free_object() function as well to get a free object number for the newly created rocket.
- When you get the free rocket, orient it to the gun's position / angle, and set it's active flag to 1, and it's launchtime# to TIMER(). Then show the rocket.
- Cycle through all array slots in the rocket array, checking if the current slot is active. If so, store the rocket's old x#,y#,z# variables as it's current position, move the rocket forward at whatever speed you want, and find the new x#, y#, z# positions. Then cast an intersection check from the old coords to the new ones, checking for intersection with the map and any enemies.
- If the map is hit, if the rocket's index in the rocket array is greater than the guessed number of rockets needed at the beginning, remove the rocket's index / delete the rocket object. If it isnt greater, just set the rocket's active flag to 0 and hide it.
- If an enemy is hit, do the same check for if a map is hit, except damage the enemy.
- Check if the time elapsed since the rocket was launched is greater than x amount of seconds, and if so, repeat the step from if the map is hit. This stops rockets from travelling into the sky infinitely. Alternatively, you can do a collision check with the sky sphere. The first method is faster / more efficient however.
- You'll want a kill_rocket(obj) function that plays an explosion effect / delete's the rocket object that you can call in any of the above circumstances (remember to take into account the check in the step for if the map is hit).
Creating / instancing objects at runtime can cause lag, which is why you want to load an initial guess of how many rockets you think will be airborn at any time before runtime. Then, the system only loads / deletes rocket objects if it's absolutely necessary.
There are calculations you can do to figure out how many rockets you'll need in the game, I just forget what the formula is. It involves taking into account the max players in the game, the delay time between rocket shots (assuming you cant fire every rocket right after each other instantly), the speed the rockets move, the time rockets have to be airborn before self destructing, etc.
You'll notice raycasting is still used in this case, in order to make sure a collision is detected, no matter how fast the rocket moves.