public void Rpc_spawn_blood(GameObject[] victim, short[] pox, short[] angle, bool[] isheadshot) { for (int i = 0; i < victim.Length && victim[i] != null; i++) { //Decompress coordinates float x = pox[i]; x /= CONSTANTS.SYNC_POS_MUTIPLIER; float y = pox[pox.Length / 2 + i]; y /= CONSTANTS.SYNC_POS_MUTIPLIER; Vector2 bleed_pos = new Vector2(x, y); //Decompress angle float angle_decompressed = CONSTANTS.seed_short_to_float(angle[i], 360); victim[i].GetComponent <Body_generic>().bleed(bleed_pos, angle_decompressed, isheadshot[i]); } }
//This function simulate bullets locally public void shoot(GameObject gun_user, short fire_point_x, short fire_point_y, short aim_dir, sbyte[] aim_dir_offset, float lag_prediction = 0) { Vector2 fire_point = new Vector2(fire_point_x / CONSTANTS.SYNC_POS_MUTIPLIER, fire_point_y / CONSTANTS.SYNC_POS_MUTIPLIER); Body_generic user_body = gun_user.GetComponent <Body_generic>(); if (equip == null) { equip = GetComponent <Equipable_generic>(); } bool hasAuthority = equip.isServer; if (!cvar_watcher.isDedicated() && !Local_precomputation) { spawn_muzzle(); } //Only spawn muzzle on clients float aim_dir_float = CONSTANTS.seed_short_to_float(aim_dir, 360); float firecone_maxrange = accuracy + precise; if (bullet.tag == "bullet")//Shooting bullet is local authoritative, meaning shooter decides if he hits { if (aim_dir_offset == null) { fire_bullet(gun_user, fire_point, aim_dir_float, local_player_protocol(user_body), lag_prediction); } else { for (int i = 0; i < aim_dir_offset.Length; i++) { float blt_dir = aim_dir_float + CONSTANTS.seed_sbyte_to_float(aim_dir_offset[i], firecone_maxrange); fire_bullet(gun_user, fire_point, blt_dir, local_player_protocol(user_body), lag_prediction); } } } else if (bullet.tag == "bullet_laser")//Shooting laser is local authoritative, meaning shooter decides if he hits { if (aim_dir_offset == null) { fire_laser(gun_user, fire_point, aim_dir_float, local_player_protocol(user_body)); } else { for (int i = 0; i < aim_dir_offset.Length; i++) { float blt_dir = aim_dir_float + CONSTANTS.seed_sbyte_to_float(aim_dir_offset[i], firecone_maxrange); fire_laser(gun_user, fire_point, blt_dir, local_player_protocol(user_body)); } } } else if (bullet.tag == "bullet_rocket")//Shooting rocket is server authoritative, meaning server decides if he hits { if (hasAuthority) { if (aim_dir_offset == null) { fire_rocket(gun_user, fire_point, aim_dir_float, hasAuthority); } else { for (int i = 0; i < aim_dir_offset.Length; i++) { float blt_dir = aim_dir_float + CONSTANTS.seed_sbyte_to_float(aim_dir_offset[i], firecone_maxrange); fire_rocket(gun_user, fire_point, blt_dir, hasAuthority); } } } } if (bullet.tag == "bullet_tesla")//This function only runs on local. local simulate path, broadcast path and damage to network { fire_tesla(gun_user, fire_point, aim_dir_float, local_player_protocol(user_body), null, lag_prediction); } else if (bullet.tag == "bullet_flame")//Shooting bullet is server authoritative, meaning server decides if he hits { float blt_dir = aim_dir_float + CONSTANTS.seed_sbyte_to_float(aim_dir_offset[0], firecone_maxrange); bullet.transform.rotation = Quaternion.Euler(0, 0, blt_dir - bullet.GetComponent <ParticleSystem>().shape.arc / 2); bullet.GetComponent <ParticleSystem>().Emit(burst_shots); } }