void CGroupAI::FindNewJob(int unit) { UnitInfo* info=myUnits[unit]; bool isFactory=info->moveSpeed==0; const deque<Command>* curCommands=aicb->GetCurrentUnitCommands(unit); if(!isFactory && info->lastGivenOrder && !curCommands->empty()){ if(info->lastGivenOrder>0 && curCommands->front().id!=CMD_GUARD){ QuedBuilding* qb=quedBuildngs[info->lastGivenOrder]; int foundUnits[1000]; int num=aicb->GetFriendlyUnits(foundUnits,qb->pos,10); for(int a=0;a<num;++a){ const UnitDef* ud=aicb->GetUnitDef(foundUnits[a]); if(ud->id==-qb->type){ //ok found the right unit float health=aicb->GetUnitHealth(foundUnits[a]); float maxHealth=aicb->GetUnitMaxHealth(foundUnits[a]); qb->buildTimeLeft=buildOptions[qb->type]->buildTime*((maxHealth-health)/maxHealth); //we have no direct access to the current build status of a unit so we assumes that the health is a good indicator break; } } qb->buildTimeLeft=buildOptions[qb->type]->buildTime; //didnt find a unit so assume we havent started building return; } if(info->lastGivenOrder<0) return; } if(isFactory && curCommands->size()){ return; } if(info->lastGivenOrder){ // SendTxt("Free unit with order %i %i",unit,info->lastGivenOrder); if(info->lastGivenOrder>0){ FinishBuilderTask(unit,true); } else { SendTxt("Free unit with guard order? %i %i",unit,info->lastGivenOrder); if(myUnits.find(-info->lastGivenOrder)!=myUnits.end()){ myUnits[-info->lastGivenOrder]->unitsGuardingMe.erase(unit); } info->lastGivenOrder=0; } } float bestValue=0; int bestJob=0; if(!isFactory){ //mobile builder float3 myPos=aicb->GetUnitPos(unit); for(map<int,QuedBuilding*>::iterator qbi=quedBuildngs.begin();qbi!=quedBuildngs.end();++qbi){ //check for building to build QuedBuilding* qb=qbi->second; bool canBuildThis=info->possibleBuildOrders.find(qb->type)!=info->possibleBuildOrders.end(); if(canBuildThis || !qb->unitsOnThis.empty()){ //can we build this directly or is there someone who can start if for us float buildTime=qb->buildTimeLeft/(qb->totalBuildSpeed+info->buildSpeed); float moveTime=max(0.01f,((qb->pos-myPos).Length()-150)/info->moveSpeed*10); float travelMod=buildTime/(buildTime+moveTime); //units prefer stuff with low travel time compared to build time float finishMod=buildOptions[qb->type]->buildTime/(qb->buildTimeLeft+buildOptions[qb->type]->buildTime*0.1f); //units prefer stuff that is nearly finished float canBuildThisMod=canBuildThis?1.5f:1; //units prefer to do stuff they have in their build options (less risk of guarded unit dying etc) float ageMod=20+sqrtf((float)(frameNum+1)-qb->startFrame); // float buildSpeedMod=info->buildSpeed/(qb->totalBuildSpeed+info->buildSpeed); float value=finishMod*canBuildThisMod*travelMod*ageMod; /* char c[6000]; sprintf(c,"value %f %f",moveTime,buildTime); aicb->SendTextMsg(c,0); */ if(value>bestValue){ bestValue=value; if(!qb->unitsOnThis.empty()) bestJob=-*qb->unitsOnThis.begin(); //negative number=pick a unit to guard else bestJob=qbi->first; //positive number=do this build project } } } for(map<int,UnitInfo*>::iterator ui=myUnits.begin();ui!=myUnits.end();++ui){ //find factories to guard if(ui->second->moveSpeed==0 && !aicb->GetCurrentUnitCommands(ui->first)->empty()){ float moveTime=max(1.0f,((aicb->GetUnitPos(ui->first)-myPos).Length()-150)/info->moveSpeed*2); float value=3.0f*(ui->second->buildSpeed/(ui->second->totalGuardSpeed+ui->second->buildSpeed))/moveTime; if(value>bestValue && ui->second->unitsGuardingMe.size()<5){ bestValue=value; bestJob=-ui->first; } } } if(bestJob){ //we have found something to do // SendTxt("Best job found %i %i %.2f",unit,bestJob,bestValue); info->lastGivenOrder=bestJob; Command c; if(bestJob>0){ //build building QuedBuilding* qb=quedBuildngs[bestJob]; c.id=qb->type; c.params.push_back(qb->pos.x); c.params.push_back(qb->pos.y); c.params.push_back(qb->pos.z); qb->totalBuildSpeed+=info->buildSpeed; qb->unitsOnThis.insert(unit); } else { //guard unit c.id=CMD_GUARD; c.params.push_back((float)-bestJob); UnitInfo* guardInfo=myUnits[-bestJob]; guardInfo->unitsGuardingMe.insert(unit); guardInfo->totalGuardSpeed+=info->buildSpeed; if(guardInfo->moveSpeed!=0){ QuedBuilding* qb=quedBuildngs[guardInfo->lastGivenOrder]; qb->totalBuildSpeed+=info->buildSpeed; } } aicb->GiveOrder(unit,&c); } } else { //factory CommandDescription* bestCommandDescription; for(std::vector<CommandDescription>::iterator cdi=commands.begin();cdi!=commands.end();++cdi){ if(cdi->type==CMDTYPE_ICON && info->possibleBuildOrders.find(cdi->id)!=info->possibleBuildOrders.end()){ //we can build this stuff float value=(float)rand()*buildOptions[cdi->id]->numQued; //the probability to pick a certain unit to build is linear to the number of qued, maybe use some better choose method ? if(value>bestValue){ bestValue=value; bestCommandDescription=&*cdi; bestJob=cdi->id; } } } if(bestJob){ Command c; c.id=bestJob; c.options=0; aicb->GiveOrder(unit,&c); // info->lastGivenOrder=bestJob; UpdateFactoryIcon(bestCommandDescription,--buildOptions[bestJob]->numQued); callback->UpdateIcons(); } } }
////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CTestBench::CTestBench(QWidget *parent) : QDialog(parent), ui(new Ui::CTestBench) { m_Active = false; m_2DPixmap = QPixmap(0,0); m_OverlayPixmap = QPixmap(0,0); m_Size = QSize(0,0); m_Rect = QRect(0,0,100,100); m_MaxdB = 10; m_MindB = -120; m_dBStepSize = 10; m_FreqUnits = 1; m_CenterFreq = 0; m_GenSampleRate = 1; m_DisplaySampleRate = 1; m_Span = m_DisplaySampleRate/2; m_FftBufPos = 0; m_GenOn = false; m_PeakOn = false; m_NewDataIsCpx = false; m_CurrentDataIsCpx = true; m_TimeDisplay = false; m_DisplayRate = 10; m_HorzSpan = 100; m_VertRange = 65000; m_TrigLevel = 100; m_TrigBufPos = 0; m_TrigCounter = 0; m_TrigState = TRIGSTATE_WAIT; m_PulseWidth = .01; m_PulsePeriod = .5; m_PulseTimer = 0.0; connect(this, SIGNAL(ResetSignal()), this, SLOT( Reset() ) ); connect(this, SIGNAL(NewFftData()), this, SLOT( DrawFftPlot() ) ); connect(this, SIGNAL(NewTimeData()), this, SLOT( DrawTimePlot() ) ); connect( this, SIGNAL( SendTxt(QString)), this, SLOT( GotTxt(QString) ) ); m_Fft.SetFFTParams( 2048, FALSE, 0.0, m_GenSampleRate); m_Fft.SetFFTAve(0); ui->setupUi(this); setWindowTitle("CuteSDR Test Bench"); ui->textEdit->clear(); m_pTimer = new QTimer(this); connect(m_pTimer, SIGNAL(timeout()), this, SLOT(OnTimer())); #if USE_FILE //test file reading kludge QDir::setCurrent("d:/"); m_File.setFileName(FILE_NAME); if(m_File.open(QIODevice::ReadOnly)) { qDebug()<<"file Opend OK"; if(USE_SVFILE) m_File.seek(0x7e); //SV else if(USE_PERSEUSFILE) m_File.seek(0x7A); //perseus } else qDebug()<<"file Failed to Open"; #endif }