// // Apply // void ExplosionObjType::Apply(const Vector &location, UnitObj *unit, Team *team) { MapObjIter::All i(NULL, MapObjIter::FilterData(location, areaOuter)); MapObj *obj; while ((obj = i.Next()) != NULL) { // Is the object within the full damage area F32 dist2 = i.GetProximity2() - areaInner2; S32 deltaHp; //Vector dir = obj->WorldMatrix().posit - location; //dir.Normalize(); if (dist2 <= 0.0f) { // Apply the full damage to this object deltaHp = -damage.GetAmount(obj->MapType()->GetArmourClass()); obj->ModifyHitPoints(deltaHp, unit, team/*, &dir*/); } else { F32 mod = 1.0f - (dist2 * areaDiff2Inv); ASSERT(mod >= 0 && mod <= 1.0f) // Apply a proportional damage to this object //Vector v = dir * mod; deltaHp = -(S32) (((F32) damage.GetAmount(obj->MapType()->GetArmourClass())) * mod); obj->ModifyHitPoints(deltaHp, unit, team/*, &v*/); } // Apply hit modifiers if (ArmourClass::Lookup(damage.GetDamageId(), obj->MapType()->GetArmourClass())) { damage.GetModifiers().Apply(obj); // Set blind target time if (blindTargetTime) { UnitObj *unitObj = Promote::Object<UnitObjType, UnitObj>(obj); if (unitObj) { unitObj->FlushTasks(); unitObj->StartBlindTarget(blindTargetTime); } } // Apply the generic effect StartGenericFX(obj, 0x32FBA304); // "ExplosionObj::ApplyTarget" } // Is there an action to execute if (action && team) { Action::Execute(team, action); } } }
// // Execute // U32 Store::Execute(const U8 *data, Player &player) { const Data *d = (Data *) data; // Create an iterator for (UnitObjList::Iterator i(&player.GetSelectedList()); *i; i++) { // Get the unit UnitObj *unit = **i; // Is this a collector ? if (Tasks::UnitCollect *task = TaskCtrl::PromoteIdle<Tasks::UnitCollect>(unit)) { // Should we search for a place to store the resource if (d->search) { task->Store(); } else { // Convert ID into a pointer if (UnitObj *storeObj = Resolver::Object<UnitObj, UnitObjType>(d->object)) { // If not updating the position, flush tasks incase moving or something if (!d->update && unit->GetActiveTask()) { unit->FlushTasks(); } // Tell this task about the new storage point task->SetStorageObject(storeObj, d->update); } } } } return (sizeof (Data)); }
// // Initial state // void SquadMoveTogether::StateInit() { LOG_DIAG(("SquadMoveTogether: Init")) // Find the slowest unit in the squad and use their traction type U8 traction = 0; F32 bottomSpeed = F32_MAX; // Work out the centre position of the squad Vector location(0.0f, 0.0f, 0.0f); U32 count = 0; SquadObj::UnitList::Iterator i(&subject->GetList()); for (!i; *i; i++) { if ((*i)->Alive()) { // Take this oportunity to reset the units node (*i)->completed = TRUE; (*i)->data = 0; if ((**i)->CanEverMove()) { // Grab the unit so we don't need to continually pound the iterator UnitObj *unit = **i; // Flush its tasks unit->FlushTasks(Tasks::UnitMove::GetConfigBlockingPriority()); // Add its position to the total location.x += unit->WorldMatrix().posit.x; location.z += unit->WorldMatrix().posit.z; count++; // Is this the slowest unit in the squad F32 speed = unit->GetMaxSpeed(); if (speed < bottomSpeed) { bottomSpeed = speed; traction = unit->MapType()->GetTractionIndex(unit->MapType()->GetDefaultLayer()); } } } } if (!count) { Quit(); return; } // Work out the averate location location.x /= count; location.z /= count; location.y = TerrainData::FindFloor(location.x, location.z); // What is the direction from the source (location) to the dest (destination) VectorDir dir; Vector(destination - location).Convert(dir); direction = dir.u; // Build a formation from the units using the direction to the destination Formation::Create(location, direction, subject, 16.0f); // Get the source and destination in terms of cells Point<F32> avg(location.x, location.z); Point<U32> srcCell; WorldCtrl::MetresToCellPoint(avg, srcCell); Point<U32> destCell; WorldCtrl::MetresToCellPoint(Point<F32>(destination.x, destination.z), destCell); switch (subject->GetPathFinder().RequestPath(srcCell.x, srcCell.z, destCell.x, destCell.z, traction)) { case PathSearch::Finder::RR_SUBMITTED: NextState(0xFDE9D5E3); // "Pathing" break; case PathSearch::Finder::RR_SAMECELL: case PathSearch::Finder::RR_OFFMAP: Quit(); return; default: ERR_FATAL(("Unknown path request result")) } }
// // StateInit // void SquadBoard::StateInit() { // Get each of the units in the squad to board transports SquadObj::UnitList::Iterator u(&subject->GetList()); // We could enhance this to use units which are closest to transports etc. // Clear the squad's completed flags for (!u; *u; u++) { (*u)->completed = FALSE; (*u)->task = 0; } // Reset squad iterator !u; for (TransportObjList::Iterator t(&transports); *t; t++) { if ((*t)->Alive()) { TransportObj *transport = **t; U32 slots = transport->TransportType()->GetSpaces(); U32 added = 0; while (slots--) { UnitObjPtr *unitPtr = *u; if (unitPtr) { ASSERT(unitPtr->Alive()) UnitObj *unit = *unitPtr; if (unit->CanEverMove()) { // Tell the unit to board unit->FlushTasks(Tasks::UnitBoard::GetConfigBlockingPriority()); Task *task; // Is this a telepad if (TaskCtrl::PromoteIdle<Tasks::TransportPad>(transport)) { unit->PrependTask(task = new Tasks::UnitMove(unit, transport), GetFlags()); } else { unit->PrependTask(task = new Tasks::UnitBoard(unit, transport), GetFlags()); } (*u)->task = task->GetTaskId(); added++; } else { // This unit can't move so complete it (*u)->completed = TRUE; } } else { break; } // Increment iterator u++; } if (!added) { // No units were added break; } } } // Complete those units which missed out for (; *u; u++) { (*u)->completed = TRUE; } NextState(0x09E5F977); // "Boarding" }