/************************************************************************** * atct_init: * calculates alpha1, alpha2, and alpha3, which are some sort of coordinate * rotation amounts, in degrees. This creates a latitude/longitude-style * coordinate system centered under the satellite at the start of imaging. * You must pass it a state vector from the start of imaging. */ void atct_init(meta_projection *proj,stateVector st) { vector up={0.0,0.0,1.0}; vector z_orbit, y_axis, a, nd; double alpha3_sign; double alpha1,alpha2,alpha3; vecCross(st.pos,st.vel,&z_orbit);vecNormalize(&z_orbit); vecCross(z_orbit,up,&y_axis);vecNormalize(&y_axis); vecCross(y_axis,z_orbit,&a);vecNormalize(&a); alpha1 = atan2_check(a.y,a.x)*R2D; alpha2 = -1.0 * asind(a.z); if (z_orbit.z < 0.0) { alpha1 += 180.0; alpha2 = -1.0*(180.0-fabs(alpha2)); } vecCross(a,st.pos,&nd);vecNormalize(&nd); alpha3_sign = vecDot(nd,z_orbit); alpha3 = acosd(vecDot(a,st.pos)/vecMagnitude(st.pos)); if (alpha3_sign<0.0) alpha3 *= -1.0; proj->param.atct.alpha1=alpha1; proj->param.atct.alpha2=alpha2; proj->param.atct.alpha3=alpha3; }
void Line::computePrism() { // These vectors span the rectangular integration prism p_c = effectivePosB() - effectivePosA(); p_a[0] = p_c[2]; p_a[1] = 0; p_a[2] = -p_c[0]; p_a = vecNormalize(p_a) * p_prism_side_a; p_b = vecNormalize(vecCross(p_c, p_a)) * p_prism_side_b; // The arguments of the cross product are not permutable }
void updateCamera(Scene* scene) { double time = WallClockTime() - sceneTimeOffset; double rtime = (time / 21.35634); // camera rotation time rtime = rtime - floor(rtime); double btime = (time / 59.8752); // camera bobbing time btime = btime - floor(btime); double ltime = (time / 98.7654); // light rotation time ltime = ltime - floor(ltime); double lbtime = (time / 92.764); // light bobbing time lbtime = lbtime - floor(lbtime); camInit(scene->cam); cl_float3 pos; cl_float3 center; vecInit(center, 14.9f, 9.7f, -14.85f); vecInit(pos, 33.0f * sin(rtime * M_PI * 2.0), 8.0f * sin(btime * M_PI * 2.0 + 0.3), 33.0f * (cos(rtime * M_PI * 2.0) - 0.11)); vecAdd(pos, center); camMove(scene->cam, pos); camLookAt(scene->cam, center); vecInit(pos, 5.0f * sin(-ltime * M_PI * 2.0), 8.0f + 6.0f * sin(lbtime * M_PI * 2.0), 5.0f * cos(ltime * M_PI * 2.0)); vecNormalize(pos); scene->lightDir = pos; }
/* Get_sep: Calculates the separation between two satellites along the satellite beam, in the normal- and parallel- to look direction. Inputs are: a state vector from scene 1, in GEI coordinates; the name of the ceos for image 2; the slant range and doppler of the center of the beam; and pointers to the output normal and parallel baselines. */ void get_sep(stateVector stVec1, meta_parameters *meta2, double range, double dop,double *Bn,double *Bp) { double lat,phi,earthRadius; vector target,up,relPos; vector upBeam,alongBeam,beamNormal; double t,timeDelta; stateVector stVec2; GEOLOCATE_REC *g; /*Target is the patch of ground at beam center.*/ /*Initialize the transformation.*/ g=init_geolocate_meta(&stVec1,meta2); getLoc(g,range,dop, &lat,&phi,&earthRadius); free_geolocate(g); sph2cart(earthRadius,lat,phi,&target); /*Create beam plane unit vectors.*/ vecSub(stVec1.pos,target,&alongBeam); vecNormalize(&alongBeam); up=stVec1.pos; vecNormalize(&up); vecCross(up,alongBeam,&beamNormal); vecNormalize(&beamNormal); vecCross(alongBeam,beamNormal,&upBeam); vecNormalize(&upBeam); /*Find the time when the second satellite crosses the first's beam.*/ t=0.0; stVec2=meta_get_stVec(meta2,t); timeDelta=1.0; while (fabs(timeDelta)>0.00001) { vecSub(stVec1.pos,stVec2.pos,&relPos); timeDelta=vecDot(beamNormal,relPos)/vecDot(beamNormal,stVec2.vel); t+=timeDelta; if (!quietflag) { printf(" Time=%f sec, delta=%f sec\n",t,timeDelta); printf(" Distance from beam plane=%f m\n",vecDot(beamNormal,relPos)); } stVec2=meta_get_stVec(meta2,t); } /*Now we have the second satellite sitting in the plane of the first's beam, so we just separate that position into components along-beam and across-beam, and return.*/ vecSub(stVec2.pos,stVec1.pos,&relPos); *Bp=vecDot(alongBeam,relPos); *Bn=vecDot(upBeam,relPos); }
void matLookAt(Matrix4x4 *m, vec3 camera, vec3 point, vec3 vecNorm){ vec3 forward, side, up; Matrix4x4 mat, mat2; memcpy(&mat2, m, sizeof(Matrix4x4)); forward.x = point.x - camera.x; forward.y = point.y - camera.y; forward.z = point.z - camera.z; forward = vecNormalize(forward); up = vecNorm; side = vecCross(up, forward); up = vecCross(forward, side); side = vecNormalize(side); up = vecNormalize(up); // stolen from gluLookat.c #define M(row,col) mat.m[col*4+row] M(0,0) = side.x; M(0,1) = side.y; M(0,2) = side.z; M(0,3) = 0.f; M(1,0) = up.x; M(1,1) = up.y; M(1,2) = up.z; M(1,3) = 0.f; M(2,0) = -forward.x; M(2,1) = -forward.y; M(2,2) = -forward.z; M(2,3) = 0.f; M(3,0) = M(3,1) = M(3,2) = 0.f; M(3,3) = 1.f; #undef M // ----------------------- matMul(m, &mat, &mat2); vecMatTranslate(m, camera); }
void getTriangleNormal(Vec tri[3], Vec norm) { Vec v0,v1; vecSub(tri[1], tri[0], v0); vecSub(tri[2], tri[0], v1); vecCrossProduct(v0, v1, norm); //VecCross(v0, v1, norm); vecNormalize(norm); }
void DefenseFighterPassiveAttack(Ship *ship,Ship *target,bool rotate) { vector heading; if(!rotate) return; vecSub(heading,target->posinfo.position,ship->posinfo.position); vecNormalize(&heading); aitrackHeading(ship,&heading,0.9999f); }
/*----------------------------------------------------------------------------- Name : shSetLightPosition Description : maintains knowledge of a GL's light positions Inputs : index - [0..1], the light whose position is being updated position - the position m - the matrix to transform by Outputs : shLight[index].position will contain the transformed light position Return : ----------------------------------------------------------------------------*/ void shSetLightPosition(sdword index, real32* position, real32* m) { real32 xposition[4]; dbgAssert(index >= 0 && index < 2); TRANSFORM_POINT(xposition, m, position); vecNormalize((vector*)&xposition); shLight[index].position[0] = xposition[0]; shLight[index].position[1] = xposition[1]; shLight[index].position[2] = xposition[2]; shLight[index].position[3] = xposition[3]; shLight[index].worldposition[0] = position[0]; shLight[index].worldposition[1] = position[1]; shLight[index].worldposition[2] = position[2]; shLight[index].worldposition[3] = position[3]; vecNormalize((vector *)&shLight[index].worldposition); }
void P2MultiBeamFrigateAttackDoAttack(Ship *ship,SpaceObjRotImpTarg *target,real32 maxdist,bool PassiveAttack) { ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; P2MultiBeamFrigateStatics *frigstat = (P2MultiBeamFrigateStatics *)shipstaticinfo->custstatinfo; P2MultiBeamFrigateSpec *spec = (P2MultiBeamFrigateSpec *)ship->ShipSpecifics; vector trajectory; vector shipRightVec; real32 range; spec->aiattacklast = universe.totaltimeelapsed; ship->autostabilizeship = FALSE; aishipGetTrajectory(ship, target, &trajectory); range = RangeToTarget(ship,target,&trajectory); if (range > frigstat->MultiBeamRange[ship->tacticstype]) { //not in range if(!PassiveAttack) { //do aiship fly to stuff here //if not in range...fly to the ship //else track zero velocity aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying + AISHIP_CarTurn,0.0f); } return; } //we are in range vecNormalize(&trajectory); if(!PassiveAttack) { aitrackZeroVelocity(ship); } matGetVectFromMatrixCol2(shipRightVec,ship->rotinfo.coordsys); aitrackHeadingAndUp(ship,&trajectory,&shipRightVec,0.9999f); if(vecMagnitudeSquared(ship->rotinfo.rotspeed) > frigstat->AttackRotationSpeed) { if(aitrackHeadingWithFlags(ship,&trajectory,0.99f,AITRACKHEADING_IGNOREUPVEC|AITRACK_DONT_ZERO_ME)) { //rotation speed reached //lets fire guns if we can P2MultiBeamFrigateFire(ship,target); } } }
static void get_target_position(stateVector *st, double look, double yaw, double sr, vector *targPos) { vector relPos = vecNew(sin(yaw), -sin(look)*cos(yaw), -cos(look)*cos(yaw)); // relPos unit vector points from s/c to targPos. // Rotate into earth axes vector look_matrix[3]; look_matrix[2] = st->pos; vecNormalize(&look_matrix[2]); vector v = st->vel; vecNormalize(&v); vecCross(look_matrix[2],v,&look_matrix[1]); vecCross(look_matrix[1],look_matrix[2],&look_matrix[0]); vecMul(look_matrix,relPos,&relPos); // scale relPos so it reaches from s/c to targPos vecScale(&relPos,sr); vecAdd(relPos,st->pos,targPos); }
void updateAppendage(Scene* scene, int sceneIndex, cl_float3 p, cl_float3 q, cl_float3 w, float A, float B, int countA, int countB) { cl_float3 U; cl_float3 V; cl_float3 W; cl_float3 j; cl_float3 d; V = q; vecSub(V, p); float D = vecLength(V); float inverseD = 1.0f / D; vecScale(V, inverseD); W = w; vecNormalize(W); vecCross(U, V, W); float A2 = A*A; float y = 0.5f * inverseD * (A2 - B * B + D * D); double square = A2 - y*y; if (square < 0.0f) throw std::runtime_error("Unable to construct appendage"); float x = sqrtf(square); j = p; vecScaledAdd(j, x, U); vecScaledAdd(j, y, V); d = j; vecSub(d, p); vecScale(d, 1.0f / float(countA)); for (int i = 0; i <= countA; i++) { Sphere* sphere = &(scene->spheres[sceneIndex + i]); sphere->center = p; vecScaledAdd(sphere->center, float(i), d); vecScale(sphere->center, 0.1f); } d = j; vecSub(d, q); vecScale(d, 1.0f / float(countB)); for (int i = 0; i <= countA; i++) { Sphere* sphere = &(scene->spheres[sceneIndex + i + countA + 1]); sphere->center = q; vecScaledAdd(sphere->center, float(i), d); vecScale(sphere->center, 0.1f); } }
void P2MultiBeamFrigateAttackPassive(Ship *ship,Ship *target,bool rotate) { ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; P2MultiBeamFrigateSpec *spec = (P2MultiBeamFrigateSpec *)ship->ShipSpecifics; P2MultiBeamFrigateStatics *frigstat = (P2MultiBeamFrigateStatics *)shipstaticinfo->custstatinfo; vector trajectory; vector heading, temp; real32 range; P2MultiBeamFrigateAttackDoAttack(ship,(SpaceObjRotImpTarg *)target,1000.0f,TRUE); return; aishipGetTrajectory(ship, (SpaceObjRotImpTarg *)target, &trajectory); range = RangeToTarget(ship,(SpaceObjRotImpTarg *)target,&trajectory); if ( (range < frigstat->MultiBeamRange[ship->tacticstype]) && (rotate) ) { temp = trajectory; temp.z+=5; temp.y+=5; temp.x+=5; vecCrossProduct(heading,trajectory,temp); vecNormalize(&heading); vecNormalize(&trajectory); if (aitrackHeadingAndUp(ship,&heading,&trajectory,0.99f)) { if (!spec->steady) aitrackForceHeading(ship,&heading,&trajectory); spec->steady = TRUE; } else spec->steady = FALSE; } shipstaticinfo->custshipheader.CustShipFire(ship, (SpaceObjRotImpTarg *)target); }
void Line::alignWithVec(Matrix<double> vec) { Matrix<double> new_vec = vecNormalize(vec)*vecLength(p_position_b-p_position_a); Matrix<double> middle(3, 1); middle[0] = p_position_a[0] + 0.5 * (p_position_b[0] - p_position_a[0]); middle[1] = p_position_a[1] + 0.5 * (p_position_b[1] - p_position_a[1]); middle[2] = p_position_a[2] + 0.5 * (p_position_b[2] - p_position_a[2]); p_position_a = middle - 0.5*new_vec; p_position_b = middle + 0.5*new_vec; computePrism(); computeVertices(); }
//fires the bursts for the ship bool doBurstFire(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; GunInfo *gunInfo = ship->gunInfo; sdword numGuns = gunInfo->numGuns; //Gun *gun; sdword done; vector trajectory,heading; real32 range,one_over_range; SpaceObjRotImpTarg dummyTarg; vecSub(trajectory,spec->burstFireVector,ship->posinfo.position); range = vecMagnitudeSquared(trajectory); range = fsqrt(range); one_over_range = 1.0f/range; vecScalarMultiply(trajectory,trajectory,one_over_range); dummyTarg.objtype = OBJ_ShipType; dummyTarg.posinfo.position = spec->burstFireVector; dummyTarg.collInfo.collPosition = spec->burstFireVector; dummyTarg.currentLOD = ship->currentLOD; dummyTarg.collMyBlob = ship->collMyBlob; vecSet(dummyTarg.posinfo.velocity,0.0f,0.0f,0.0f); //track target even more precisely vecSub(heading,spec->burstFireVector,ship->posinfo.position); vecNormalize(&heading); aitrackHeadingWithFlags(ship,&heading,0.9999f,AITRACKHEADING_IGNOREUPVEC); //set special information that needs to be 'transmitted' //to the code in gunshoot. //fix later spec->bulletLifeTime = range*oneOverburstSpeed; bitSet(ship->specialFlags,SPECIAL_BurstFiring); done = gunShootGunsAtTarget(ship,&dummyTarg,0.0f,&trajectory); bitClear(ship->specialFlags,SPECIAL_BurstFiring); if(done == TRUE) { spec->cooldown = TRUE; spec->burstChargeState2 = burstCoolDownTime; } return done; }
void createSphere(float radius, std::vector<float>& vertices, std::vector<unsigned int>& indices, std::vector<float>& normals) { int stacks = 64; int slices = 64; for(int i = 0; i <= stacks; i++) { float lat0 = M_PI * (-0.5 + (float) (i) / stacks); float z0 = sin(lat0)*radius; float zr0 = cos(lat0); for(int j = 0; j < slices; j++) { float lng = 2 * M_PI * (float) (j - 1) / slices; float x = cos(lng)*radius; float y = sin(lng)*radius; float v[4] = {x*zr0, y*zr0, z0, 1.0f}; vertices.push_back(v[0]); vertices.push_back(v[1]); vertices.push_back(v[2]); vertices.push_back(v[3]); float n3[3] = {x * zr0, y * zr0, z0}; vecNormalize(n3,n3); normals.push_back(n3[0]); normals.push_back(n3[1]); normals.push_back(n3[2]); normals.push_back(0.0f); } } for (int i = 0; i < stacks; i++) { for (int j = 0; j < slices; j++) { indices.push_back(i*slices+j); indices.push_back(i*slices+((j+1)%slices)); indices.push_back((i+1)*slices+((j+1)%slices)); indices.push_back((i+1)*slices+((j+1)%slices)); indices.push_back((i+1)*slices+j); indices.push_back(i*slices+j); } } }
// Construct a line through two points. void initGeomLine(geomPt pt1, geomPt pt2, geomLine self) { geomVec perp; geomCopy(pt1, self->pt1); geomCopy(pt2, self->pt2); // (A,B) is the vector perpendicular to right side of line, (deltaY, -deltaX). perp[0] = pt2[1]-pt1[1]; perp[1] = pt1[0]-pt2[0]; vecNormalize(perp, perp); self->A = perp[0]; self->B = perp[1]; // C is the negative of the distance of the line from the origin. self->C = 0.0; // Small chicken-and-egg problem... self->C = -signedDist(self,pt1); }
void DefenseFighterAttack(Ship *ship,SpaceObjRotImpTarg *target,real32 maxdist) { vector trajectory; real32 range; aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); if (range < 1000.0f) { aitrackZeroVelocity(ship); vecNormalize(&trajectory); aitrackHeading(ship,&trajectory,0.9999f); } else { aishipFlyToPointAvoidingObjs(ship,&target->posinfo.position,AISHIP_PointInDirectionFlying,0.0f); } }
//this function flies the ship to within range of the desired target location and //orients itself to fire. Returns true when in position bool flytoBurstPosition(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; vector heading; bool ready = FALSE; //maybe track to within gun gimbleness vecSub(heading,spec->burstFireVector,ship->posinfo.position); vecNormalize(&heading); if(aitrackHeadingWithFlags(ship,&heading,0.99f,AITRACKHEADING_IGNOREUPVEC)) { ready = TRUE; } if(!MoveReachedDestinationVariable(ship,&spec->burstFireVector,burstRange)) { aishipFlyToPointAvoidingObjs(ship,&spec->burstFireVector,AISHIP_FastAsPossible,0.0f); return(FALSE); } aitrackZeroVelocity(ship); return(ready); }
vector<vector<double > > spectralDecomposition(CSCMat mat, int nev, double diffuse_t) { /* Compute Eigenvectors and Eigenvalues of lower Laplacian matrix */ int n = mat.pCol.size() -1; // dimension (number of rows or cols od similiar matrix) int nconv; // number of "converged" eigenvalues. int nnz = mat.val.size(); double* eigVal = new double[n]; // Eigenvalues. double* eigVec = new double[n*nev]; // Eigenvectors stored sequentially. char uplo = 'L'; #ifdef DEBUG printf("Spectral decomposition started \n"); unsigned int start_time = time(NULL); #endif nconv = AREig(eigVal, eigVec, n, nnz, &mat.val[0], &mat.iRow[0], &mat.pCol[0], uplo, nev, "SM", 0, 0.0, 1000000); #ifdef DEBUG unsigned int end_time = time(NULL); printf("Spectral decomposition finished in %u s\n", end_time-start_time); #endif Solution(nconv, n, nnz, &mat.val[0], &mat.iRow[0], &mat.pCol[0], uplo, eigVal, eigVec); vector<vector<double > > dataPoints = getDataPoints(eigVec,nev,n); // unnormalized data point for clustering eigenvectors in columns //vector<vector<double > > dataPointsTrans = getDataPointsTrans(eigVec,nev,n); diffuse(dataPoints, eigVal, diffuse_t); //print2DVecArray(dataPoints); //vecSave2DArray("eigvec.txt", dataPoints); vecNormalize(dataPoints); //vecSave2DArray("eigvecnorm.txt", dataPoints); return dataPoints; }
// gluLookAt() equivalent void matrixLookAt( float result[16], const float eye[3], const float target[3], const float up[3]) { float forward[3] = { target[0] - eye[0], target[1] - eye[1], target[2] - eye[2] }; vecNormalize(forward); float side[3]; vecCross(side, forward, up); float up_after[3]; vecCross(up_after, side, forward); float view_matrix[16] = MATRIX_IDENTITY; view_matrix[0] = side[0]; view_matrix[4] = side[1]; view_matrix[8] = side[2]; view_matrix[1] = up_after[0]; view_matrix[5] = up_after[1]; view_matrix[9] = up_after[2]; view_matrix[2] = -forward[0]; view_matrix[6] = -forward[1]; view_matrix[10] = -forward[2]; // Final translation float trans_matrix[16]; float minus_eye[3] = {-eye[0], -eye[1], -eye[2]}; matrixTranslate(trans_matrix, minus_eye); matrixMult(result, view_matrix, trans_matrix); }
void MineLayerAttackRun(Ship *ship,SpaceObjRotImpTarg *target,AttackSideStep *attacksidestep,AttackSideStepParameters *parameters) { vector trajectory; //real32 dist; real32 range; //real32 temp; // bool didshoot; ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; Gun *gun; udword numGuns,target_class; GunInfo *guninfo = ship->gunInfo; //vector tmpvec; //real32 randegf; //sdword randeg; //matrix tmpmat; //vector targetheading; MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics; MinelayerCorvetteStatics *minelayercorvettestatics; minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; numGuns = guninfo->numGuns; gun = &guninfo->guns[0]; if(target != NULL) { if(target->objtype == OBJ_ShipType) target_class = ((Ship *)target)->staticinfo->shipclass; else target_class = CLASS_NonCombat; } switch (ship->aistateattack) { case ATTACK_INIT: case APPROACH: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x MINELAYER_ATTACK_APPROACH",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying,0.0f); range = RangeToTarget(ship,target,&trajectory); //lets check if we want to force drop... if(target->objtype == OBJ_ShipType) { if(((Ship *)target)->shiptype == Mothership) { //its a mothership vector tempvec; real32 tempreal; vecSub(tempvec,target->collInfo.collPosition,ship->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); if(tempreal < mothershipDistSqr) { //we're within range of force dropping! ship->aistateattack = DROP_MOTHERSHIP; } break; } } if (range < minelayercorvettestatics->breakInAwayDist) { ship->aistateattack = BREAKPOSITION; spec->aivec.x = 0.0f; spec->aivec.y = 0.0f; spec->aivec.z = 0.0f; } break; case DROP_MOTHERSHIP: { vector tempvec; real32 tempreal; vecSub(tempvec,ship->collInfo.collPosition,target->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); vecNormalize(&tempvec); if(tempreal > mothershipDistSqr2) { ship->aistateattack = ATTACK_INIT; } if(aitrackHeadingWithFlags(ship,&tempvec,0.97f,AITRACKHEADING_IGNOREUPVEC)) { if(MinelayerCorvetteStaticMineDrop(ship,target)) //problem...there will be other targets...bah..lets see.. { MinelayerCorvetteOrderChangedCleanUp(ship); } } break; } case BREAKPOSITION: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAKPOSITION",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); ship->aistateattack = BREAK1; case BREAK1: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK1",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); //aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); aishipFlyToPointAvoidingObjs(ship,&target->posinfo.position,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range < minelayercorvettestatics->DropRange) { //temp vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); //temp ship->aistateattack = KILL; //within mining range so start dropping spec->aispheretime=0.0f; //reset time; } break; case KILL: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); spec->aispheretime += universe.phystimeelapsed; if(gunCanShoot(ship, gun)) { if(gun->numMissiles > 0) { spec->mineaistate = MINE_DROP_ATTACK; MinelayerCorvetteFire(ship,target); } } if(range > minelayercorvettestatics->DropStopRange) { //out of range.... ship->aistateattack = BREAK2; } if(spec->aispheretime > minelayercorvettestatics->Break2SphereizeFreq) { //time to sphereize; spec->aivec.x =0.0f; spec->aivec.y =0.0f; spec->aivec.z =0.0f; spec->aispheretime = -1000000.0f; // Reset, and never do again till next attack pass... vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL: Adjust for Break2 Sphereizing Godliness Maneuver :)",(udword)ship); #endif } aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); break; case BREAK2: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK2",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range > minelayercorvettestatics->FlyAwayDist[target_class] || (MoveReachedDestinationVariable(ship,&spec->aivec,minelayercorvettestatics->FlyAwayTolerance))) { //turn around and start over ship->aistateattack = APPROACH; } break; default: dbgAssert(FALSE); break; } }
/*----------------------------------------------------------------------------- Name : shSpecularColour Description : shades a vertex according to the specular model in use Inputs : specInd - [0..2] the index of the specular shader side = 0 or 1 Outputs : Return : ----------------------------------------------------------------------------*/ void shSpecularColour( sdword specInd, sdword side, vector* vobj, vector* norm, ubyte* color, real32* m, real32* minv) { vector veye = {0.0f, 0.0f, 1.0f}; vector xnorm, xvobj; real32 nx, ny, nz; real32 alpha, nDotVP; real32 fade; extern bool bFade; extern real32 meshFadeAlpha; fade = bFade ? meshFadeAlpha : 1.0f; shTransformNormal(&xnorm, norm, minv); if (side == 0) { nx = xnorm.x; ny = xnorm.y; nz = xnorm.z; } else { nx = -xnorm.x; ny = -xnorm.y; nz = -xnorm.z; } if (specInd == 0) { nDotVP = nz; if (nDotVP > 0.0f) { alpha = shPow(CLAMP(nDotVP, 0.0f, 1.0f), shSpecularExponent[specInd]); } else { alpha = 0.0f; } #if SLOW_TO_INT color[3] = (ubyte)(fade * (real32)color[3] * CLAMP(alpha, 0.0f, 1.0f)); #else color[3] = (ubyte)FAST_TO_INT(fade * (real32)color[3] * CLAMP(alpha, 0.0f, 1.0f)); #endif } else if (specInd == 1) { vector vpInfNorm[2]; real32 alpha0, alpha1; sdword l, c; memcpy(&vpInfNorm[0], shLight[0].position, sizeof(vector)); memcpy(&vpInfNorm[1], shLight[1].position, sizeof(vector)); #if 0 shTransformVertex(&xvobj, vobj, m); veye.x = xvobj.x; veye.y = xvobj.z; veye.z = xvobj.y; vecNormalize(&veye); nDotVP = nx * veye.x + ny * veye.y + nz * veye.z; alpha0 = gl_pow(CLAMP(nDotVP, 0.0f, 1.0f), 5.0f); #endif alpha1 = 0.0f; for (l = 0; l < lightNumLights; l++) { nDotVP = nx * vpInfNorm[l].x + ny * vpInfNorm[l].y + nz * vpInfNorm[l].z; if (nDotVP > 0.0f) { alpha1 += shPow(nDotVP, shSpecularExponent[1]); } } alpha = 2.3f * alpha1;//(0.9f * alpha0) + (0.23f * alpha1); c = (sdword)(fade * color[3] * alpha); c = CLAMP(c, 0, 255); color[3] = (ubyte)c; } else/* if (specInd == 2)*/ { shTransformVertex(&xvobj, vobj, m); veye.x = xvobj.x; veye.y = xvobj.y; veye.z = xvobj.z; vecNormalize(&veye); nDotVP = nx * veye.x + ny * veye.y + nz * veye.z; if (nDotVP < 0.0f) { nDotVP = -nDotVP; } if (nDotVP > 0.0f) { alpha = shPow(CLAMP(nDotVP, 0.0f, 1.0f), shSpecularExponent[2]); } else { alpha = 0.0f; } #if SLOW_TO_INT color[1] = (ubyte)((real32)color[1] * CLAMP(alpha, 0.0f, 0.92f)); color[3] = (ubyte)(fade * (real32)color[3] * CLAMP(alpha, 0.0f, 1.0f)); #else color[1] = (ubyte)FAST_TO_INT((real32)color[1] * CLAMP(alpha, 0.0f, 0.92f)); color[3] = (ubyte)FAST_TO_INT(fade * (real32)color[3] * CLAMP(alpha, 0.0f, 1.0f)); #endif } }
const Matrix<double> Line::effectivePosA() const { return p_position_a + vecNormalize(p_position_a - p_position_b) * p_offset_a; }
const Matrix<double> Line::effectivePosB() const { return p_position_b + vecNormalize(p_position_b - p_position_a) * p_offset_b; }
void doKamikazeAttack(Ship *ship,SpaceObjRotImpTarg *target) { real32 mag,dist,range,shipvel; vector destination,trajectory,heading,shipheading,EinsteinVelocity; ShipStaticInfo *shipstaticinfo = ship->staticinfo; vecSub(trajectory,target->collInfo.collPosition,ship->posinfo.position); mag = vecMagnitudeSquared(trajectory); dist = fsqrt(mag); destination = trajectory; vecNormalize(&destination); heading = destination; //this hokey fudge factor is needed so the kamikaze ship doesn't //slow down as it reaches its destination mag = dist + 500.0f; vecScalarMultiply(destination,destination,mag); vecAddTo(destination,target->collInfo.collPosition); range = RangeToTargetGivenDist(ship,target,dist); switch(ship->kamikazeState) { case K_Start: //if within a threshold range bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); if(range < 500.0f) { //calculate flyby dist matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys); vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist); vecAdd(ship->kamikazeVector,shipheading,target->collInfo.collPosition); ship->kamikazeState = K_TurnAround; } ship->kamikazeState = K_Ram; break; case K_Ram: if (range < 400.0f) { ship->kamikazeState = K_Yell; } case K_Ram2: //lets use...mmmmm..twister theor...no...relativity vecSub(EinsteinVelocity,ship->posinfo.velocity,target->posinfo.velocity); shipvel = fsqrt(vecMagnitudeSquared(EinsteinVelocity)); if(ship->shiptype == MinelayerCorvette) { ((MinelayerCorvetteSpec *)(ship->ShipSpecifics))->mineaistate = MINE_DROP_ATTACK; } else if (ship->shiptype == DefenseFighter) { goto dontshoot; } if (isShipStaticInterceptor(shipstaticinfo)) { if (range < shipstaticinfo->bulletRange[ship->tacticstype]) { GenericInterceptorStatics *interceptorstat = (GenericInterceptorStatics *)shipstaticinfo->custstatinfo; uword targetIndex; if (target->objtype == OBJ_ShipType) { targetIndex = (uword)((ShipStaticInfo *)target->staticinfo)->shipclass; } else { targetIndex = (uword)NUM_CLASSES; } if (GenericInterceptorCanFire(ship,target,&trajectory,interceptorstat->triggerHappy[ship->tacticstype][targetIndex])) { ship->staticinfo->custshipheader.CustShipFire(ship,target); } } } else { gunShootGunsAtTarget(ship,target,range,&trajectory); } dontshoot: aishipFlyToPointAvoidingObjs(ship,&destination,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f); if(range < 1500.0f) { bitSet(ship->specialFlags,SPECIAL_KamikazeCrazyFast); } else { bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); } /* if(range < 400.0f && (shipvel < ship->staticinfo->staticheader.maxvelocity*0.7f || vecDotProduct(trajectory,heading) < 0)) { //ship is inside 400.0f, and isn't faceing ship, or isn't //going fast enough //calculate flyby dist matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys); vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist); vecAdd(ship->kamikazeVector,shipheading,target->posinfo.position); ship->kamikazeState = K_TurnAround; } */ break; case K_TurnAround: bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); aishipFlyToPointAvoidingObjs(ship,&ship->kamikazeVector,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f); if(MoveReachedDestinationVariable(ship,&ship->kamikazeVector,300.0f)) ship->kamikazeState = K_TurnAround2; break; case K_TurnAround2: bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); if(aitrackHeadingWithFlags(ship,&heading,0.90f,AITRACKHEADING_IGNOREUPVEC)) ship->kamikazeState = K_Ram; break; case K_Yell: // speechEvent(ship, COMM_LInt_Kamikaze, 0); battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_Kamikaze, ship, SOUND_EVENT_DEFAULT); ship->kamikazeState = K_Ram2; break; } //fire guns here... // // //Sound note: Could put in kamikaze state change here after // getting to within a certain distance of target // // ask bryce how to... }
void DrawGLScene5() { Vec v1,v2,v3,v4,v5,norm; glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION,LightPosition); glTranslatef(-1.5f,0.0f,-6.0f); glRotatef(rtri,0.0f,1.0f,0.0f); glColor3f(0.8f,0.0f,0.0f); glBegin(GL_TRIANGLES); //Notice the process here... //1. build verts //2. make 2 vectors //3. find cross product. that's the normal //4. normalize it to a length of 1 vecMake( 0.0f, 1.0f, 0.0f, v1); vecMake(-1.0f,-1.0f, 1.0f, v2); vecMake( 1.0f,-1.0f, 1.0f, v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake( 1.0f,-1.0f, 1.0f,v2); vecMake( 1.0f,-1.0f,-1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake( 1.0f,-1.0f,-1.0f,v2); vecMake(-1.0f,-1.0f,-1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake(-1.0f,-1.0f,-1.0f,v2); vecMake(-1.0f,-1.0f, 1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); glEnd(); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); glTranslatef(1.5f,0.0f,-7.0f); glRotatef(rquad,1.0f,1.0f,1.0f); glColor3f(0.0f,0.5f,1.0f); glBegin(GL_QUADS); //top //notice the normal being set glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // bottom of cube glNormal3f( 0.0f, -1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // front of cube glNormal3f( 0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // back of cube. glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // left of cube glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // Right of cube glNormal3f( 1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); glEnd(); rtri+=2.0f; rquad-=1.0f; }
void addMonkeyResearchShipChangePosition(Ship *dockwith, Ship *ship,sdword dockindex) { DockStaticPoint *dockwithstaticpoint; vector coneheadingInWorldCoordSysDockWith,DockWithHeading,destination,DockWithUp,destinationoffset; vector desiredHeading,desiredUp,conepositionInWorldCoordSysDockWith,tmpvec; real32 theta; matrix rotmatrix,tmpmat; ResearchShipStatics *resstatics; resstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; dbgAssertOrIgnore(dockwith != NULL); //if we're calling this there should be another reserach station available somewhere if(ship->shiprace == R1) { dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R1final_dock_distance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R1final_dock_distance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R1final_dock_distance; vecAdd(destination,dockwith->posinfo.position, destinationoffset); if(((ResearchShipSpec *)ship->ShipSpecifics)->pie_plate_num == 0) { //ship is docking on'a'top so add upwards factor matGetVectFromMatrixCol1(DockWithUp,dockwith->rotinfo.coordsys); vecScalarMultiply(DockWithUp,DockWithUp,resstatics->R1VerticalDockDistance); vecAdd(destination,destination,DockWithUp); } theta = DEG_TO_RAD(60); matMakeRotAboutX(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); //share a lot of these things...later... ship->rotinfo.coordsys = tmpmat; ship->posinfo.position = destination; } else { //r2 positioning dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matMultiplyMatByVec(&conepositionInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->position); vecAddTo(conepositionInWorldCoordSysDockWith,dockwith->posinfo.position); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R2DockFinalDistance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R2DockFinalDistance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R2DockFinalDistance; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); desiredHeading = coneheadingInWorldCoordSysDockWith; if(dockindex == 0) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 1) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 2) { desiredUp = DockWithHeading; } else if(dockindex == 3) { theta = DEG_TO_RAD(60); matMakeRotAboutZ(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); matGetVectFromMatrixCol1(desiredUp,tmpmat); } else if(dockindex == 4) { destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*100; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*100; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*100; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); matGetVectFromMatrixCol1(desiredUp,dockwith->rotinfo.coordsys); vecScalarMultiply(desiredHeading,desiredHeading,-1.0f); } else { dbgAssertOrIgnore(FALSE); //shouldget here. } vecNormalize(&desiredUp); matPutVectIntoMatrixCol1(desiredUp,ship->rotinfo.coordsys); vecCrossProduct(tmpvec,desiredHeading,desiredUp); matPutVectIntoMatrixCol2(tmpvec,ship->rotinfo.coordsys); matPutVectIntoMatrixCol3(desiredHeading,ship->rotinfo.coordsys); ship->posinfo.position = destination; ship->posinfo.velocity.x = 0.0f; ship->posinfo.velocity.y = 0.0f; ship->posinfo.velocity.z = 0.0f; } }
void defensefightertargetbullet(Ship *ship, Bullet *bullettotarget) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; DefenseFighterStatics *defensefighterstatics; DefenseStruct *newdefensestruct; Bullet *laser; GunStatic *gunstatic; Gun *gun; ShipStaticInfo *shipstatic; vector positionInWorldCoordSys,tempvec; real32 floatDamage; udword intDamage; udword intVelocity; udword intLength; etgeffectstatic *stat; etglod *etgLOD; sdword LOD; Effect *newEffect; #ifdef HW_BUILD_FOR_DEBUGGING /* dbgMessagef("B: %d %x %x %f %f %f %x %f %x",universe.univUpdateCounter, bullettotarget->flags, bullettotarget->owner, bullettotarget->timelived, bullettotarget->damage, bullettotarget->damageFull, bullettotarget->SpecialEffectFlag, bullettotarget->BulletSpeed, bullettotarget); */ #endif gun = &ship->gunInfo->guns[0]; gunstatic = gun->gunstatic; shipstatic = (ShipStaticInfo *)ship->staticinfo; defensefighterstatics = (DefenseFighterStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; bitSet(bullettotarget->SpecialEffectFlag, 0x0002); //set the flag laser = memAlloc(sizeof(Bullet),"Bullet",0); memset(laser,0,sizeof(Bullet)); // for safety laser->objtype = OBJ_BulletType; laser->flags = 0; laser->staticinfo = NULL; ClearNode(laser->renderlink); laser->currentLOD = ship->currentLOD; laser->cameraDistanceSquared = ship->cameraDistanceSquared; laser->soundType = gunstatic->gunsoundtype; laser->bulletType = BULLET_Laser; laser->owner = ship; laser->gunowner = gun; laser->target = NULL; laser->bulletColor = etgBulletColor[shipstatic->shiprace][laser->soundType]; laser->bulletmass = 0.0f; //gunstatic->bulletmass; laser->lengthmag = 600.0f; laser->damage = frandombetween(defensefighterstatics->DamageReductionLow, defensefighterstatics->DamageReductionHigh); laser->timelived = 0.0f; laser->totallifetime = 100.0f; //laser will only live for a sec anyways... laser->SpecialEffectFlag = 0; laser->traveldist = gunstatic->bulletlength; laser->beamtraveldist = gunstatic->bulletlength; //SET_MOVING_LINEARLY(laser->posinfo.isMoving); //laser->posinfo.haventCalculatedDist = TRUE; laser->DFGFieldEntryTime = 0.0f; matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position); vecAdd(laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position); vecSub(laser->lengthvec, bullettotarget->posinfo.position, laser->posinfo.position); // heading tempvec = laser->lengthvec; vecNormalize(&tempvec); //matMultiplyMatByVec(&gunheadingInWorldCoordSys, &ship->rotinfo.coordsys, &tempvec); //laser->bulletheading = gunheadingInWorldCoordSys; laser->bulletheading = tempvec; matCreateCoordSysFromHeading(&laser->rotinfo.coordsys,&tempvec); vecZeroVector(laser->posinfo.velocity); //Laser effect... floatDamage = (real32)laser->damage; intDamage = TreatAsUdword(floatDamage); intVelocity = TreatAsUdword(gunstatic->bulletspeed); intLength = TreatAsUdword(gunstatic->bulletlength); //create an effect for bullet, if applicable etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunBullet];//get pointer to bullet effect //etgLOD = etgGunEventTable[0][gunstatic->gunsoundtype][EGT_GunBullet];//get pointer to bullet effect //in future change back to proper one above... if (etgLOD != NULL) { if (bullettotarget != NULL) { LOD = min(ship->currentLOD, bullettotarget->currentLOD); } else { LOD = ship->currentLOD; } if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgBulletEffectsEnabled && etgEffectsEnabled && !etgFrequencyExceeded(stat)) #else if (stat != NULL && etgBulletEffectsEnabled && !etgFrequencyExceeded(stat)) #endif { laser->effect = etgEffectCreate(stat, laser, NULL, NULL, NULL, 1.0f, EAF_AllButNLips, 3, intDamage, intVelocity, intLength); // univAddObjToRenderListIf((SpaceObj *)laser->effect,(SpaceObj *)ship); // add to render list if parent ship is in render list //do length calculations :) ((real32 *)laser->effect->variable)[ETG_LengthVariable] = fsqrt(vecMagnitudeSquared(laser->lengthvec)); } else { laser->effect = NULL; //play no effect for this bullet } // laser->effect = NULL; //need for render...add later? laser->hitEffect = etgGunEventTable[shipstatic->shiprace][bullettotarget->gunowner->gunstatic->gunsoundtype][EGT_BulletDestroyed];//get pointer to bullet effect if (ship->soundevent.burstHandle < 0) { soundEventBurstFire(ship, gun); } etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunFire];//get pointer to bullet effect if (etgLOD != NULL) { LOD = ship->currentLOD; if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgEffectsEnabled && etgFireEffectsEnabled && !etgFrequencyExceeded(stat)) #else if (stat != NULL && etgFireEffectsEnabled && !etgFrequencyExceeded(stat)) #endif { //if there is a gun fire effect newEffect = etgEffectCreate(stat, laser, NULL, NULL, NULL, 1.0f, EAF_AllButNLips, 1, intDamage); // univAddObjToRenderListIf((SpaceObj *)newEffect,(SpaceObj *)ship); // add to render list if parent ship is in render list } /* //spawn bullet hitting effect etgLOD = etgTractorBeamEffectTable[ship->shiprace]; //etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunFire];//get pointer to bullet effect if (etgLOD != NULL) { LOD = ship->currentLOD; if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgEffectsEnabled) #else if (stat != NULL) #endif { //if there is a gun fire effect // size = etgEffectSize(stat->nParticleBlocks);//compute size of effect size = stat->effectSize; newEffect = memAlloc(size, "DefenseFHittingEffect", 0); //allocate the new effect newEffect->objtype = OBJ_EffectType; newEffect->flags = SOF_Rotatable | SOF_AttachVelocity | SOF_AttachPosition | SOF_AttachCoordsys; newEffect->staticinfo = (StaticInfo *)stat; ClearNode(newEffect->renderlink); newEffect->currentLOD = LOD; newEffect->cameraDistanceSquared = ship->cameraDistanceSquared; newEffect->timeElapsed = 0.0f; //brand new heavies floatDamage = 30.0f; intDamage = TreatAsUdword(floatDamage); newEffect->rotinfo.coordsys = bullettotarget->rotinfo.coordsys; newEffect->posinfo.position = bullettotarget->posinfo.position; //start at same spot as bullet newEffect->posinfo.velocity = bullettotarget->posinfo.velocity; //start at same spot as bullet etgEffectCodeStart(stat, newEffect, 1, intDamage);//get the code a-runnin' SET_MOVING_IMMOBILE(newEffect->posinfo.isMoving); newEffect->posinfo.haventCalculatedDist = TRUE; univUpdateObjRotInfo((SpaceObjRot *)newEffect); // newEffect->owner = NULL; // nothing owns this effect newEffect->owner = (Ship *) bullettotarget; listAddNode(&universe.SpaceObjList,&(newEffect->objlink),newEffect); univAddObjToRenderListIf((SpaceObj *)newEffect,(SpaceObj *)ship); // add to render list if parent ship is in render list } */ //Not sure If I need to add... listAddNode(&universe.SpaceObjList,&(laser->objlink),laser); listAddNode(&universe.BulletList,&(laser->bulletlink),laser); univAddObjToRenderListIf((SpaceObj *)laser,(SpaceObj *)ship); // add to render list if parent ship is in render list newdefensestruct = memAlloc(sizeof(DefenseStruct),"DS(DefenseStruct)",Pyrophoric); newdefensestruct->bullet = bullettotarget; newdefensestruct->CoolDown = FALSE; newdefensestruct->CoolDownTime = 0.0f; newdefensestruct->LaserDead = FALSE; listAddNode(&spec->DefenseList,&newdefensestruct->bulletnode,newdefensestruct); newdefensestruct->laser = laser; if(bitTest(ship->flags,SOF_CloakGenField)) { bitSet(ship->flags,SOF_DeCloaking); bitClear(ship->flags,SOF_Cloaked); bitClear(ship->flags,SOF_Cloaking); } }
void DefenseFighterHouseKeep(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; DefenseFighterStatics *defensefighterstatics; Node *bulletnode; Node *tempnode; DefenseStruct *defensestruct; vector seperationvector; vector tempvec,rot_vector; GunStatic *gunstatic; Gun *gun; vector positionInWorldCoordSys; gun = &ship->gunInfo->guns[0]; gunstatic = gun->gunstatic; defensefighterstatics = (DefenseFighterStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; bulletnode = spec->DefenseList.head; while (bulletnode != NULL) { //as long as theres a bullet to deal with defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode); /* if (defensestruct->bullet) dbgMessagef("DS: %d %f %d %f %d %d", universe.univUpdateCounter, defensestruct->bullet->collOptimizeDist, defensestruct->laser ? 1:0, defensestruct->CoolDownTime, defensestruct->CoolDown ? 1:0, defensestruct->LaserDead ? 1:0); else dbgMessagef("DS: %d N %d %f %d %d", universe.univUpdateCounter, defensestruct->laser ? 1:0, defensestruct->CoolDownTime, defensestruct->CoolDown ? 1:0, defensestruct->LaserDead ? 1:0);*/ if(!defensestruct->CoolDown) { //laser cannon isn't cooling down, so continue tracking if (defensestruct->bullet == NULL || defensestruct->bullet->damage <= 0) { //bullet is already dead...don't kill it again defensestruct->bullet = NULL; //destroy pointer... if (defensestruct->laser != NULL) { defensestruct->laser->timelived =10000.0f; //kill laser } defensestruct->LaserDead = TRUE; //set killed flag defensestruct->laser=NULL; defensestruct->CoolDown = TRUE; //begin laser cooldown defensestruct->CoolDownTime = 0.0f; //reset to 0 for cooldown count bulletnode=bulletnode->next; continue; } if((universe.univUpdateCounter & defensefighterstatics->DamageRate) == 0) { // Time to do damage... //Do damage to bullet defensestruct->bullet->damage = (defensestruct->bullet->damage - frandombetween(defensefighterstatics->DamageReductionLow,defensefighterstatics->DamageReductionHigh)); if(defensestruct->bullet->damage <= 0) { //bullet is destroyed DefenseFighterDestroyedABullet(ship, defensestruct->bullet, defensestruct->laser); defensestruct->bullet->damage = 0; //cap at 0; defensestruct->bullet = NULL; //destroy pointer... //dbgMessagef("Defense Fighter Destroyed A Bullet."); if (defensestruct->laser != NULL) { defensestruct->laser->timelived =10000.0f; //kill laser } defensestruct->LaserDead = TRUE; //set killed flag if(defensestruct->laser->effect != NULL) { univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect); } defensestruct->laser=NULL; defensestruct->CoolDown = TRUE; //begin laser cooldown defensestruct->CoolDownTime = 0.0f; //reset to 0 for cooldown count } } if(defensestruct->laser != NULL) { //check if bullet is still in range and infront... if((universe.univUpdateCounter & defensefighterstatics->RangeCheckRate) == 0) { //time to check if in front vecSub(seperationvector, ship->posinfo.position, defensestruct->bullet->posinfo.position); if(vecMagnitudeSquared(seperationvector) > ship->staticinfo->bulletRangeSquared[ship->tacticstype]) { //bullet is out of range defensestruct->laser->timelived =10000.0f; //kill laser defensestruct->LaserDead = TRUE; //set killed flag if(defensestruct->laser->effect != NULL) { univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect); } defensestruct->laser=NULL; //dbgMessagef("Bullet out of range."); bitClear(defensestruct->bullet->SpecialEffectFlag,0x0002); defensestruct->CoolDown = TRUE; //begin laser cooldown defensestruct->bullet = NULL; //set target to NULL so it isn't referenced again! defensestruct->CoolDownTime = 0.0f; //reset to 0 for cooldown count } else if(!defensefighterCheckInFront(ship, defensestruct->bullet)) { //if bullet ISN'T in front defensestruct->laser->timelived =10000.0f; //kill laser defensestruct->LaserDead = TRUE; //set killed flag if(defensestruct->laser->effect != NULL) { univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect); } defensestruct->laser=NULL; //dbgMessagef("Bullet Not infront anymore...stop tracking."); if(defensefighterstatics->MultipleTargettingofSingleBullet) { bitClear(defensestruct->bullet->SpecialEffectFlag,0x0002); } defensestruct->CoolDown = TRUE; //begin laser cooldown defensestruct->bullet = NULL; //set target to NULL so it isn't referenced again! defensestruct->CoolDownTime = 0.0f; //reset to 0 for cooldown count } } } //This code is for the sake of the visual effect which STILL won't work //properly!!! So it is temperary only! if(defensestruct->laser != NULL) { //update bullent info...for visual effect dbgAssertOrIgnore(defensestruct->bullet != NULL); matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position); vecAdd(defensestruct->laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position); vecSub(defensestruct->laser->lengthvec, defensestruct->bullet->posinfo.position, defensestruct->laser->posinfo.position); // heading tempvec = defensestruct->laser->lengthvec; vecNormalize(&tempvec); //matMultiplyMatByVec(&gunheadingInWorldCoordSys, &ship->rotinfo.coordsys, &tempvec); //laser->bulletheading = gunheadingInWorldCoordSys; defensestruct->laser->bulletheading = tempvec; matCreateCoordSysFromHeading(&defensestruct->laser->rotinfo.coordsys,&tempvec); if(defensestruct->laser->effect != NULL) { //adjust length ((real32 *)defensestruct->laser->effect->variable)[ETG_LengthVariable] = fsqrt(vecMagnitudeSquared(defensestruct->laser->lengthvec)); } } } else { //this laser cannon is cooling, so cool it defensestruct->CoolDownTime += universe.phystimeelapsed; if(defensestruct->CoolDownTime > defensefighterstatics->CoolDownTimePerLaser) { //Laser Terminal has cooled down...so free it up tempnode = bulletnode->next; listDeleteNode(bulletnode); //dbgMessagef("Deleting defense node in CoolDown."); bulletnode = tempnode; continue; } } bulletnode = bulletnode->next; } if (spec->DefenseList.num == 0) { soundEventBurstStop(ship, gun); } //do special rotation if neccessary if(bitTest(ship->dontrotateever,1)) { //matGetVectFromMatrixCol3(rot_vector,ship->rotinfo.coordsys); vecSet(rot_vector,100.0f,0.0f,0.0f); vecAddTo(ship->rotinfo.torque, rot_vector); vecCapVectorSloppy(&ship->rotinfo.rotspeed, defensefighterstatics->max_rot_speed ); spec->rotate_time_counter -= universe.phystimeelapsed; if(spec->rotate_time_counter <= 0.0f) { bitClear(ship->dontrotateever,1); spec->DefenseFighterCanNowRotate = FALSE; } } else if (spec->DefenseFighterCanNowRotate == FALSE) { spec->rotate_time_counter += universe.phystimeelapsed; if(spec->rotate_time_counter >= defensefighterstatics->rotate_recover_time) { spec->DefenseFighterCanNowRotate = TRUE; spec->rotate_time_counter = defensefighterstatics->rotate_time; } } }
void defenseFighterAdjustLaser(Bullet *laser) { //calculates laser direction n' such for rendering... DefenseFighterSpec *spec; // DefenseFighterStatics *defensefighterstatics; Node *bulletnode; DefenseStruct *defensestruct; Ship *ship; vector tempvec; GunStatic *gunstatic; Gun *gun; vector positionInWorldCoordSys; if(laser->owner == NULL) return; ship = laser->owner; gun = &ship->gunInfo->guns[0]; gunstatic = gun->gunstatic; spec= (DefenseFighterSpec *)ship->ShipSpecifics; // defensefighterstatics = (DefenseFighterStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; bulletnode = spec->DefenseList.head; while (bulletnode != NULL) { //as long as theres a bullet to deal with defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode); if(defensestruct->LaserDead == TRUE) { bulletnode = bulletnode->next; continue; } if(laser == defensestruct->laser) { dbgAssertOrIgnore(defensestruct->bullet != NULL); matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position); vecAdd(laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position); vecSub(laser->lengthvec, defensestruct->bullet->posinfo.position, laser->posinfo.position); // heading tempvec = defensestruct->laser->lengthvec; vecNormalize(&tempvec); //matMultiplyMatByVec(&gunheadingInWorldCoordSys, &ship->rotinfo.coordsys, &tempvec); //laser->bulletheading = gunheadingInWorldCoordSys; defensestruct->laser->bulletheading = tempvec; matCreateCoordSysFromHeading(&defensestruct->laser->rotinfo.coordsys,&tempvec); if(defensestruct->laser->effect != NULL) { //adjust length ((real32 *)defensestruct->laser->effect->variable)[ETG_LengthVariable] = fsqrt(vecMagnitudeSquared(defensestruct->laser->lengthvec)); } return; } bulletnode = bulletnode->next; } //we shouldn't get to this point :) //dbgMessagef("Laser Drawn doesn't exist in defense fighter records."); //on further reflection..if we kill the laster...but it doesn't go bye bye, we might get here... }