/*=================================================================== Procedure : AI Spline Movement.... Input : ENEMY * Enemy Output : Nothing ===================================================================*/ void AI_SPLINE_FOLLOWPATH( register ENEMY * Enemy ) { NODE * TNode; NODE * Node1; NODE * Node2; NODE * Node3; NODE * Node4; VECTOR OldPos; VECTOR MoveOffset; float Distance; float WantedDistance; float Time; float Tstep; VECTOR TempPos; int Count; OldPos = Enemy->Object.Pos; if( !Enemy->SplineNode1 ) { //We have to start TNode = Enemy->Object.NearestNode; Enemy->SplineNode1 = (void*) TNode; Enemy->SplineNode2 = (void*) TNode; Node1 = (NODE*)Enemy->SplineNode1; Node2 = (NODE*)Enemy->SplineNode2; Enemy->SplineNode3 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node2 , Node1 , Node2 , NULL , NULL ); Node3 = (NODE*)Enemy->SplineNode3; Enemy->SplineNode4 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL ); } Node1 = (NODE*)Enemy->SplineNode1; Node2 = (NODE*)Enemy->SplineNode2; Node3 = (NODE*)Enemy->SplineNode3; Node4 = (NODE*)Enemy->SplineNode4; WantedDistance = (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) * framelag; Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F; Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos ); Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate * 0.65F) ); Distance = 0.0F; Count = 0; do { Enemy->Timer += Tstep; if( Enemy->Timer >= 1.0F ) { Enemy->SplineNode1 = Enemy->SplineNode2; Enemy->SplineNode2 = Enemy->SplineNode3; Enemy->SplineNode3 = Enemy->SplineNode4; Node1 = (NODE*)Enemy->SplineNode1; Node2 = (NODE*)Enemy->SplineNode2; Node3 = (NODE*)Enemy->SplineNode3; Enemy->Timer = ((Enemy->Timer - 1.0F) * Time); Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos ); Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) ); Enemy->Timer /= Time; Enemy->SplineNode4 = (void*) FindSuitableSplineNodeRandom( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL ); Node4 = (NODE*)Enemy->SplineNode4; Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F; if( Node3 && (Node3->Flags&NODE_TERMINATE) ) { KillUsedEnemy( Enemy ); return; } } TempPos = Enemy->Object.Pos; spline(&Enemy->Object.Pos, Enemy->Timer, &Node1->Pos, &Node2->Pos, &Node3->Pos, &Node4->Pos); Distance += DistanceVector2Vector( &Enemy->Object.Pos , &TempPos); Count++; }while( ( Distance < WantedDistance ) && (Count < 100) ); AI_THINK( Enemy , true , true); if( (Enemy->AIFlags & AI_ANYPLAYERINRANGE) ) { Enemy->PrimaryFireTimer -= framelag; if( Enemy->PrimaryFireTimer < 0.0F ) Enemy->PrimaryFireTimer = 0.0F; if(Enemy->PrimaryFireTimer == 0.0F) { if( !Enemy->TShip ) { AI_DO_SCAN( Enemy ); } Enemy->PrimaryFireTimer = RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME ); } } AI_UPDATEGUNS( Enemy ); MoveOffset.x = Enemy->Object.Pos.x - OldPos.x; MoveOffset.y = Enemy->Object.Pos.y - OldPos.y; MoveOffset.z = Enemy->Object.Pos.z - OldPos.z; Enemy->Object.Group = MoveGroup( &Mloadheader, &OldPos, Enemy->Object.Group, &MoveOffset ); }
/************************************************************************* * This function finds all the connected components induced by the * partitioning vector in wgraph->where and tries to push them around to * remove some of them **************************************************************************/ void EliminateComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor) { int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, other, target, deltawgt; idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt; idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps; nvtxs = graph->nvtxs; xadj = graph->xadj; adjncy = graph->adjncy; vwgt = graph->vwgt; adjwgt = graph->adjwgt; where = graph->where; pwgts = graph->pwgts; touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs)); cptr = idxwspacemalloc(ctrl, nvtxs); cind = idxwspacemalloc(ctrl, nvtxs); perm = idxwspacemalloc(ctrl, nvtxs); todo = idxwspacemalloc(ctrl, nvtxs); maxpwgt = idxwspacemalloc(ctrl, nparts); cpvec = idxwspacemalloc(ctrl, nparts); npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts)); for (i=0; i<nvtxs; i++) perm[i] = todo[i] = i; /* Find the connected componends induced by the partition */ ncmps = -1; first = last = 0; nleft = nvtxs; while (nleft > 0) { if (first == last) { /* Find another starting vertex */ cptr[++ncmps] = first; ASSERT(touched[todo[0]] == 0); i = todo[0]; cind[last++] = i; touched[i] = 1; me = where[i]; npcmps[me]++; } i = cind[first++]; k = perm[i]; j = todo[k] = todo[--nleft]; perm[j] = k; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (where[k] == me && !touched[k]) { cind[last++] = k; touched[k] = 1; } } } cptr[++ncmps] = first; /* printf("I found %d components, for this %d-way partition\n", ncmps, nparts); */ if (ncmps > nparts) { /* There are more components than processors */ /* First determine the max allowed load imbalance */ tvwgt = idxsum(nparts, pwgts); for (i=0; i<nparts; i++) maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt; deltawgt = 5; for (i=0; i<ncmps; i++) { me = where[cind[cptr[i]]]; /* Get the domain of this component */ if (npcmps[me] == 1) continue; /* Skip it because it is contigous */ /*printf("Trying to move %d from %d\n", i, me); */ /* Determine the weight of the block to be moved and abort if too high */ for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) cwgt += vwgt[cind[j]]; if (cwgt > .30*pwgts[me]) continue; /* Skip the component if it is over 30% of the weight */ /* Determine the connectivity */ idxset(nparts, 0, cpvec); for (j=cptr[i]; j<cptr[i+1]; j++) { ii = cind[j]; for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) cpvec[where[adjncy[jj]]] += adjwgt[jj]; } cpvec[me] = 0; target = -1; for (j=0; j<nparts; j++) { if (cpvec[j] > 0 && (cwgt < deltawgt || pwgts[j] + cwgt < maxpwgt[j])) { if (target == -1 || cpvec[target] < cpvec[j]) target = j; } } /* printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/ if (target != -1) { /* Assign all the vertices of 'me' to 'target' and update data structures */ INC_DEC(pwgts[target], pwgts[me], cwgt); npcmps[me]--; MoveGroup(ctrl, graph, nparts, target, i, cptr, cind); } } } idxwspacefree(ctrl, nparts); idxwspacefree(ctrl, nparts); idxwspacefree(ctrl, nparts); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); }
bool QueueEditor::InternEditList(ItemList* itemList, IdList* idList, DownloadQueue::EEditAction action, int offset, const char* text) { ItemList workItems; if (!itemList) { itemList = &workItems; PrepareList(itemList, idList, action, offset); } switch (action) { case DownloadQueue::eaFilePauseAllPars: case DownloadQueue::eaFilePauseExtraPars: PauseParsInGroups(itemList, action == DownloadQueue::eaFilePauseExtraPars); break; case DownloadQueue::eaGroupMerge: return MergeGroups(itemList); case DownloadQueue::eaGroupSort: return SortGroups(itemList, text); case DownloadQueue::eaFileSplit: return SplitGroup(itemList, text); case DownloadQueue::eaFileReorder: ReorderFiles(itemList); break; default: for (EditItem& item : itemList) { switch (action) { case DownloadQueue::eaFilePause: PauseUnpauseEntry(item.m_fileInfo, true); break; case DownloadQueue::eaFileResume: PauseUnpauseEntry(item.m_fileInfo, false); break; case DownloadQueue::eaFileMoveOffset: case DownloadQueue::eaFileMoveTop: case DownloadQueue::eaFileMoveBottom: MoveEntry(item.m_fileInfo, item.m_offset); break; case DownloadQueue::eaFileDelete: DeleteEntry(item.m_fileInfo); break; case DownloadQueue::eaGroupSetPriority: SetNzbPriority(item.m_nzbInfo, text); break; case DownloadQueue::eaGroupSetCategory: case DownloadQueue::eaGroupApplyCategory: SetNzbCategory(item.m_nzbInfo, text, action == DownloadQueue::eaGroupApplyCategory); break; case DownloadQueue::eaGroupSetName: SetNzbName(item.m_nzbInfo, text); break; case DownloadQueue::eaGroupSetDupeKey: case DownloadQueue::eaGroupSetDupeScore: case DownloadQueue::eaGroupSetDupeMode: SetNzbDupeParam(item.m_nzbInfo, action, text); break; case DownloadQueue::eaGroupSetParameter: SetNzbParameter(item.m_nzbInfo, text); break; case DownloadQueue::eaGroupMoveTop: case DownloadQueue::eaGroupMoveBottom: case DownloadQueue::eaGroupMoveOffset: MoveGroup(item.m_nzbInfo, item.m_offset); break; case DownloadQueue::eaGroupPause: case DownloadQueue::eaGroupResume: case DownloadQueue::eaGroupPauseAllPars: case DownloadQueue::eaGroupPauseExtraPars: EditGroup(item.m_nzbInfo, action, offset, text); break; case DownloadQueue::eaGroupDelete: case DownloadQueue::eaGroupParkDelete: case DownloadQueue::eaGroupDupeDelete: case DownloadQueue::eaGroupFinalDelete: if (item.m_nzbInfo->GetKind() == NzbInfo::nkUrl) { DeleteUrl(item.m_nzbInfo, action); } else { EditGroup(item.m_nzbInfo, action, offset, text); } default: // suppress compiler warning "enumeration not handled in switch" break; } } } return itemList->size() > 0; }