/* Interior update for tranport step */ void trans_update_interior(mesh_t *mesh, mesh_t *mesh_old, int cur_y, int cur_x) { cell_t *cur_cell, *cur_cell_old, *adj_cell_vert, *adj_cell_hor, *adj_cell_diag; double y_comp, x_comp; /* Gets the x and y components of the backwards in time vector for method */ /* of characteristics */ y_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 1); x_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 0); // if ((cur_y == 62) && (cur_x == 1)) // printf("x: %d, y: %d, xcomp: %e, ycomp: %e\n", cur_x, cur_y, x_comp, y_comp ); cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)]; cur_cell_old = &mesh->cell[MESH_INDEX(cur_y, cur_x)]; /* Gets the quadrant the foot is in */ int quad = get_quadrant(y_comp, x_comp); /* Sets components to proportions of full cell */ y_comp = fabs(y_comp / mesh->dim.h); x_comp = fabs(x_comp / mesh->dim.h); /* Selects the configuration of cells */ assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, quad); cur_cell->saturation = trans_get_average_sat(cur_cell_old, adj_cell_hor, adj_cell_vert, adj_cell_diag, y_comp, x_comp); }
//Finds set of Q_PTS consecutive data points that lie in more than QUADS //quadrants. void LIC_4() { CMV[4] = FALSE; int i,j,q1,q2,q3,q4; for(i=0;i<NUMPOINTS;i++)//NUMPOINTS { q1 = 0; q2 = 0; q3 = 0; q4 = 0; // iterate over Q_PTS consecutive points and stop if you reach the last // NUMPOINT for(j=i;(j<i+PARAMETERS.Q_PTS)&&(i+PARAMETERS.Q_PTS<NUMPOINTS+1);j++) { double z = get_quadrant(X[j],Y[j]); if(z == 1) q1++; else if(z == 2) q2++; else if(z == 3) q3++; else q4++; }//closes inner for loop for Q_PTS switch(PARAMETERS.QUADS) { //more than 1 Quad case 1: if(q1*q2>0||q1*q3>0||q1*q4>0||q2*q3>0||q2*q4>0||q3*q4>0) //atleast two out q1,q2,q3 and q4 need to be non-zero { CMV[4]=TRUE; break; } //more than 2 Quad case 2: if(q1*q2*q3!=0||q2*q3*q4!=0||q3*q4*q1!=0||q1*q2*q4!=0) //atleast three out q1,q2,q3 and q4 need to be non-zero { CMV[4]=TRUE; break; } //more than 3 Quad case 3: if((q1*q2*q3*q4)>0) { CMV[4]=TRUE; break; } } }//closes for loop }// end of LIC4 function LIC4 function
gboolean starchart_event_button (GtkWidget *widget, GdkEventButton *event, gpointer gwp_ptr) { gint x, y, q; gdouble wx, wy; GSList *planets_nearby, *ships_nearby; static GwpPlanet *ps_planet = NULL, *s_planet = NULL; static GwpShip *ps_ship = NULL, *s_ship = NULL; static gboolean loaded = FALSE; static GtkNotebook *mini = NULL; if (!loaded) { loaded = TRUE; mini = (GtkNotebook *) lookup_widget("notebook_mini"); } /* Get focus on starchart */ gtk_widget_grab_focus(GTK_WIDGET(starchart_get_canvas())); /* First get canvas coords */ x = (gint) event->x; y = (gint) event->y; /* Translate coords to World system */ gnome_canvas_c2w(starchart_get_canvas(), x, y, &wx, &wy); q = get_quadrant(wx, wy); /* Select a planet */ if((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { /* Search for nearest planet and select it */ planets_nearby = starchart_get_surrounding_quads(planets_per_quad, q); /* Keep record of previously selected planet */ ps_planet = s_planet; s_planet = starchart_select_nearest_planet(GTK_WIDGET(gwp_ptr), planets_nearby, wx, wy); /* When a planet is selected, emit the corresponding signal */ g_signal_emit_by_name (s_planet, "selected"); } /* Open Planet panel (double-click) */ else if((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { /* If the d-click was on the same planet, show the panels! */ if(ps_planet == s_planet) { starchart_open_extra_planet_panels(); while (gtk_events_pending()) gtk_main_iteration(); /* Re-select planet to update extra panels */ planets_nearby = starchart_get_surrounding_quads(planets_per_quad, q); starchart_select_nearest_planet(GTK_WIDGET(gwp_ptr), planets_nearby, wx, wy); } } /* Select a ship */ else if((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) { /* Search for nearest ship and select it */ ships_nearby = starchart_get_surrounding_quads(ships_per_quad, q); /* Keep record of previously selected ship */ ps_ship = s_ship; s_ship = starchart_select_nearest_ship(GTK_WIDGET(gwp_ptr), ships_nearby, wx, wy); } /* Open Ship panel (double-click) */ else if((event->type == GDK_2BUTTON_PRESS) && (event->button == 3)) { /* If the d-click was on the same planet, show the panels! */ if(ps_ship == s_ship) { starchart_open_extra_ship_panels(); while (gtk_events_pending()) gtk_main_iteration(); /* Re-select ship to update extra panels */ ships_nearby = starchart_get_surrounding_quads(ships_per_quad, q); starchart_select_nearest_ship(GTK_WIDGET(gwp_ptr), ships_nearby, wx, wy); } } return TRUE; }
int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float time_limit = 0.0f, int *next_hit = NULL) { mc_info mc, mc_shield, mc_hull; ship *shipp; ship_info *sip; weapon *wp; weapon_info *wip; Assert( ship_objp != NULL ); Assert( ship_objp->type == OBJ_SHIP ); Assert( ship_objp->instance >= 0 ); shipp = &Ships[ship_objp->instance]; sip = &Ship_info[shipp->ship_info_index]; Assert( weapon_objp != NULL ); Assert( weapon_objp->type == OBJ_WEAPON ); Assert( weapon_objp->instance >= 0 ); wp = &Weapons[weapon_objp->instance]; wip = &Weapon_info[wp->weapon_info_index]; Assert( shipp->objnum == OBJ_INDEX(ship_objp)); // Make ships that are warping in not get collision detection done if ( shipp->is_arriving() ) return 0; // Return information for AI to detect incoming fire. // Could perhaps be done elsewhere at lower cost --MK, 11/7/97 float dist = vm_vec_dist_quick(&ship_objp->pos, &weapon_objp->pos); if (dist < weapon_objp->phys_info.speed) { update_danger_weapon(ship_objp, weapon_objp); } int valid_hit_occurred = 0; // If this is set, then hitpos is set int quadrant_num = -1; polymodel *pm = model_get(sip->model_num); // total time is flFrametime + time_limit (time_limit used to predict collisions into the future) vec3d weapon_end_pos; vm_vec_scale_add( &weapon_end_pos, &weapon_objp->pos, &weapon_objp->phys_info.vel, time_limit ); // Goober5000 - I tried to make collision code here much saner... here begin the (major) changes mc_info_init(&mc); // set up collision structs mc.model_instance_num = shipp->model_instance_num; mc.model_num = sip->model_num; mc.submodel_num = -1; mc.orient = &ship_objp->orient; mc.pos = &ship_objp->pos; mc.p0 = &weapon_objp->last_pos; mc.p1 = &weapon_end_pos; mc.lod = sip->collision_lod; memcpy(&mc_shield, &mc, sizeof(mc_info)); memcpy(&mc_hull, &mc, sizeof(mc_info)); // (btw, these are leftover comments from below...) // // Note: This code is obviously stupid. We want to add the shield point if there is shield to hit, but: // 1. We want the size/color of the hit effect to indicate shield damage done. (i.e., for already-weak shield, smaller effect) // 2. Currently (8/9/97), apply_damage_to_shield() passes lefer damage to hull, which might not make sense. If // wouldn't have collided with hull, shouldn't do damage. Once this is fixed, the code below needs to cast the // vector through to the hull if there is leftover damage. // // WIF2_PIERCE_SHIELDS pierces shields // AL 1-14-97: "Puncture" doesn't mean penetrate shield anymore, it means that it punctures // hull to inflict maximum subsystem damage // // _argv[-1], 16 Jan 2005: Surface shields. // Surface shields allow for shields on a ship without a shield mesh. Good for putting real shields // on the Lucifer. This also fixes the strange bug where shots will occasionally go through the // shield mesh when they shouldn't. I don't know what causes this, but this fixes that -- shields // will absorb it when it hits the hull instead. This has no fancy graphical effect, though. // Someone should make one. // check both kinds of collisions int shield_collision = 0; int hull_collision = 0; // check shields for impact if (!(ship_objp->flags[Object::Object_Flags::No_shields])) { if (sip->flags[Ship::Info_Flags::Auto_spread_shields]) { // The weapon is not allowed to impact the shield before it reaches this point vec3d shield_ignored_until = weapon_objp->last_pos; float weapon_flown_for = vm_vec_dist(&wp->start_pos, &weapon_objp->last_pos); float min_weapon_span; if (sip->auto_shield_spread_min_span >= 0.0f) { min_weapon_span = sip->auto_shield_spread_min_span; } else { min_weapon_span = sip->auto_shield_spread; } // If weapon hasn't yet flown a distance greater than the maximum ignore // range, then some part of the currently checked range needs to be // ignored if (weapon_flown_for < min_weapon_span) { vm_vec_sub(&shield_ignored_until, &weapon_end_pos, &wp->start_pos); vm_vec_normalize(&shield_ignored_until); vm_vec_scale(&shield_ignored_until, min_weapon_span); vm_vec_add2(&shield_ignored_until, &wp->start_pos); } float this_range = vm_vec_dist(&weapon_objp->last_pos, &weapon_end_pos); // The range during which the weapon is not allowed to collide with the // shield, except if it actually hits the hull float ignored_range; // If the weapon has not yet surpassed the ignore range, calculate the // remaining ignore range if (vm_vec_dist(&wp->start_pos, &shield_ignored_until) > weapon_flown_for) ignored_range = vm_vec_dist(&weapon_objp->last_pos, &shield_ignored_until); else ignored_range = 0.0f; // The range during which the weapon may impact the shield float active_range = this_range - ignored_range; // During the ignored range, we only check for a ray collision with // the model if (ignored_range > 0.0f) { mc_shield.flags = MC_CHECK_MODEL; mc_shield.p1 = &shield_ignored_until; shield_collision = model_collide(&mc_shield); mc_shield.p1 = &weapon_end_pos; mc_shield.hit_dist = mc_shield.hit_dist * (ignored_range / this_range); } // If no collision with the model found in the ignore range, only // then do we check for sphereline collisions with the model during the // non-ignored range if (!shield_collision && weapon_flown_for + this_range > min_weapon_span) { mc_shield.p0 = &shield_ignored_until; mc_shield.p1 = &weapon_end_pos; mc_shield.radius = sip->auto_shield_spread; if (sip->auto_shield_spread_from_lod > -1) { mc_shield.lod = sip->auto_shield_spread_from_lod; } mc_shield.flags = MC_CHECK_MODEL | MC_CHECK_SPHERELINE; shield_collision = model_collide(&mc_shield); mc_shield.lod = sip->collision_lod; mc_shield.submodel_num = -1; // Because we manipulated p0 and p1 above, hit_dist will be // relative to the values we used, not the values the rest of // the code expects; this fixes that mc_shield.p0 = &weapon_objp->last_pos; mc_shield.p1 = &weapon_end_pos; mc_shield.hit_dist = (ignored_range + (active_range * mc_shield.hit_dist)) / this_range; } if (shield_collision) { // If we used a sphereline check, then the collision point will lie // somewhere on the ship's hull; this re-positions it to lie on the // correct point along the weapon's path if (mc_shield.flags & MC_CHECK_SPHERELINE) { vec3d tempv; vm_vec_sub(&tempv, mc_shield.p1, mc_shield.p0); vm_vec_scale(&tempv, mc_shield.hit_dist); vm_vec_add2(&tempv, mc_shield.p0); mc_shield.hit_point_world = tempv; } // Re-calculate hit_point because it's likely pointing to the wrong // place vec3d tempv; vm_vec_sub(&tempv, &mc_shield.hit_point_world, &ship_objp->pos); vm_vec_rotate(&mc_shield.hit_point, &tempv, &ship_objp->orient); } } else if (sip->flags[Ship::Info_Flags::Surface_shields]) { if (pm->shield.ntris > 0) { // If there is a shield mesh, we need to check that first mc_shield.flags = MC_CHECK_SHIELD; shield_collision = model_collide(&mc_shield); } if (!shield_collision) { // But if no shield mesh or it was missed, check for a hull collision mc_shield.flags = MC_CHECK_MODEL; shield_collision = model_collide(&mc_shield); // Because we used MC_CHECK_MODEL, the returned hit position might be // in a submodel's frame of reference, so we need to ensure we end up // in the ship's frame of reference vec3d local_pos; vm_vec_sub(&local_pos, &mc_shield.hit_point_world, &ship_objp->pos); vm_vec_rotate(&mc_shield.hit_point, &local_pos, &ship_objp->orient); } } else { // Normal collision check against a shield mesh mc_shield.flags = MC_CHECK_SHIELD; shield_collision = (pm->shield.ntris > 0) ? model_collide(&mc_shield) : 0; } } // If we found a shield collision but were only checking for a simple model // collision, we can re-use the same collision info for the hull as well if (shield_collision && mc_shield.flags == MC_CHECK_MODEL) { memcpy(&mc_hull, &mc_shield, sizeof(mc_info)); hull_collision = shield_collision; // The weapon has impacted on the hull, so if it should therefore bypass // the shields altogether, we do it here if (sip->auto_shield_spread_bypass) { shield_collision = 0; } } else { mc_hull.flags = MC_CHECK_MODEL; hull_collision = model_collide(&mc_hull); } if (shield_collision) { // pick out the shield quadrant quadrant_num = get_quadrant(&mc_shield.hit_point, ship_objp); // make sure that the shield is active in that quadrant if (shipp->flags[Ship::Ship_Flags::Dying] || !ship_is_shield_up(ship_objp, quadrant_num)) quadrant_num = -1; // see if we hit the shield if (quadrant_num >= 0) { // do the hit effect if ( mc_shield.shield_hit_tri != -1 && (mc_shield.hit_dist*(flFrametime + time_limit) - flFrametime) < 0.0f ) { add_shield_point(OBJ_INDEX(ship_objp), mc_shield.shield_hit_tri, &mc_shield.hit_point); } // if this weapon pierces the shield, then do the hit effect, but act like a shield collision never occurred; // otherwise, we have a valid hit on this shield if (wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) quadrant_num = -1; else valid_hit_occurred = 1; } } // see which impact we use if (shield_collision && valid_hit_occurred) { memcpy(&mc, &mc_shield, sizeof(mc_info)); Assert(quadrant_num >= 0); } else if (hull_collision) { memcpy(&mc, &mc_hull, sizeof(mc_info)); valid_hit_occurred = 1; } // check if the hit point is beyond the clip plane when warping out. if ((shipp->flags[Ship::Ship_Flags::Depart_warp]) && (shipp->warpout_effect) && (valid_hit_occurred)) { vec3d warp_pnt, hit_direction; matrix warp_orient; shipp->warpout_effect->getWarpPosition(&warp_pnt); shipp->warpout_effect->getWarpOrientation(&warp_orient); vm_vec_sub(&hit_direction, &mc.hit_point_world, &warp_pnt); if (vm_vec_dot(&hit_direction, &warp_orient.vec.fvec) < 0.0f) { valid_hit_occurred = 0; } } // deal with predictive collisions. Find their actual hit time and see if they occured in current frame if (next_hit && valid_hit_occurred) { // find hit time *next_hit = (int) (1000.0f * (mc.hit_dist*(flFrametime + time_limit) - flFrametime) ); if (*next_hit > 0) // if hit occurs outside of this frame, do not do damage return 1; } if ( valid_hit_occurred ) { wp->collisionInfo = new mc_info; // The weapon will free this memory later memcpy(wp->collisionInfo, &mc, sizeof(mc_info)); Script_system.SetHookObjects(4, "Ship", ship_objp, "Weapon", weapon_objp, "Self",ship_objp, "Object", weapon_objp); bool ship_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, ship_objp); Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp); bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDESHIP, weapon_objp); if(!ship_override && !weapon_override) { if (shield_collision && quadrant_num >= 0) { if ((sip->shield_impact_explosion_anim > -1) && (wip->shield_impact_explosion_radius > 0)) { shield_impact_explosion(&mc.hit_point, ship_objp, wip->shield_impact_explosion_radius, sip->shield_impact_explosion_anim); } } ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal); } Script_system.SetHookObjects(2, "Self",ship_objp, "Object", weapon_objp); if(!(weapon_override && !ship_override)) Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, ship_objp, wp->weapon_info_index); Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp); if((weapon_override && !ship_override) || (!weapon_override && !ship_override)) Script_system.RunCondition(CHA_COLLIDESHIP, '\0', NULL, weapon_objp); Script_system.RemHookVars(4, "Ship", "Weapon", "Self","Object"); } else if ((Missiontime - wp->creation_time > F1_0/2) && (wip->is_homing()) && (wp->homing_object == ship_objp)) { if (dist < wip->shockwave.inner_rad) { vec3d vec_to_ship; vm_vec_normalized_dir(&vec_to_ship, &ship_objp->pos, &weapon_objp->pos); if (vm_vec_dot(&vec_to_ship, &weapon_objp->orient.vec.fvec) < 0.0f) { // check if we're colliding against "invisible" ship if (!(shipp->flags[Ship::Ship_Flags::Dont_collide_invis])) { wp->lifeleft = 0.001f; if (ship_objp == Player_obj) nprintf(("Jim", "Frame %i: Weapon %d set to detonate, dist = %7.3f.\n", Framecount, OBJ_INDEX(weapon_objp), dist)); valid_hit_occurred = 1; } } } } return valid_hit_occurred; }
int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float time_limit = 0.0f, int *next_hit = NULL) { mc_info mc, mc_shield, mc_hull; ship *shipp; ship_info *sip; weapon *wp; weapon_info *wip; Assert( ship_objp != NULL ); Assert( ship_objp->type == OBJ_SHIP ); Assert( ship_objp->instance >= 0 ); shipp = &Ships[ship_objp->instance]; sip = &Ship_info[shipp->ship_info_index]; Assert( weapon_objp != NULL ); Assert( weapon_objp->type == OBJ_WEAPON ); Assert( weapon_objp->instance >= 0 ); wp = &Weapons[weapon_objp->instance]; wip = &Weapon_info[wp->weapon_info_index]; Assert( shipp->objnum == OBJ_INDEX(ship_objp)); // Make ships that are warping in not get collision detection done if ( shipp->flags & SF_ARRIVING ) return 0; // if one object is a capital, only check player and player weapons with // the capital -- too slow for now otherwise. // if ( Polygon_models[Ships[num].modelnum].use_grid && !( (other_objp == Player_obj) || (&Objects[other_objp->parent] == Player_obj)) ) // return 0; // If either of these objects doesn't get collision checks, abort. if (Ship_info[shipp->ship_info_index].flags & SIF_NO_COLLIDE) return 0; // Return information for AI to detect incoming fire. // Could perhaps be done elsewhere at lower cost --MK, 11/7/97 float dist = vm_vec_dist_quick(&ship_objp->pos, &weapon_objp->pos); if (dist < weapon_objp->phys_info.speed) { update_danger_weapon(ship_objp, weapon_objp); } ship_model_start(ship_objp); int valid_hit_occurred = 0; // If this is set, then hitpos is set int quadrant_num = -1; polymodel *pm = model_get(sip->model_num); // total time is flFrametime + time_limit (time_limit used to predict collisions into the future) vec3d weapon_end_pos; vm_vec_scale_add( &weapon_end_pos, &weapon_objp->pos, &weapon_objp->phys_info.vel, time_limit ); // Goober5000 - I tried to make collision code here much saner... here begin the (major) changes // set up collision structs mc.model_num = sip->model_num; mc.submodel_num = -1; mc.orient = &ship_objp->orient; mc.pos = &ship_objp->pos; mc.p0 = &weapon_objp->last_pos; mc.p1 = &weapon_end_pos; memcpy(&mc_shield, &mc, sizeof(mc_info)); memcpy(&mc_hull, &mc, sizeof(mc_info)); // (btw, these are leftover comments from below...) // // Note: This code is obviously stupid. We want to add the shield point if there is shield to hit, but: // 1. We want the size/color of the hit effect to indicate shield damage done. (i.e., for already-weak shield, smaller effect) // 2. Currently (8/9/97), apply_damage_to_shield() passes lefer damage to hull, which might not make sense. If // wouldn't have collided with hull, shouldn't do damage. Once this is fixed, the code below needs to cast the // vector through to the hull if there is leftover damage. // // WIF2_PIERCE_SHIELDS pierces shields // AL 1-14-97: "Puncture" doesn't mean penetrate shield anymore, it means that it punctures // hull to inflict maximum subsystem damage // // _argv[-1], 16 Jan 2005: Surface shields. // Surface shields allow for shields on a ship without a shield mesh. Good for putting real shields // on the Lucifer. This also fixes the strange bug where shots will occasionally go through the // shield mesh when they shouldn't. I don't know what causes this, but this fixes that -- shields // will absorb it when it hits the hull instead. This has no fancy graphical effect, though. // Someone should make one. // set flags mc_shield.flags = MC_CHECK_SHIELD; mc_hull.flags = MC_CHECK_MODEL; // check both kinds of collisions int shield_collision = (pm->shield.ntris > 0) ? model_collide(&mc_shield) : 0; int hull_collision = model_collide(&mc_hull); // check shields for impact if (!(ship_objp->flags & OF_NO_SHIELDS)) { // pick out the shield quadrant if (shield_collision) quadrant_num = get_quadrant(&mc_shield.hit_point); else if (hull_collision && (sip->flags2 & SIF2_SURFACE_SHIELDS)) quadrant_num = get_quadrant(&mc_hull.hit_point); // make sure that the shield is active in that quadrant if ((quadrant_num >= 0) && ((shipp->flags & SF_DYING) || !ship_is_shield_up(ship_objp, quadrant_num))) quadrant_num = -1; // see if we hit the shield if (quadrant_num >= 0) { // do the hit effect if (shield_collision) add_shield_point(OBJ_INDEX(ship_objp), mc_shield.shield_hit_tri, &mc_shield.hit_point); else /* TODO */; // if this weapon pierces the shield, then do the hit effect, but act like a shield collision never occurred; // otherwise, we have a valid hit on this shield if (wip->wi_flags2 & WIF2_PIERCE_SHIELDS) quadrant_num = -1; else valid_hit_occurred = 1; } } // see which impact we use if (shield_collision && valid_hit_occurred) { memcpy(&mc, &mc_shield, sizeof(mc_info)); Assert(quadrant_num >= 0); } else if (hull_collision) { memcpy(&mc, &mc_hull, sizeof(mc_info)); valid_hit_occurred = 1; } //nprintf(("AI", "Frame %i, Hit tri = %i\n", Framecount, mc.shield_hit_tri)); ship_model_stop(ship_objp); // deal with predictive collisions. Find their actual hit time and see if they occured in current frame if (next_hit && valid_hit_occurred) { // find hit time *next_hit = (int) (1000.0f * (mc.hit_dist*(flFrametime + time_limit) - flFrametime) ); if (*next_hit > 0) // if hit occurs outside of this frame, do not do damage return 1; } if ( valid_hit_occurred ) { Script_system.SetHookObjects(4, "Ship", ship_objp, "Weapon", weapon_objp, "Self",ship_objp, "Object", weapon_objp); bool ship_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, ship_objp); Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp); bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDESHIP, weapon_objp); if(!ship_override && !weapon_override) { ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal); } Script_system.SetHookObjects(2, "Self",ship_objp, "Object", weapon_objp); if(!(weapon_override && !ship_override)) Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, ship_objp); Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp); if((weapon_override && !ship_override) || (!weapon_override && !ship_override)) Script_system.RunCondition(CHA_COLLIDESHIP, '\0', NULL, weapon_objp); Script_system.RemHookVars(4, "Ship", "Weapon", "Self","Object"); /* if(!Script_system.IsOverride(wip->sc_collide_ship)) { ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal); } if(wip->sc_collide_ship.IsValid()) { ade_odata lua_self_obj = l_Weapon.Set(object_h(weapon_objp)); ade_odata lua_ship_obj = l_Ship.Set(object_h(ship_objp)); Script_system.SetHookVar("Self", 'o', &lua_self_obj); Script_system.SetHookVar("Ship", 'o', &lua_ship_obj); Script_system.RunBytecode(wip->sc_collide_ship); Script_system.RemHookVar("Self"); Script_system.RemHookVar("Ship"); }*/ } else if ((Missiontime - wp->creation_time > F1_0/2) && (wip->wi_flags & WIF_HOMING) && (wp->homing_object == ship_objp)) { if (dist < wip->shockwave.inner_rad) { vec3d vec_to_ship; vm_vec_normalized_dir(&vec_to_ship, &ship_objp->pos, &weapon_objp->pos); if (vm_vec_dot(&vec_to_ship, &weapon_objp->orient.vec.fvec) < 0.0f) { // check if we're colliding against "invisible" ship if (!(shipp->flags2 & SF2_DONT_COLLIDE_INVIS)) { wp->lifeleft = 0.001f; if (ship_objp == Player_obj) nprintf(("Jim", "Frame %i: Weapon %i set to detonate, dist = %7.3f.\n", Framecount, OBJ_INDEX(weapon_objp), dist)); valid_hit_occurred = 1; } } } } return valid_hit_occurred; }
void trans_update_corner(mesh_t *mesh, mesh_t *mesh_old, int cur_y, int cur_x, int boundary_side1, int boundary_side2) { cell_t *cur_cell, *cur_cell_old, *adj_cell_vert, *adj_cell_hor, *adj_cell_diag; double y_comp, x_comp; /* Gets the x and y components of the backwards in time vector for method */ /* of characteristics */ y_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 1); x_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 0); cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)]; cur_cell_old = &mesh->cell[MESH_INDEX(cur_y, cur_x)]; /* Gets the quadrant the foot is in */ int quad = get_quadrant(y_comp, x_comp); int corner_type = get_corner_config(boundary_side1, boundary_side2); /* Sets components to proportions of full cell */ y_comp = fabs(y_comp / mesh->dim.h); x_comp = fabs(x_comp / mesh->dim.h); // printf("ycomp %e, xcomp %e\n", y_comp, x_comp); /* Selects the configuration of cells */ switch (corner_type) { case 1: switch (quad) { case 1: dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag); break; case 2: dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 3); break; case 3: assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, quad); break; default: dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 2); break; } break; case 2: switch (quad) { case 1: dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 1); break; case 2: dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag); break; case 3: dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 2); break; default: assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, quad); break; } break; case 3: switch (quad) { case 1: assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, quad); break; case 2: dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 0); break; case 3: dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag); break; default: dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 1); break; } break; default: switch (quad) { case 1: dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 0); break; case 2: assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, quad); break; case 3: dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag, cur_y, cur_x, 3); break; default: dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert, &adj_cell_diag); break; } } cur_cell->saturation = trans_get_average_sat(cur_cell_old, adj_cell_hor, adj_cell_vert, adj_cell_diag, y_comp, x_comp); // printf("sat: %e\n", cur_cell->saturation); }