Speeds find_speeds_no_rot(int rx, int ry, float r_theta, int target_x, int target_y, float target_theta ){ Speeds res; //target pos wrt the robot int tx = target_x - rx; int ty = target_y - ry; float t_theta = standardize_angle(target_theta - r_theta); // rotate the point about r_theta // | cos(theta) sin(theta) | // | -sin(theta) cos(theta) | int temp_x = tx* cos(r_theta) + ty*sin(r_theta); int temp_y = tx*-sin(r_theta) + ty*cos(r_theta); tx = temp_x; ty = temp_y; // at this point, (tx, ty, t_theta) is the coordinates of the target in the robot's system res.left = res.right = pid (tx, 0, 0); res.front = res.rear = pid (ty, 0, 0); res = limit_speed(res); //if (t_theta > MIN_TURN_ANGLE && t_theta < 2*M_PI - MIN_TURN_ANGLE) // { //res = add_rotation(res, t_theta); // loggingObj->ShowMsg(QString("rotating %1") // .arg( t_theta ) // .toAscii() // .data()); //} res = limit_speed(res); return res; }
/** * @brief Updates all the weapons in the layer. * * @param dt Current delta tick. * @param layer Layer to update. */ static void weapons_updateLayer( const double dt, const WeaponLayer layer ) { Weapon **wlayer; int *nlayer; Weapon *w; int i; int spfx; int s; /* Choose layer. */ switch (layer) { case WEAPON_LAYER_BG: wlayer = wbackLayer; nlayer = &nwbackLayer; break; case WEAPON_LAYER_FG: wlayer = wfrontLayer; nlayer = &nwfrontLayer; break; default: WARN("Unknown weapon layer!"); } i = 0; while (i < *nlayer) { w = wlayer[i]; switch (w->outfit->type) { /* most missiles behave the same */ case OUTFIT_TYPE_AMMO: case OUTFIT_TYPE_TURRET_AMMO: if (w->lockon > 0.) /* decrement lockon */ w->lockon -= dt; limit_speed( &w->solid->vel, w->outfit->u.amm.speed, dt ); w->timer -= dt; if (w->timer < 0.) { spfx = -1; /* See if we need armour death sprite. */ if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_ARMOUR)) spfx = outfit_spfxArmour(w->outfit); /* See if we need shield death sprite. */ else if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_SHIELD)) spfx = outfit_spfxShield(w->outfit); /* Add death sprite if needed. */ if (spfx != -1) { spfx_add( spfx, w->solid->pos.x, w->solid->pos.y, w->solid->vel.x, w->solid->vel.y, SPFX_LAYER_BACK ); /* presume back. */ /* Add sound if explodes and has it. */ s = outfit_soundHit(w->outfit); if (s != -1) w->voice = sound_playPos(s, w->solid->pos.x, w->solid->pos.y, w->solid->vel.x, w->solid->vel.y); } weapon_destroy(w,layer); break; } break; case OUTFIT_TYPE_BOLT: case OUTFIT_TYPE_TURRET_BOLT: w->timer -= dt; if (w->timer < 0.) { spfx = -1; /* See if we need armour death sprite. */ if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_ARMOUR)) spfx = outfit_spfxArmour(w->outfit); /* See if we need shield death sprite. */ else if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_SHIELD)) spfx = outfit_spfxShield(w->outfit); /* Add death sprite if needed. */ if (spfx != -1) { spfx_add( spfx, w->solid->pos.x, w->solid->pos.y, w->solid->vel.x, w->solid->vel.y, SPFX_LAYER_BACK ); /* presume back. */ /* Add sound if explodes and has it. */ s = outfit_soundHit(w->outfit); if (s != -1) w->voice = sound_playPos(s, w->solid->pos.x, w->solid->pos.y, w->solid->vel.x, w->solid->vel.y); } weapon_destroy(w,layer); break; } else if (w->timer < w->falloff) w->strength = w->timer / w->falloff; break; /* Beam weapons handled a part. */ case OUTFIT_TYPE_BEAM: case OUTFIT_TYPE_TURRET_BEAM: w->timer -= dt; if (w->timer < 0.) { weapon_destroy(w,layer); break; } /* We use the lockon to tell when we have to create explosions. */ w->lockon -= dt; if (w->lockon < 0.) { if (w->lockon < -1.) w->lockon = 0.100; else w->lockon = -1.; } break; default: WARN("Weapon of type '%s' has no update implemented yet!", w->outfit->name); break; } /* Out of bounds, loop is over. */ if (i >= *nlayer) break; /* Only increment if weapon wasn't deleted. */ if (w == wlayer[i]) { weapon_update(w,dt,layer); if ((i < *nlayer) && (w == wlayer[i])) i++; } } }