//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); }
//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); }
//This function define how the projectile predicts public void detect() { //Cheap prediction RaycastHit2D hit_approx = Physics2D.Raycast(transform.position, aimdir * speed, speed * delta_time * CONSTANTS.PROJECTILE_SPEED_MULTI, hit_fltr); if (hit_approx.collider == null) { return; } //If prediction hit, run detail raycast RaycastHit2D[] hit = Physics2D.RaycastAll(transform.position, aimdir * speed, speed * delta_time * CONSTANTS.PROJECTILE_SPEED_MULTI, hit_fltr); if (hit.Length != 0) { for (int i = 0; i < hit.Length; i++) { //If structure and tag Body_hitbox_generic body_hitbox = hit[i].collider.GetComponent <Body_hitbox_generic>(); //If hit lag-ghost hitbox, link to the actual hitbox then examine damage //Non-server clients wont be detecting the lag-ghost as it only exist on server end if (body_hitbox != null)//Characters { int ret_value = impact_character(body_hitbox, hit[i].point); if (ret_value == 0)////if this box has been hit OR bullet hits the shooter { continue; } else if (ret_value == -1)//If bullet stopped by body { break; } } else//Objects or level; Lag compensate will not apply on physic object { GameObject obj = hit[i].collider.gameObject; impact_object(obj, hit[i].point); break; } } } }
private void OnTriggerStay2D(Collider2D collision) { if (Time.time <= time_to_damage) { return; } time_to_damage = Time.time + CONSTANTS.NETWORK_TICK_RATE; Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, circleCollider.radius, hitFilter); if (hits != null) { for (int i = 0; i < hits.Length; i++) { Body_hitbox_generic hitbox = hits[i].GetComponent <Body_hitbox_generic>(); if (hitbox != null) { hitbox.body.damage(null, Vector2.zero, dmg_thermal: thermal); } } } }
// Update is called once per frame void Update() { if (isServer) { if (TargetOfLaser == null) { targetPos = transform.position; } else { Vector2 aimdir = TargetOfLaser.position - transform.position; RaycastHit2D hit = Physics2D.Raycast(transform.position, aimdir, Vector2.Distance(TargetOfLaser.position, transform.position), blockage); if (hit) { targetPos = hit.point; if (DamagePerSecond > 0 && Time.time > time_to_damage) { Body_hitbox_generic body_hitbox = hit.collider.GetComponent <Body_hitbox_generic>(); if (body_hitbox != null) { time_to_damage = Time.time + CONSTANTS.NETWORK_TICK_RATE; body_hitbox.body.damage(null, Vector2.zero, dmg_electric: DamagePerSecond * CONSTANTS.NETWORK_TICK_RATE); } } } else { targetPos = TargetOfLaser.position; } } thisPos = transform.position; } positions[0] = transform.position; positions[1] = targetPos; linerenderer.SetPositions(positions); }
//This function define how the projectile predicts public void detect() { RaycastHit2D hit = Physics2D.Raycast(rocketRB.position, aimdir, speed * delta_time * CONSTANTS.PROJECTILE_SPEED_MULTI, hit_fltr); if (hit) { //Spawn explosion if (explosion != null) { Vector2 exp_pos = hit.point - (hit.point - rocketRB.position).normalized * CONSTANTS.EXPLOSION_OFFSET_WALL; Rpc_spawn_explosion(exp_pos); if (isDedicated()) { spawn_explosion(exp_pos); } } //Exert force & damage Body_hitbox_generic hitbox = hit.collider.GetComponent <Body_hitbox_generic>(); if (hitbox != null) { impact_character(hitbox, hit.point); } else//physic objects { impact_object(hit.collider.gameObject, hit.point); } Rpc_unlink_smoke(); fade = true; rocketRB.position = hit.point - aimdir.normalized * 0.1f;//keep explosion occuring outside of wall Destroy(GetComponent <SpriteRenderer>()); time_to_destroy = Time.time + fade_time; speed = 0; } }
//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); }
public int impact_character(Body_hitbox_generic hit_box, Vector2 hit_point) { throw new System.NotImplementedException(); }