//This function will detect object collision //projectile will stop no matter what public void impact_object(GameObject obj, Vector2 hit_point) { float heat = Damage(); if (obj.tag == "structure")//Structure { if (local && heat > 0) { Body_generic activator_body = activator.GetComponent <Body_generic>(); if (activator_body.dmg_tags.Contains(obj.tag) && activator.layer != obj.layer) { float angle = Mathf.Atan2(aimdir.y, aimdir.x) * 180 / Mathf.PI; //If Client authoritates laser if (activator_body.isPlayer && !activator_body.isServer) { activator_body.player_controller.add_to_shot_list(obj, heat, hit_point, 0, CONSTANTS.seed_float_to_short(angle, 360), false, 1); } else//Server client || npc authoritates laser { obj.GetComponent <Structure_generic>().health -= CONSTANTS.heat_to_physics(heat); } if (activator_body.isLocalPlayer) { activator_body.player_controller.hit_mark(); } } } } if (obj.GetComponent <Rigidbody2D>() != null) { Vector2 force = CONSTANTS.DAMAGE_FORCE_MULTIPLIER * (end - start).normalized * heat / 20; obj.GetComponent <Rigidbody2D>().AddForceAtPosition(force, hit_point); } }
void Sample_color(GameObject the_user) { Color chosen_color; Body_generic user_body = the_user.GetComponent <Body_generic>(); if (user_body.isLocalPlayer) { chosen_color = CONSTANTS.COLOR_PLAYERLOCAL; } else if (user_body.isPlayer) { if (user_body.character_type == user_body.cvar_watcher.local_player.character_type)//Player ally { chosen_color = CONSTANTS.COLOR_PLAYERALLYOTHER; } else//Player Enemy { chosen_color = CONSTANTS.COLOR_PLAYERENEMYOTHER; } } else//NPC { if (user_body.character_type == user_body.cvar_watcher.local_player.character_type)//NPC ally { chosen_color = CONSTANTS.COLOR_ALLY; } else//NPC Enemy { chosen_color = CONSTANTS.COLOR_ENEMY; } } laserAimColor.SetKeys(new GradientColorKey[] { new GradientColorKey(chosen_color, 0), new GradientColorKey(chosen_color, 1) }, laserAimColor.alphaKeys); }
// Use this for initialization void Start() { cvar_watcher = FindObjectOfType <Server_watcher>(); Darkness = GameObject.Find("Darkness"); fade_view = GameObject.Find("Fade_view"); if (!cvar_watcher.losVision) { Destroy(Darkness); Destroy(fade_view); Destroy(this); return; } fade_view_left = fade_view.transform.Find("Fade_view_leaf_left"); fade_view_right = fade_view.transform.Find("Fade_view_leaf_right"); controller = GetComponent <Player_controller>(); if (!controller.isLocalPlayer) { Destroy(this); return; } body = GetComponent <Body_generic>(); viewMesh = new Mesh(); viewMesh.name = "View Mesh"; viewMeshFilter.mesh = viewMesh; sprite_orient = GetComponent <Player_controller>().sprite_orient; fade_view.transform.localScale = new Vector2(body.viewRadius, body.viewRadius); fade_view_left.localRotation = Quaternion.Euler(0, 0, body.viewAngle / 2); fade_view_right.localRotation = Quaternion.Euler(0, 0, -body.viewAngle / 2); //StartCoroutine("FindTargetsWithDelay", 0.2f); }
//This function will detect character collision and calculate damage //Return 1: keep the projectile going //Return 0: this object shouldn't be impacted //Return -1: this projectile is stopped by character public int impact_character(Body_hitbox_generic hit_box, Vector2 hit_point) { Body_generic body = hit_box.body; if (body.gameObject == activator) { return(-1); } if (local) { float heat_dmg = 0; float angle = Mathf.Atan2(aimdir.y, aimdir.x) * 180 / Mathf.PI; if (activator.GetComponent <Body_generic>().dmg_tags.Contains(body.tag)) { heat_dmg = Damage(); } Vector2 force = CONSTANTS.DAMAGE_FORCE_MULTIPLIER * aimdir.normalized * heat_dmg / 20; //If Client authoritates laser if (activator.GetComponent <Body_generic>().isPlayer&& !activator.GetComponent <Body_generic>().isServer) { activator.GetComponent <Player_controller>().add_to_shot_list(body.gameObject, heat_dmg, hit_point, force.magnitude, CONSTANTS.seed_float_to_short(angle, 360), false, 1); body.GetComponent <Rigidbody2D>().AddForceAtPosition(force, hit_point); } else//Server client || npc authoritates laser { if (heat_dmg > 0) { body.damage(activator, force, dmg_physics: CONSTANTS.heat_to_physics(heat_dmg), dmg_thermal: heat_dmg, headshot: false); if (body.isPlayer && !body.hasAuthority)//Non-server client { body.request_bleed(hit_point, angle, false); body.Rpc_add_force(force); } else//Host or npc { body.request_bleed(hit_point, angle, false); body.GetComponent <Rigidbody2D>().AddForceAtPosition(force, hit_point); } } //Friendly fire, just force else { if (body.isPlayer && !body.hasAuthority)//Non-server client { body.Rpc_add_force(force); } else//Host or npc { body.GetComponent <Rigidbody2D>().AddForceAtPosition(force, hit_point); } } } } return(-1); }
string print_debug_info(GameObject obj) { if (obj == null) { return("This object is NULL"); } string info = ""; Equipable_generic item = obj.GetComponent <Equipable_generic>(); Body_generic body = obj.GetComponent <Body_generic>(); if (item != null) { info += "Item: " + obj.name + "\nUser: "******"\nFaded: " + item.fade + "\n"; Gun_generic gun = obj.GetComponent <Gun_generic>(); Ammo_generic ammo = obj.GetComponent <Ammo_generic>(); if (gun != null) { info += "Ammo: " + gun.ammo + "\n"; } else if (ammo != null) { info += "Amount: " + ammo.amount + "\n"; } } else if (body != null) { if (body.isPlayer) { info += "\nPlayer: " + obj.name; info += "\nEquiped: " + obj.GetComponent <Player_controller>().equiped_item; } else { info += "\nNPC: " + obj.name; info += "\nEquiped: " + obj.GetComponent <AI_generic>().equiped_item; } info += "\nHealth: " + body.health + "/" + body.max_health; info += "\nReload * " + body.reload_multiplier; info += "\nStress # " + body.stress_resistent; info += "\nStrength: " + body.strength; info += "\nSpeed: " + body.speed_run; info += "\nAim: " + body.aim_suppress; if (isServer) { info += "\nServer-sided Var---------------"; info += "\nExperience # " + body.experience; info += "\nSPs # " + body.skill_points; info += "\nPhysical Resiliance # " + body.physical_resilience; } } return(info); }
//This function will detect object collision //projectile will stop no matter what public void impact_object(GameObject obj, Vector2 hit_point) { if (obj.GetComponent <Rigidbody2D>() != null) { if (local)//If rigidbody, Exert force { obj.GetComponent <Rigidbody2D>().AddForceAtPosition(aimdir * speed * mass / 2, hit_point); } } if (obj.tag == "structure")//Structure { Body_generic activator_body = activator.GetComponent <Body_generic>(); if (local && (activator == null || (activator_body.dmg_tags.Contains(obj.tag) && activator.layer != obj.layer)))// { float angle = Mathf.Atan2(aimdir.y, aimdir.x) * 180 / Mathf.PI; //If Client authoritates bullet if (activator != null && activator_body.isPlayer && !activator_body.isServer) { activator_body.player_controller.add_to_shot_list(obj, Damage(), hit_point, 0, CONSTANTS.seed_float_to_short(angle, 360), false, 0); } else { obj.GetComponent <Structure_generic>().health -= Damage(); } } } if (spark != null && !isDedicated) { float angle = Mathf.Atan2(aimdir.y, aimdir.x) * 180 / Mathf.PI; Instantiate(spark, hit_point, Quaternion.Euler(0, 0, angle)); } transform.position = hit_point; /* * if (local) * { * * } * else * { * bulletRB.position = hit_point;//Avoid synctransform call * } */ speed = 0; time_of_collision = Time.realtimeSinceStartup; }
//better use the referenced user, to prevent misusing the old user void colorCode_laserAim(GameObject code_ref_obj) { if (code_ref_obj == null || laserAimSource == null || isDedicated()) { return; } //Laser Aim Body_generic user_body = code_ref_obj.GetComponent <Body_generic>(); if (!user_body.cvar_watcher.cl_preroundStarted) { user_body.cvar_watcher.onClientReady.Add(OnClientReady); return; } Sample_color(code_ref_obj); }
//This function will detect character collision and calculate damage //Return 1: keep the projectile going //Return 0: this object shouldn't be impacted //Return -1: this projectile is stopped by character public int impact_character(Body_hitbox_generic hit_box, Vector2 hit_point) { Vector2 force = CONSTANTS.DAMAGE_FORCE_MULTIPLIER * aimdir * speed * mass / 2; Body_generic body = hit_box.body; if (body.isPlayer && !body.hasAuthority)//client player { body.Rpc_add_force(force); } else//host player & npc { body.GetComponent <Rigidbody2D>().AddForceAtPosition(force, hit_point); } if (activator.GetComponent <Body_generic>().dmg_tags.Contains(hit_box.tag)) { body.damage(activator, force: force, dmg_physics: Damage(), headshot: false); } return(-1); }
// Use this for initialization void Start() { Vector2 epicenter = PS.transform.position; AudioSource audio = GetComponent <AudioSource>(); audio.pitch = Time.timeScale; //Damage if (Client_watcher.Singleton.isServer) { //Stun if (isFlashBang) { float stun_radius = light.range * 0.8f; Collider2D[] stun_colliders = Physics2D.OverlapCircleAll(epicenter, stun_radius, hit_fltr); for (int i = 0; i < stun_colliders.Length; i++) { RaycastHit2D hit = Physics2D.Linecast(epicenter, stun_colliders[i].transform.position, block_fltr); if (hit.collider == null && stun_colliders[i].GetComponent <Body_hitbox_generic>() != null) { GameObject char_main = stun_colliders[i].GetComponent <Body_hitbox_generic>().body.gameObject; float dist = Vector2.Distance(char_main.transform.position, epicenter); if (dist <= stun_radius) { float stun_ratio = (1 - dist / stun_radius) * thermal / 10000; char_main.GetComponent <Body_generic>().Rpc_stunned_screen(stun_ratio); } } } } //Hurt Collider2D[] colliders = Physics2D.OverlapCircleAll(epicenter, radius, hit_fltr); Body_generic activator_body = activator.GetComponent <Body_generic>(); for (int i = 0; i < colliders.Length; i++) { RaycastHit2D hit = Physics2D.Linecast(epicenter, colliders[i].transform.position, block_fltr); if (hit.collider == null) { float dist = Vector2.Distance(colliders[i].transform.position, epicenter); if (dist <= radius) { //force Vector2 force = CONSTANTS.DAMAGE_FORCE_MULTIPLIER * ((Vector2)colliders[i].transform.position - epicenter).normalized * (1 - dist / radius) * power * 6; GameObject char_main; if (colliders[i].GetComponent <Body_hitbox_generic>() != null && colliders[i].tag != "headsquirt") { char_main = colliders[i].GetComponent <Body_hitbox_generic>().body.gameObject; } else { char_main = colliders[i].gameObject; } //damage float dmg_physical = (1 - dist / radius) * power / 3; float dmg_thermal = (1 - dist / radius) * thermal / 3; RaycastHit2D[] hits = Physics2D.LinecastAll(epicenter, char_main.transform.position, hit_fltr); for (int j = 0; j < hits.Length - 1; j++) { if (hits[j].collider.gameObject.tag == "structure" && hits[j].collider.gameObject != char_main)//There are (other) structure blocking { dmg_physical = 0; break; } else if (hits[j].collider.GetComponent <Body_generic>() != null) { dmg_physical -= hits[j].collider.GetComponent <Body_generic>().tissue_dense; } } if (dmg_physical < 0) { dmg_physical = 0; } if (dmg_thermal < 0) { dmg_thermal = 0; } //Characters if (char_main.GetComponent <Body_generic>() != null) { char_main.GetComponent <Body_generic>().damage(activator, force: force, dmg_physics: dmg_physical, dmg_thermal: dmg_thermal); } //Structures else if (char_main.GetComponent <Structure_generic>() != null) { if (char_main.layer == activator.layer)//Ally structure { continue; } else { char_main.GetComponent <Structure_generic>().health -= dmg_physical; } } /* * else if (char_main.GetComponent<Prop_generic>() != null) * { * char_main.GetComponent<Prop_generic>().damage(activator, force: force, dmg_physics: dmg_physical, dmg_thermal: dmg_thermal); * } * else if (char_main.GetComponent<Bullseye_generic>() != null) * { * char_main.GetComponent<Bullseye_generic>().damage(activator, dmg_physics: dmg_physical, dmg_thermal: dmg_thermal); * } */ if (char_main.GetComponent <Body_generic>() != null && char_main.GetComponent <Body_generic>().isPlayer) { char_main.GetComponent <Body_generic>().Rpc_add_force(force); } else if (char_main.GetComponent <Rigidbody2D>() != null)//host player & server object { char_main.GetComponent <Rigidbody2D>().AddForce(force); } } } } } //Cosmetic if (!Server_watcher.Singleton.isDedicated()) { if (isMeshEffect)//mesh explosion; frag { mesh = new Mesh(); mesh_fltr = GetComponent <MeshFilter>(); mesh_renderer = GetComponent <MeshRenderer>(); mesh_fltr.mesh = mesh; mesh_renderer.sortingLayerName = "Flame"; mesh_color = mesh_renderer.sharedMaterial.color; if (material != null) { mesh_renderer.sharedMaterial = material; } time_to_destroyWind = Time.time + windLife; } else//no mesh no particle, flashbang { Destroy(GetComponent <MeshFilter>()); Destroy(GetComponent <MeshRenderer>()); } PS.transform.position = new Vector3(epicenter.x, epicenter.y, -2.5f); if (countParticleLife) { time_to_destroy = Time.time + PS.main.startLifetime.constant; } else { time_to_destroy = Time.time + GetComponent <AudioSource>().clip.length; } light_intensity = light.intensity; if (sprite != null) { sprite_alpha = sprite.color.a; } if (exp_decal != null) { FindObjectOfType <Decal_manager>().add_decal(exp_decal, epicenter, radius / 7, 10); } } else { Destroy(gameObject); } }
// Use this for initialization void Start() { //Server need this link to assign purchased weapons body = GetComponent <Body_generic>(); cvar_watcher = FindObjectOfType <Server_watcher>(); main_camera = Camera.main; controller = GetComponent <Player_controller>(); if (!GetComponent <Player_controller>().isLocalPlayer) { enabled = false; return; } else//Continues as local player { if (cvar_watcher.map_type == CONSTANTS.MAP_TYPE.PVP) { //Menu menu = Instantiate(menu_prefab).GetComponent <Menu_watcher>(); menu.body = body; menu.buffer_inventory_size = body.inventory_size; if (body.isBot()) { menu.robot_menu.SetActive(true); menu.robot_submenu[controller.character_subtype].SetActive(true); menu.human_menu.SetActive(false); menu.zombie_menu.SetActive(false); menu.purchase_buttons = menu.purchase_buttons_robot; menu.upgrade_buttons = menu.upgrade_buttons_robot; menu.purchasables = cvar_watcher.purchases_robot; } else if (body.isHuman()) { menu.robot_menu.SetActive(false); menu.human_menu.SetActive(true); menu.human_submenu[controller.character_subtype].SetActive(true); menu.zombie_menu.SetActive(false); menu.purchase_buttons = menu.purchase_buttons_human; menu.upgrade_buttons = menu.upgrade_buttons_human; menu.purchasables = cvar_watcher.purchases_human; } else if (body.isZombie()) { menu.robot_menu.SetActive(false); menu.human_menu.SetActive(false); menu.zombie_menu.SetActive(true); menu.zombie_submenu[controller.character_subtype].SetActive(true); menu.purchase_buttons = menu.purchase_buttons_human; menu.upgrade_buttons = menu.upgrade_buttons_zombie; menu.purchasables = cvar_watcher.purchases_zombie; } menu.purchase_buttons_robot = null; menu.purchase_buttons_human = null; } cursor = Instantiate(cursor); cursor_anim = cursor.GetComponent <Animator>(); cursor_l = cursor.transform.Find("cursor_l"); cursor_r = cursor.transform.Find("cursor_r"); cursor_u = cursor.transform.Find("cursor_u"); cursor_d = cursor.transform.Find("cursor_d"); cursor_marker_sw = cursor.transform.Find("hit_marker_sw"); cursor_marker_se = cursor.transform.Find("hit_marker_se"); cursor_marker_nw = cursor.transform.Find("hit_marker_nw"); cursor_marker_ne = cursor.transform.Find("hit_marker_ne"); } GetComponent <Body_generic>().OnDamaged = damaged_screen; //HUD set-up //HUD_camera = Instantiate(HUD_camera, Vector2.zero, Quaternion.identity); //HUD_generic hud_generic = HUD_camera.GetComponent<HUD_generic>(); //HUD_camera.transform.parent = main_camera.transform; //HUD_camera.transform.position = main_camera.transform.position; HUD = Instantiate(HUD); HUD_generic hud_generic = HUD.GetComponent <HUD_generic>(); ammo_field = hud_generic.AmmoField; icon_field = hud_generic.ItemIcon; icon_field_anim = icon_field.GetComponent <Animator>(); overlay = hud_generic.Overlay; //ammo_field.GetComponent<MeshRenderer>().sortingLayerName = "HUD"; //Disable unwanted screen filters if (body.character_type == Body_generic.Character_type.Robot) { //Destroy(main_camera.GetComponent<ColorCorrectionCurves>()); Destroy(main_camera.GetComponent <BlurOptimized>()); //Destroy(main_camera.GetComponent<ContrastStretch>()); } else if (body.character_type == Body_generic.Character_type.Human) { Destroy(main_camera.GetComponent <NoiseAndGrain>()); Destroy(main_camera.GetComponent <VignetteAndChromaticAberration>()); } else if (body.character_type == Body_generic.Character_type.Zombie) { Destroy(main_camera.GetComponent <NoiseAndGrain>()); Destroy(main_camera.GetComponent <VignetteAndChromaticAberration>()); } }
//Server pull trigger public void Pull_trigger(Body_generic body)//AI_generic ai) { if ((ammo <= 0) || (Time.time <= time_to_fire || (body.isPlayer && is_shoot_inside_wall()))) { return; } body.reloading = false; body.anim_reload(false); time_to_fire = Time.time + 1 / rate_of_fire; //Obtain bullet initial position and direction short firepoint_x = (short)(fire_point.position.x * CONSTANTS.SYNC_POS_MUTIPLIER); short firepoint_y = (short)(fire_point.position.y * CONSTANTS.SYNC_POS_MUTIPLIER); short aim_angle_short = get_aim_dir_short(); float aim_angle_float = get_aim_dir_float(); //Calculate additional bullet output due to low fps int fps_stack = (int)Mathf.Clamp(Time.deltaTime / (1.0f / rate_of_fire), 1, CONSTANTS.MAX_ROF_FRAMERATE_OVERLOAD); fps_stack = Mathf.Min(fps_stack, ammo); ammo -= (ushort)fps_stack; body.bodyRB.AddForce(-get_aim_vec().normalized *recoil *fps_stack); //client_player.shake_screen(shake_extent, transform.rotation.eulerAngles.z+180); /* * if ((ammo <= 0) || (Time.time <= time_to_fire)) * { * return; * } * * * short firepoint_x = (short)(fire_point.position.x * CONSTANTS.SYNC_POS_MUTIPLIER); * short firepoint_y = (short)(fire_point.position.y * CONSTANTS.SYNC_POS_MUTIPLIER); * short aim_angle_short = get_aim_dir_short(); * float aim_angle_float = get_aim_dir_float(); * * ammo -= 1; * time_to_fire = Time.time + 1 / rate_of_fire; * body.bodyRB.AddForce(-get_aim_vec().normalized * recoil);//ai.GetComponent<Rigidbody2D>().AddForce(-get_aim_vec().normalized * recoil); * body.reloading = false;//ai.reloading = false; */ if (burst_shots == 1) { if (fps_stack <= 1) { short aim_dir_bias = get_bullet_seed_single(aim_angle_float, firecone_angle); //Local shooting shoot(body.gameObject, firepoint_x, firepoint_y, aim_dir_bias, null); //Others shooting if (body.isServer && !Local_precomputation) { server_shoot(body.gameObject, firepoint_x, firepoint_y, aim_dir_bias, null, ammo <= 0); } else if (body.isPlayer && !Local_precomputation) { body.GetComponent <Player_controller>().Cmd_request_shoot_optimized_single(firepoint_x, firepoint_y, aim_dir_bias, ammo <= 0); } } else { sbyte[] blt_dir = get_bullet_seed_single_incremental(firecone_angle, body.aim_suppress, fps_stack); //Local shooting shoot(body.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir); //Others shooting if (body.isServer && !Local_precomputation) { server_shoot(body.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir, ammo <= 0); } else if (!Local_precomputation) { body.GetComponent <Player_controller>().Cmd_request_shoot_optimized(firepoint_x, firepoint_y, aim_angle_short, blt_dir, ammo <= 0); } } /* * short aim_dir_bias = get_bullet_seed_single(get_aim_dir_float(), firecone_angle); * //Local shooting * shoot(ai.gameObject, firepoint_x, firepoint_y, aim_dir_bias, null); * //Others shooting * if (!Local_precomputation) * { * server_shoot(ai.gameObject, firepoint_x, firepoint_y, aim_dir_bias, null, ammo <= 0); * } */ } else if (burst_shots >= 2) { sbyte[] blt_dir = get_bullet_seed(firecone_angle, fps_stack); //Local shooting shoot(body.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir); //Others shooting if (body.isServer && !Local_precomputation) { server_shoot(body.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir, ammo <= 0); } else if (!Local_precomputation) { body.GetComponent <Player_controller>().Cmd_request_shoot_optimized(firepoint_x, firepoint_y, aim_angle_short, blt_dir, ammo <= 0); } /* * sbyte[] blt_dir = get_bullet_seed(firecone_angle); * //Local shooting * shoot(ai.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir); * //Others shooting * if (!Local_precomputation) * { * server_shoot(ai.gameObject, firepoint_x, firepoint_y, aim_angle_short, blt_dir, ammo <= 0); * } */ } //--------------------------------------------------- firecone_angle = Mathf.Clamp(firecone_angle + fps_stack * (body.aim_suppress) * accuracy / bias_factor, 0, accuracy); }
//This function will detect character collision and calculate damage //Return 1: keep the projectile going //Return 0: this object shouldn't be impacted //Return -1: this projectile is stopped by character public int impact_character(Body_hitbox_generic hit_box, Vector2 hit_point) { Body_generic body = hit_box.body; //if this box has been hit OR bullet hits the shooter if (collidedlist.Contains(body.gameObject.GetInstanceID()) || body.gameObject == activator) {// if previously hit or hit self return(0); } //Approximate fps-independent speed in the middle hit target float real_speed = Mathf.Lerp(speed, (speed - delta_time * CONSTANTS.FPS_SCALE * speed_damp), Vector2.Distance(transform.position, hit_point) / (speed * delta_time * CONSTANTS.PROJECTILE_SPEED_MULTI)); if (local) { float absorbed_speed;//For force calculation if (body.tissue_dense < real_speed) { absorbed_speed = body.tissue_dense; } else { absorbed_speed = real_speed; } if (real_speed > speed_min) { bool isHeadShot = false; float angle = Mathf.Atan2(aimdir.y, aimdir.x) * 180 / Mathf.PI; float damage = 0; Vector2 force = CONSTANTS.DAMAGE_FORCE_MULTIPLIER * aimdir * absorbed_speed * mass / 2; IDamageActivator Activator = null; bool allowDamage = false; if (activator == null) { allowDamage = true; } else { Activator = activator.GetComponent <IDamageActivator>(); if (Activator.canDamage(body)) { allowDamage = true; } } //Examine if can damage, Can hit body/headbox if (allowDamage) { //headshot detection if (hit_box.gameObject.tag == "headsquirt")//hitbox is headbox { isHeadShot = true; } else//hitbox is bodybox, examine further if hit headbox { RaycastHit2D[] hit_head = Physics2D.RaycastAll(hit_point, aimdir * real_speed, body.size * 2, hit_head_fltr); foreach (RaycastHit2D hitx in hit_head) { //hit normal bullet impace fx if (hitx.collider.tag == "headsquirt" && hitx.collider.GetComponent <Body_hitbox_generic>().body.gameObject == body.gameObject)//if sub-hitbox's parent is current body box { isHeadShot = true; break; } } } damage = Damage(); } if (Activator != null) { Activator.OnHitCharacter(body, damage, hit_point, force, isHeadShot, DamageType.Physical); } body.OnDamagedBy(Activator, damage, hit_point, force, isHeadShot, DamageType.Physical); //if (activator == null || activator.GetComponent<Body_generic>().dmg_tags.Contains(body.tag)) //{ // //headshot detection // if (hit_box.gameObject.tag == "headsquirt")//hitbox is headbox // { // isHeadShot = true; // } // else//hitbox is bodybox, examine further if hit headbox // { // RaycastHit2D[] hit_head = Physics2D.RaycastAll(hit_point, aimdir * real_speed, body.size * 2, hit_head_fltr); // foreach (RaycastHit2D hitx in hit_head) // { // //hit normal bullet impace fx // if (hitx.collider.tag == "headsquirt" && hitx.collider.GetComponent<Body_hitbox_generic>().body.gameObject == body.gameObject)//if sub-hitbox's parent is current body box // { // isHeadShot = true; // break; // } // } // } // damage = Damage(); //} //if(activator == null) //{ //Body_generic activator_body = activator.GetComponent<Body_generic>(); //if (activator_body.isLocalPlayer) //{ // activator_body.player_controller.hit_mark(); //} ////If non-host local hit //if (activator != null && activator_body.isPlayer && !activator_body.isServer) //{ // activator.GetComponent<Player_controller>().add_to_shot_list(body.gameObject, damage, hit_point, force.magnitude, CONSTANTS.seed_float_to_short(angle, 360), isHeadShot, 0); // body.GetComponent<Rigidbody2D>().AddForceAtPosition(force, hit_point); //} //else//Server client || npc authoritates bullet //{ // //Cause damage and bleed and force // if (damage > 0) // { // body.damage(activator, force: force, dmg_physics: mass * real_speed * real_speed / 10000, headshot: isHeadShot); // if (body.isPlayer && !body.hasAuthority)//Pushing non-server client // { // //body.Rpc_bleed_n_force(hit_point, force, isHeadShot); // body.request_bleed(hit_point, angle, isHeadShot); // body.Rpc_add_force(force); // } // else//Pushing host or npc // { // body.request_bleed(hit_point, angle, isHeadShot); // body.GetComponent<Rigidbody2D>().AddForceAtPosition(force, hit_point); // } // } // //Friendly fire, just force // else // { // if (body.isPlayer && !body.hasAuthority)//Non-server client // { // body.Rpc_add_force(force); // } // else//Host or npc // { // body.GetComponent<Rigidbody2D>().AddForceAtPosition(force, hit_point); // } // } //} //} } } speed = real_speed - body.tissue_dense; if (speed < speed_min) { speed = 0; /* * if (local) * { * transform.position = hit_point; * } * else * { * bulletRB.position = hit_point; * } */ time_of_collision = Time.realtimeSinceStartup; return(-1); } collidedlist.Add(body.gameObject.GetInstanceID()); return(1); }
//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); } }
/// <summary> /// Check if bullet has authority: NPC & server player only authoritative on server; Client only authoritative on local /// </summary> /// <param name="user_body"></param> /// <returns></returns> bool local_player_protocol(Body_generic user_body) { return(user_body.isLocalPlayer || (user_body.isServer && !user_body.isPlayer)); }
// Update is called once per frame void Update() { if (!isLocalPlayer) { return; } //Camera mousepos = new Vector2(mainCam.ScreenToWorldPoint(Input.mousePosition).x, mainCam.ScreenToWorldPoint(Input.mousePosition).y); main_camera.position = new Vector3(transform.position.x, transform.position.y, main_camera.position.z); if (!msg_watcher.isEditingMsg) { if (Input.GetKey(zoomout)) { mainCam.orthographicSize *= 1.03f; } if (Input.GetKey(zoomin)) { mainCam.orthographicSize /= 1.03f; } } if (Input.GetKeyDown(rotate_cam)) { cam_vec = mousepos - (Vector2)transform.position; } else if (Input.GetKey(rotate_cam)) { Vector2 offset_vec = (mousepos - (Vector2)transform.position); float offset = cam_angle - Mathf.Atan2((offset_vec).y, (offset_vec).x) * 180 / Mathf.PI + Mathf.Atan2((cam_vec).y, (cam_vec).x) * 180 / Mathf.PI; cam_angle = offset; main_camera.rotation = Quaternion.Euler(0, 0, offset); } if (mainCam.orthographicSize > max_view) { mainCam.orthographicSize = max_view; } else if (mainCam.orthographicSize < min_view) { mainCam.orthographicSize = min_view; } cam3D.localPosition = new Vector3(cam3D.localPosition.x, cam3D.localPosition.y, -Mathf.Lerp(CONSTANTS.CAM3D_MIN_Z, CONSTANTS.CAM3D_MAX_Z, (mainCam.orthographicSize - CONSTANTS.CAM_MIN_VIEW) / (CONSTANTS.CAM_MAX_VIEW - CONSTANTS.CAM_MIN_VIEW))); if (msg_watcher.isEditingMsg) { return; } //Timescale if (Input.GetKeyDown(slowdownTime) && FindObjectsOfType <Player_generic>().Length <= 1) { Cmd_slowTime(); } else if (Input.GetKeyDown(resetTime) && FindObjectsOfType <Player_generic>().Length <= 1) { Cmd_normalTime(); } //Lighting if (Input.GetKeyDown(toggle_light)) { if (light.enabled) { light.enabled = false; light_zombie.enabled = false; light_human.enabled = false; light_robot.enabled = false; } else { light.enabled = true; light_zombie.enabled = true; light_human.enabled = true; light_robot.enabled = true; } } //Debug if (Input.GetKeyDown(debug)) { Collider2D check = Physics2D.OverlapCircle(transform.position, 1, debug_mask); if (check != null && check.tag != "structure") { GameObject the_object = check.gameObject; if (check.GetComponent <Body_hitbox_generic>() != null) { the_object = check.GetComponent <Body_hitbox_generic>().body.gameObject; } debug_check_object(the_object); } } else if (Input.GetKeyDown(debug_clear)) { clear_debug_info(); } else if (Input.GetKeyDown(debug_toggle)) { if (debug_info.enabled) { debug_info.enabled = false; Client_watcher.Singleton.GetComponent <FPSDisplay>().enabled = false; } else { debug_info.enabled = true; Client_watcher.Singleton.GetComponent <FPSDisplay>().enabled = true; } } //Movement if (track_body == null) { float move_angle = 0; float move_force = 1; Vector2 move_dir = Vector2.zero; if (Input.GetKey(FastTravel)) { move_force = Speed_fasttravel; } else { move_force = Speed_travel; } if (Input.GetKey(MoveUp)) { move_dir.y = 1; } else if (Input.GetKey(MoveDown)) { move_dir.y = -1; } else { move_dir.y = 0; } if (Input.GetKey(MoveLeft)) { move_dir.x = -1; } else if (Input.GetKey(MoveRight)) { move_dir.x = 1; } else { move_dir.x = 0; } if (move_dir.magnitude != 0) { move_angle = Mathf.Atan2(move_dir.y, move_dir.x) * 180 / Mathf.PI; move_angle += mainCam.transform.rotation.eulerAngles.z; move_dir = new Vector2(Mathf.Cos(move_angle * Mathf.PI / 180), Mathf.Sin(move_angle * Mathf.PI / 180)); } obRB.AddForce(move_dir.normalized * move_force * Time.unscaledDeltaTime / (50 * Time.fixedDeltaTime)); if (Input.GetKeyDown(Stop)) { obRB.velocity = Vector2.zero; } } else { interpolator.interpolate(track_body.transform.position); //obRB.position = track_body.transform.position; health_bar.ratio = track_body.health / track_body.max_health; } //Switch characters if ((Input.GetKeyDown(switch_character_next) || Input.GetKeyDown(switch_character_prev) || Input.GetKeyDown(switch_selected)) && characters != null && characters.Length > 0) { if (Input.GetKeyDown(switch_selected)) { Collider2D selected = Physics2D.OverlapCircle(transform.position, 1, character_mask); if (selected != null && selected.tag != "structure") { Body_generic selected_character = selected.GetComponent <Body_hitbox_generic>().body; for (int i = 0; i < characters.Length; i++) { if (characters[i] == selected_character) { characters_index = i; break; } } track_body = selected_character; health_bar.gameObject.SetActive(true); isFreeMode = false; } } else if (isFreeMode) { isFreeMode = false; track_body = characters[characters_index]; health_bar.gameObject.SetActive(true); } else if (Input.GetKeyDown(switch_character_next)) { characters_index++; if (characters_index == characters.Length) { characters_index = 0; } track_body = characters[characters_index]; } else if (Input.GetKeyDown(switch_character_prev)) { characters_index--; if (characters_index < 0) { characters_index = characters.Length - 1; } track_body = characters[characters_index]; } } else if (Input.GetKeyDown(switch_free)) { if (!isFreeMode) { isFreeMode = true; track_body = null; health_bar.gameObject.SetActive(false); } } }
/// <summary> /// Gurranteed to be local /// </summary> /// <param name="activator"></param> /// <param name="fire_point"></param> /// <param name="blt_dir"></param> /// <param name="hasAuthority"></param> /// <param name="lag_prediction"></param> GameObject[] fire_tesla_init(GameObject activator, Vector2 fire_point, float blt_dir, float max_bounce_range, LayerMask hit_fltr, LayerMask obstacle_fltr) { Vector2 spread_origin = fire_point; Vector2 aimdir = (new Vector2(Mathf.Cos(blt_dir * Mathf.PI / 180), Mathf.Sin(blt_dir * Mathf.PI / 180))).normalized; Body_generic activator_body = activator.GetComponent <Body_generic>(); Player_controller activator_controller = activator.GetComponent <Player_controller>(); Body_generic victim_body = null; RaycastHit2D hit = Physics2D.Raycast(transform.position, aimdir, blt_speed * CONSTANTS.VOLT_DIST_RATIO / 2, hit_fltr + obstacle_fltr); List <GameObject> collidedlist = new List <GameObject>(); Body_hitbox_generic hitbox; float volts_left = blt_speed; int number_streams = 0; if (hit) { hitbox = hit.collider.GetComponent <Body_hitbox_generic>(); if (hitbox != null) //If hit body, Damage and spread { volts_left = (1 - (Vector2.Distance(hit.point, transform.position) / (blt_speed * CONSTANTS.VOLT_DIST_RATIO))) * blt_speed; collidedlist.Add(hitbox.body.gameObject); number_streams = Mathf.Max(1, (int)(volts_left / blt_speed_min)); spread_origin = hit.point; } } if (number_streams == 0) { //Send trail paths spawn_muzzle(); if (activator_controller != null) { activator_body.Cmd_spawn_tesla_muzzle(gameObject); } else { activator_body.Rpc_spawn_tesla_muzzle(gameObject); } return(null); } List <GameObject>[] stream_path = new List <GameObject> [number_streams]; List <Tesla_generic.teslaNode> spread_list = new List <Tesla_generic.teslaNode>(); Tesla_generic.teslaNode initial_node = new Tesla_generic.teslaNode(); initial_node.target = hit.collider.gameObject; initial_node.volts_left = volts_left; initial_node.stream_idxes = new int[number_streams]; collidedlist.Add(hit.collider.gameObject); for (int i = 0; i < number_streams; i++) { initial_node.stream_idxes[i] = i; } //Debug.LogError("distance: "+ Vector2.Distance(hit.point, transform.position) + "; volt left: "+volts_left+ "; number streams: "+number_streams); spread_list.Add(initial_node); int path_size = 0; //while there are stem that is branching out while (spread_list.Count > 0)//Each step { //Debug.LogError("step: "+spread_list.Count); List <Tesla_generic.teslaNode> spread_temp = new List <Tesla_generic.teslaNode>(); //For each of the stem for (int i = 0; i < spread_list.Count; i++) { List <Tesla_generic.teslaNode> current_spread_temp = new List <Tesla_generic.teslaNode>(); int j; Tesla_generic.teslaNode node = spread_list[i]; victim_body = node.target.GetComponent <Body_generic>(); if (victim_body == null)//structure doesnt take damage from tesla { continue; } if (activator_body.isServer) { if (node.target.layer != activator.layer)//Only if damaging opposite team will bleed { victim_body.request_bleed(victim_body.transform.position, 0, false); } victim_body.damage(activator, Vector2.zero, dmg_electric: node.volts_left / 30); } else { activator_controller.add_to_shot_list(victim_body.gameObject, node.volts_left / 30, victim_body.transform.position, 0, 0, false, 2); } if (activator_body.isLocalPlayer) { activator_controller.hit_mark(); } spread_origin = node.target.transform.position; //Debug.LogError("From node: "+node.target + "; volt: "+node.volts_left); //Mark all the stream with its index for (j = 0; j < node.stream_idxes.Length; j++) { if (stream_path[node.stream_idxes[j]] == null) { stream_path[node.stream_idxes[j]] = new List <GameObject>(); } stream_path[node.stream_idxes[j]].Add(node.target); path_size++; //Debug.LogError("add: " + node.target); } //overlap circle Collider2D[] victims = Physics2D.OverlapCircleAll(spread_origin, Mathf.Min(node.volts_left * CONSTANTS.VOLT_DIST_RATIO, radius), hit_fltr); //Debug.LogError("hit count: " + victims.Length); if (victims.Length == 0) { continue; } //Sort circle victims = victims.OrderBy(o => Vector2.Distance(o.transform.position, spread_origin)).ToArray(); //Pointer j = 0; //Compute distance for the next stem, put on dist_to_parent float volt = node.volts_left; float total_volt_to_parent = 0; Tesla_generic.teslaNode next_node = new Tesla_generic.teslaNode(); next_node.target = victims[j].gameObject; next_node.volt_to_parent = Vector2.Distance(victims[j].transform.position, spread_origin) / CONSTANTS.VOLT_DIST_RATIO; //While this stem has voltage && can reach next stem int hits = 0; while (volt > blt_speed_min + next_node.volt_to_parent && hits <= CONSTANTS.TESLA_MAX_SPLIT) { //If the next stemmed object isnt on collided list if (!collidedlist.Contains(next_node.target) && !Physics2D.Linecast(spread_origin, next_node.target.transform.position, obstacle_fltr)) { //subtract copy of dist/volt_ratio\ volt -= next_node.volt_to_parent + blt_speed_min; total_volt_to_parent += next_node.volt_to_parent; //Copy the stem onto a spread_temp list spread_temp.Add(next_node); current_spread_temp.Add(next_node); hits++; //Put the stemmed object on collided list collidedlist.Add(next_node.target); //Debug.LogError("spread to: " + next_node.target + "; volt distance: " + next_node.volt_to_parent); } //Increment pointer j++; if (j >= victims.Length) { break; } next_node = new Tesla_generic.teslaNode(); //take the next stem on the sorted list next_node.target = victims[j].gameObject; //Compute distance for the next stem next_node.volt_to_parent = Vector2.Distance(victims[j].transform.position, spread_origin) / CONSTANTS.VOLT_DIST_RATIO; } //Pointer current_idx = 0 int current_idx = 0; //For each on the spread_temp list for (int k = 0; k < current_spread_temp.Count; k++) { next_node = current_spread_temp[k]; //stem volt = (1 - dist_to_parent / volt_of_current_stem) * volt_of_current_stem if (current_spread_temp.Count == 1) { next_node.volts_left = volt; } else { next_node.volts_left = ((total_volt_to_parent - next_node.volt_to_parent) / (current_spread_temp.Count - 1)) * volt / total_volt_to_parent; } //Debug.LogError("spread to: " + next_node.target + "; volt distance: " + next_node.volt_to_parent); //Debug.LogError("volts total: "+node.volts_left+"; total parent: "+ total_volt_to_parent + "; this: "+ next_node.volts_left+ "; volt to parent: "+ next_node.volt_to_parent); //Initialize volt / minimum for the stream idxes if (next_node.volts_left <= 0) { current_spread_temp.RemoveAt(k); k--; continue; } next_node.stream_idxes = new int[Mathf.Max(1, (int)(next_node.volts_left / blt_speed_min))]; //Must be at least one stream //For volt / minimum for (int y = 0; y < next_node.stream_idxes.Length; y++) { //stream_idxes[] = current_stream_idxes[k] next_node.stream_idxes[y] = node.stream_idxes[current_idx]; /* * try * { * * } * catch * { * Debug.LogError("bug!"); * Debug.LogError("next node volt: " + next_node.volts_left); * Debug.LogError("spread count: " + current_spread_temp.Count + "; number rays: " + next_node.stream_idxes.Length + "; number ray current: " + node.stream_idxes.Length + "; currect:" + current_idx); * } */ current_idx++; } } } spread_list.Clear(); spread_list = spread_temp; } if (stream_path.Length == 0) { return(null); } GameObject[] serialized_path = new GameObject[path_size + stream_path.Length]; int serialized_index = 0; for (int i = 0; i < stream_path.Length; i++) { for (int j = 0; j < stream_path[i].Count; j++) { serialized_path[serialized_index] = stream_path[i][j]; serialized_index++; } serialized_index++; } //Send trail paths if (activator_body.isPlayer && activator_body.hasAuthority) { activator_body.Cmd_send_tesla_path(serialized_path, gameObject); } else { activator_body.Rpc_send_tesla_path(serialized_path, gameObject); } return(serialized_path); }
// Use this for initialization void Start() { cvar_watcher = FindObjectOfType <Server_watcher>(); if (race == Body_generic.Character_type.Human) { cvar_watcher.team_human = this; } else if (race == Body_generic.Character_type.Robot) { cvar_watcher.team_robot = this; } else if (race == Body_generic.Character_type.Zombie) { cvar_watcher.team_zombie = this; } //set text if (text_counter != null) { text_counter.text = respawns_token.ToString(); } cvar_watcher.onClientReady.Add(OnClientReady); /* * //Find the player entity and register them to corresponding teams; If this fail to find players, players are going to find the team * //Let player/observer know of this entity, and making them check if this team members are spawn-ready * Player_controller[] players = FindObjectsOfType<Player_controller>(); * Debug.LogError("player number: "+players.Length); * for (int i = 0; i < players.Length; i++) * { * //Debug.LogError("found player: " + players[i].gameObject.name + " and his type: " + players[i].GetComponent<Body_generic>().character_type); * if (players[i].GetComponent<Body_generic>().character_type == race) * { * players[i].GetComponent<Body_generic>().team = this; * //Debug.LogError("player ready: "+ players[i].gameObject.name); * //body_ready++; * } * } */ //Server operations, spawn npc and assign team if (isServer) { alive = cvar_watcher.get_joined_character(race); if (alive <= 0) { enabled = false; } respawns_token = cvar_watcher.get_init_tickets(race); //Spawn npcs int number_to_spawn = alive - cvar_watcher.get_joined_player(race); //body_to_getReady = alive; //Rpc_tell_client_number(alive); for (int i = 0; i < number_to_spawn; i++) { int ran = UnityEngine.Random.Range(0, character.Length); GameObject npc = Instantiate(character[ran], transform.position, transform.rotation); //Debug.LogError("spawn: "+character[ran]); NetworkServer.Spawn(npc); Body_generic body_npc = npc.GetComponent <Body_generic>(); body_npc.cvar_watcher = cvar_watcher;//Needs to initialize on server side npc.GetComponent <Body_generic>().bodyRB = npc.GetComponent <Rigidbody2D>(); body_npc.OnRespawn = npc.GetComponent <AI_generic>().shopping; npc.GetComponent <AI_generic>().set_ai_condition(AI_generic.AI_condition.AGGRESSIVE); body_npc.team = this; //Make sure the upgrades are ready before shopping; if (body_npc.isHuman()) { body_npc.upgrades = cvar_watcher.upgrades_human; } else if (body_npc.isBot()) { body_npc.upgrades = cvar_watcher.upgrades_robot; } else if (body_npc.isZombie()) { body_npc.upgrades = cvar_watcher.upgrades_zombie; } npc.GetComponent <AI_generic>().body = body_npc; npc.GetComponent <AI_generic>().shopping(); //npc.GetComponent<AI_generic>().freeze_movement = true;//waiting for the preround to end npc.GetComponent <Body_generic>().character_cond = Body_generic.Character_condition.FROZEN; } } /* * if (isServer) * { * int percent = 100 / weapon.Length; * for (int i = 0; i < spawners.Length; i++) * { * spawners[i].spawn_limit = team_limit; * for(int j = 0; j < weapon.Length; j++) * { * spawners[i].equip_template.Add(new KeyValuePair<GameObject, int>(weapon[j], percent)); * } * spawners[i].npc_template.Add(new KeyValuePair<GameObject, int>(character, 100)); * } * } */ }