As I make my progress working on shooter project, I thought that sharing my code (partly) on the forum won't hurt anyone (hopefully).

Here I want to share ugly recoil code I use + proper bullet (timing) creation (big thanks to Superku for giving me the hint).
Code:
#include <acknex.h>
#include <default.c>
#include <windows.h>

#define PRAGMA_POINTER

var amount_of_bullets = 0;

void bullet_create(){
	var alive = 16;
	VECTOR pos,temp,vel;
	
	var accurasy_x = 5 - random(10);
	var accurasy_y = 5 - random(10);
	vec_set(&pos, &camera->x);
	vec_set(&vel, vector(500, accurasy_x, accurasy_y));
	vec_rotate(&vel, &camera->pan);
	
	amount_of_bullets++;
	
	while(alive > 0){
		
		vec_set(&temp, &vel);
		vec_scale(&temp, time_step);
		vec_add(&temp, &pos);
		c_trace(&pos, &temp, IGNORE_PASSABLE | USE_POLYGON);
		if(trace_hit){ alive = 0; }
		
		draw_point3d(&pos, COLOR_RED, 100, 4);
		
		vec_set(&pos, &temp);
		alive -= time_step;
		
		wait(1);
	}
	
	amount_of_bullets--;
}

void main(){
	
	fps_max = 60;
	fps_min = 30;
	
	level_load("");
	wait(3);
	
	sun_light = 0;
	random_seed(0);
	
	ENTITY *ground = ent_create(CUBE_MDL, vector(0, 0, -32), NULL);
	set(ground, POLYGON | LIGHT);
	vec_set(&ground->scale_x, vector(25, 25, 0.1));
	vec_set(&ground->blue, COLOR_GREEN);
	ground->ambient = 100;
	
	ENTITY *box = ent_create(CUBE_MDL, vector(64, -16, -16), NULL);
	set(box, POLYGON | LIGHT);
	vec_set(&box->blue, COLOR_RED);
	box->ambient = 100;
	
	VECTOR cam_pos;
	vec_fill(&cam_pos, 0);
	ANGLE cam_angle;
	vec_fill(&cam_angle, 0);
	
	ANGLE recoil_angle;
	vec_fill(&recoil_angle, 0);
	
	VECTOR explo_pos;
	vec_fill(&explo_pos, 0);
	
	var explo_power = 0, explo_timer = 0, explo_def_time = 0.5;
	var recoil_power = 1.5, recoil_do = 0, recoil_arc = 0;
	var shooting_timer = 0, shooting_delay = 0, shooting_rate = 1.5;
	
	while(1){
		
		fps_max = 60;
		if(key_q){ fps_max = 20; }
		if(key_e){ fps_max = 30; }
		DEBUG_VAR(fps_max, 60);
		
		static var autolock_mouse_locked = 0;
		if(!autolock_mouse_locked && window_focus){
			autolock_mouse_locked = 1;
			RECT rect;
			GetClientRect(hWnd, &rect);
			ClientToScreen(hWnd, &rect);
			ClientToScreen(hWnd, &rect.right);
			ClipCursor(&rect);
		}
		if(autolock_mouse_locked && !window_focus){
			autolock_mouse_locked = 0;
			ClipCursor(NULL);
		}
		
		cam_angle.pan = cycle(cam_angle.pan - mickey.x / 6.5, 0, 360);
		cam_angle.tilt = clamp(cam_angle.tilt - mickey.y / 6.5, -90, 90);
		cam_angle.roll = 0;
		
		if(recoil_do){
			
			if(random(1) > 0.5){ recoil_angle.pan -= random(recoil_power); }
			else{ recoil_angle.pan += random(recoil_power); }			
			recoil_angle.tilt += (recoil_power + random(recoil_power));
			
		}
		else{
			
			recoil_angle.pan -= (recoil_angle.pan - 0) * 0.1 * time_step;
			recoil_angle.tilt -= (recoil_angle.tilt - 0) * 0.1 * time_step;
			
		}
		
		recoil_angle.tilt = clamp(recoil_angle.tilt, 0, 35);
		recoil_do = 0;
		
		if(mouse_left && shooting_delay == 0){
			
			bullet_create();				
			recoil_do = 1;
			shooting_delay = 1;
			
		}
		
		if(shooting_delay == 1){
			
			shooting_timer += time_step;
			while(shooting_timer >= shooting_rate){
				recoil_do = 0;
				shooting_delay = 0;
				shooting_timer -= shooting_rate;
			}
			
		}
		
		// logic here is to increase (add) 'explo_power' when there is an explosion near by
		// increase it depending on the distance to explosions origin
		// also set upper limit, cause having few explosions near by at once will make camera go nuts
		/*
		// fast example
		var dist_to_explosion = vec_dist(my.x, you.x); // you.x - here is an explosion's position
		explo_power += you->explosion_damage / dist_to_explosion; // you->explosion_damage - damage at explosion't origin position (max damage)
		explo_power = clamp(explo_power, 0, 10); // 10 - uppwer limit 
		*/
		if(mouse_right){
			
			explo_timer += time_step;
			while(explo_timer >= explo_def_time){				
				explo_power = 5;				
				explo_timer -= explo_def_time;				
			}
			
		}
		explo_power -= (explo_power - 0) * 0.1 * time_step;
		
		if(explo_power > 0.5){
			
			if(random(1) > 0.5){ explo_pos.x = random(explo_power); }
			else{ explo_pos.x = random(explo_power); }
			if(random(1) > 0.5){ explo_pos.y = random(explo_power); }
			else{ explo_pos.y = random(explo_power); }
			
		}
		else{
			
			explo_pos.x -= (explo_pos.x - 0) * 0.1 * time_step;
			explo_pos.y -= (explo_pos.y - 0) * 0.1 * time_step;
			
		}
		
		recoil_arc = (recoil_angle.tilt * 0.25);
		recoil_arc = clamp(recoil_arc, 0, 15);
		camera->arc = 90 - recoil_arc;
		
		camera->pan = cam_angle.pan + recoil_angle.pan;
		camera->tilt = cam_angle.tilt + recoil_angle.tilt;
		camera->roll = cam_angle.roll;
		
		vec_set(&cam_pos, vector(explo_pos.x, explo_pos.y, 0));
		vec_rotate(&cam_pos, vector(camera->pan, 0, 0));
		// vec_add(&cam_pos, &my->x); // attach to player here
		
		vec_set(&camera->x, &cam_pos);
		
		DEBUG_VAR(amount_of_bullets, 100);
		
		wait(1);
	}
	
}

Just run the code and shoot (mouse left), you can change framerate with Q (fps_max = 20) and E (fps_max = 30). You can also see that the amount of bullet's won't change on lower framerate (thank you mighty Superku!). Yet I'm still working on improving the recoil effect, I'm not really sure if it's really framerate independent right now, but seems to be working so far. Any improvements and ideas are welcome. No credit needed (you can credit Superku for the hint he shared and for being an awesome member of this forum).

Edit: added explosion effect, hold mouse right for it.

Best regards.

Last edited by 3run; 12/10/17 20:26. Reason: added explosion/aftershock effect

Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung