void AI::DoScatter(Ship &ship, Command &command, const list<shared_ptr<Ship>> &ships) { if(!command.Has(Command::FORWARD)) return; double turnRate = ship.TurnRate(); double acceleration = ship.Acceleration(); for(const shared_ptr<Ship> &other : ships) { if(other.get() == &ship) continue; // Check for any ships that have nearly the same movement profile as // this ship and are in nearly the same location. Point offset = other->Position() - ship.Position(); if(offset.LengthSquared() > 400.) continue; if(fabs(other->TurnRate() / turnRate - 1.) > .05) continue; if(fabs(other->Acceleration() / acceleration - 1.) > .05) continue; // Move away from this ship. What side of me is it on? command.SetTurn(offset.Cross(ship.Facing().Unit()) > 0. ? 1. : -1.); return; } }
DrawList::Item::Item(const Animation &animation, Point pos, Point unit, Point blur, float clip, int step) : position{static_cast<float>(pos.X()), static_cast<float>(pos.Y())}, clip(clip), flags(animation.GetSwizzle()) { Animation::Frame frame = animation.Get(step); tex0 = frame.first; tex1 = frame.second; flags |= static_cast<uint32_t>(frame.fade * 256.f) << 8; double width = animation.Width(); double height = animation.Height(); Point uw = unit * width; Point uh = unit * height; if(clip < 1.) { // "clip" is the fraction of its height that we're clipping the sprite // to. We still want it to start at the same spot, though. pos -= uh * ((1. - clip) * .5); position[0] = static_cast<float>(pos.X()); position[1] = static_cast<float>(pos.Y()); uh *= clip; } // (0, -1) means a zero-degree rotation (since negative Y is up). transform[0] = -uw.Y(); transform[1] = uw.X(); transform[2] = -uh.X(); transform[3] = -uh.Y(); // Calculate the blur vector, in texture coordinates. This should be done by // projecting the blur vector onto the unit vector and then scaling it based // on the sprite size. But, the unit vector first has to be normalized (i.e. // divided by the unit vector length), and the sprite size also has to be // multiplied by the unit vector size, so: double zoomCorrection = 4. * unit.LengthSquared(); this->blur[0] = unit.Cross(blur) / (width * zoomCorrection); this->blur[1] = -unit.Dot(blur) / (height * zoomCorrection); }