int CChar::NPC_GetAttackContinueMotivation( CChar * pChar, int iMotivation ) const { ADDTOCALLSTACK("CChar::NPC_GetAttackContinueMotivation"); // I have seen fit to attack them. // How much do i want to continue an existing fight ? cowardice ? // ARGS: // iMotivation = My base motivation toward this creature. // // RETURN: // -101 = ? dead meat. (run away) // // 0 = I'm have no interest. // 50 = even match. // 100 = he's a push over. if ( !m_pNPC ) return 0; if ( pChar->IsStatFlag( STATF_DEAD | STATF_INVUL | STATF_Stone )) return( -100 ); if ( m_pNPC->m_Brain == NPCBRAIN_GUARD ) return( 100 ); if ( m_pNPC->m_Brain == NPCBRAIN_BERSERK ) return( iMotivation + 80 - GetDist( pChar )); // less interested the further away they are // Try to stay on one target. if ( Fight_IsActive() && m_Act_Targ == pChar->GetUID()) iMotivation += 8; // Less interested the further away they are. iMotivation -= GetDist( pChar ); if ( !g_Cfg.m_fMonsterFear ) return( iMotivation ); // I'm just plain stronger. iMotivation += ( Stat_GetAdjusted(STAT_STR) - pChar->Stat_GetAdjusted(STAT_STR)); // I'm healthy. int iTmp = GetHealthPercent() - pChar->GetHealthPercent(); if ( iTmp < -50 ) iMotivation -= 50; else if ( iTmp > 50 ) iMotivation += 50; // I'm smart and therefore more cowardly. (if injured) iMotivation -= Stat_GetAdjusted(STAT_INT) / 16; return( iMotivation ); }
GroupTTT::GroupTTT(KPTurn *K1,KPTurn *K2,KPTurn *K3,Segment *s1_, Segment *s2_) { A = K1; B = K2; C = K3; s1 = s1_; s2 = s2_; j1=1; // 1 or -1 //if ((s1->name=="s4")||(s2->name=="s4")) j=-1; ConnectorTurn *ct1,*ct2; ct1=(ConnectorTurn*)A->GetC1(); ct2=(ConnectorTurn*)A->GetC2(); if (ct1->s == s1) s1cA = ct1; else if (ct2->s == s1) s1cA = ct2; else throw "GroupTTT: KPair A not connected to s1"; ct1=(ConnectorTurn*)B->GetC1(); ct2=(ConnectorTurn*)B->GetC2(); if (ct1->s == s1) s1cB = ct1; else if (ct2->s == s1) s1cB = ct2; else throw "GroupTTT: KPair B not connected to s1"; if (ct1->s == s2) s2cB = ct1; else if (ct2->s == s2) s2cB = ct2; else throw "GroupTTT: KPair B not connected to s2"; ct1=(ConnectorTurn*)C->GetC1(); ct2=(ConnectorTurn*)C->GetC2(); if (ct1->s == s2) s2cC = ct1; else if (ct2->s == s2) s2cC = ct2; else throw "GroupTTT: KPair C not connected to s2"; lab=GetDist(s1cA,s1cB); lcb=GetDist(s2cC,s2cB); }
double CSzSSA::SolidsMassFlow() { CSD_Distribution* pSz=GetDist(); if (pSz) return pSz->SolidsMass(pModel->Temp(), pModel->Press(), &pModel->m_Ovr, pModel->SVData()); return m_iSolids>=0 ? pModel->VMass[m_iSolids] : 0; };
flag CSzSSA::ValidateData(ValidateDataBlk & VDB) { flag OK=true; SQSzDist1 *pSz=SQSzDist1::Ptr(pModel, false); m_iMethod=pSz ? SSA_FromPSD : SSA_Independent; //if (m_iMethod==SSA_FromPSD) // { // m_bAllowSet=false; // } CSD_Distribution *pDst=GetDist(); if (pDst) { m_bHasPSD=pDst!=NULL; m_iSolids=pDst->PriSzId(0); } else m_bHasPSD=false; SetCI(1, DataSettable() && m_iSolids<0); if (OK) Equilibrate(); return OK; }
void ConvertDataValue(WIDATAITEM *UpdateData, char *Data) { char str[MAX_DATA_LEN]; // convert the unit if (strcmp(Data, Translate("<Error>")) && strcmp(Data, NODATA) && strcmp(Data, Translate(NODATA))) { // temperature if (!strcmp(UpdateData->Name, "Temperature") || !strcmp(UpdateData->Name, "High") || !strcmp(UpdateData->Name, "Low") || !strcmp(UpdateData->Name, "Feel") || !strcmp(UpdateData->Name, "Dewpoint") || !_stricmp(UpdateData->Unit, "C") || !_stricmp(UpdateData->Unit, "F") || !_stricmp(UpdateData->Unit, "K")) { GetTemp(Data, UpdateData->Unit, str); strcpy(Data, str); } // pressure else if (!strcmp(UpdateData->Name, "Pressure") || !_stricmp(UpdateData->Unit, "HPA") || !_stricmp(UpdateData->Unit, "KPA") || !_stricmp(UpdateData->Unit, "MB") || !_stricmp(UpdateData->Unit, "TORR") || !_stricmp(UpdateData->Unit, "IN") || !_stricmp(UpdateData->Unit, "MM")) { GetPressure(Data, UpdateData->Unit, str); strcpy(Data, str); } // speed else if (!strcmp(UpdateData->Name, "Wind Speed") || !_stricmp(UpdateData->Unit, "KM/H") || !_stricmp(UpdateData->Unit, "M/S") || !_stricmp(UpdateData->Unit, "MPH") || !_stricmp(UpdateData->Unit, "KNOTS")) { GetSpeed(Data, UpdateData->Unit, str); strcpy(Data, str); } // visibility else if (!strcmp(UpdateData->Name, "Visibility") || !_stricmp(UpdateData->Unit, "KM") || !_stricmp(UpdateData->Unit, "MILES")) { GetDist(Data, UpdateData->Unit, str); strcpy(Data, str); } // converting case for condition to the upper+lower format else if (!_stricmp(UpdateData->Unit, "COND")) CaseConv(Data); // degree sign else if (!_stricmp(UpdateData->Unit, "DEG")) { if (!opt.DoNotAppendUnit) strcat(Data, opt.DegreeSign); } // percent sign else if (!_stricmp(UpdateData->Unit, "%")) { if (!opt.DoNotAppendUnit) strcat(Data, "%"); } // truncating strings for day/month to 2 or 3 characters else if (!_stricmp(UpdateData->Unit, "DAY") || !_stricmp(UpdateData->Unit, "MONTH")) if (opt.dUnit > 1 && strlen(Data) > opt.dUnit) Data[opt.dUnit] = '\0'; } }
void ConvertDataValue(WIDATAITEM *UpdateData, TCHAR *Data) { TCHAR str[MAX_DATA_LEN]; // convert the unit if (mir_tstrcmp(Data, TranslateT("<Error>")) && mir_tstrcmp(Data, NODATA) && mir_tstrcmp(Data, TranslateTS(NODATA))) { // temperature if (!mir_tstrcmp(UpdateData->Name, _T("Temperature")) || !mir_tstrcmp(UpdateData->Name, _T("High")) || !mir_tstrcmp(UpdateData->Name, _T("Low")) || !mir_tstrcmp(UpdateData->Name, _T("Feel")) || !mir_tstrcmp(UpdateData->Name, _T("Dewpoint")) || !mir_tstrcmpi(UpdateData->Unit, _T("C")) || !mir_tstrcmpi(UpdateData->Unit, _T("F")) || !mir_tstrcmpi(UpdateData->Unit, _T("K"))) { GetTemp(Data, UpdateData->Unit, str); mir_tstrcpy(Data, str); } // pressure else if (!mir_tstrcmp(UpdateData->Name, _T("Pressure")) || !mir_tstrcmpi(UpdateData->Unit, _T("HPA")) || !mir_tstrcmpi(UpdateData->Unit, _T("KPA")) || !mir_tstrcmpi(UpdateData->Unit, _T("MB")) || !mir_tstrcmpi(UpdateData->Unit, _T("TORR")) || !mir_tstrcmpi(UpdateData->Unit, _T("IN")) || !mir_tstrcmpi(UpdateData->Unit, _T("MM"))) { GetPressure(Data, UpdateData->Unit, str); mir_tstrcpy(Data, str); } // speed else if (!mir_tstrcmp(UpdateData->Name, _T("Wind Speed")) || !mir_tstrcmpi(UpdateData->Unit, _T("KM/H")) || !mir_tstrcmpi(UpdateData->Unit, _T("M/S")) || !mir_tstrcmpi(UpdateData->Unit, _T("MPH")) || !mir_tstrcmpi(UpdateData->Unit, _T("KNOTS"))) { GetSpeed(Data, UpdateData->Unit, str); mir_tstrcpy(Data, str); } // visibility else if (!mir_tstrcmp(UpdateData->Name, _T("Visibility")) || !mir_tstrcmpi(UpdateData->Unit, _T("KM")) || !mir_tstrcmpi(UpdateData->Unit, _T("MILES"))) { GetDist(Data, UpdateData->Unit, str); mir_tstrcpy(Data, str); } // elevation else if (!mir_tstrcmp(UpdateData->Name, _T("Elevation")) || !mir_tstrcmpi(UpdateData->Unit, _T("FT")) || !mir_tstrcmpi(UpdateData->Unit, _T("M"))) { GetElev(Data, UpdateData->Unit, str); mir_tstrcpy(Data, str); } // converting case for condition to the upper+lower format else if (!mir_tstrcmpi(UpdateData->Unit, _T("COND"))) CaseConv(Data); // degree sign else if (!mir_tstrcmpi(UpdateData->Unit, _T("DEG"))) { if (!opt.DoNotAppendUnit) mir_tstrcat(Data, opt.DegreeSign); } // percent sign else if (!mir_tstrcmpi(UpdateData->Unit, _T("%"))) { if (!opt.DoNotAppendUnit) mir_tstrcat(Data, _T("%")); } // truncating strings for day/month to 2 or 3 characters else if (!mir_tstrcmpi(UpdateData->Unit, _T("DAY")) || !mir_tstrcmpi(UpdateData->Unit, _T("MONTH"))) if (opt.dUnit > 1 && mir_tstrlen(Data) > opt.dUnit) Data[opt.dUnit] = '\0'; } }
double CSzSSA::SpecificSurfaceAreaMass() { if (m_iMethod==SSA_FromPSD) { CSD_Distribution* pSz=GetDist(); if (pSz) return pSz->SpecificSurfaceAreaM(pModel->Temp(), pModel->Press(), &pModel->m_Ovr, pModel->SVData()); } return m_dSAM; };
double CSzSSA::SpecificSurfaceAreaVol() { if (m_iMethod==SSA_FromPSD) { CSD_Distribution* pSz=GetDist(); if (pSz) return pSz->SpecificSurfaceAreaV(pModel->Temp(), pModel->Press(), &pModel->m_Ovr, pModel->SVData(), pModel->Volume(som_Liq)); } double D=PartDiamFromSAM(); return PartNumPerLiter()*PI*D*D; }
int xCanvas::AddPoint(const xPoint& pt) { if (!m_bStrokeStarted) return -1; xPoint rpt = pt; xPoint rpt_old = m_stroke.points.size() > 0 ? *(m_stroke.points.end()-1) : pt; int dist = GetDist(rpt, rpt_old); if (m_stroke.points.size() > 0 && dist < 2) // 천천히 움직일경우 무시 return -1; // process tablet messages ... uint32 mcnt = m_Tablet.PeekMsgs(); // get latest message rpt.pressure = -1.0f; // init pressure for mouse if (mcnt) { WCMSG msg; m_Tablet.ProcessMsg(mcnt-1, msg); //rpt.x = msg.pos.x; //rpt.y = msg.pos.y; rpt.pressure = (msg.btn_pressure >= 1023) ? 1.0f : float(msg.btn_pressure)/1023.0f;; #ifdef _DEBUG TRACE("##xCanvas::AddPoint: btn_pressure = %d\n", msg.btn_pressure); //if (btn_pressure >= 1024) //Beep(1000 + msg.btn_pressure,5); #endif } //rpt.timeStamp = timeGetTime(); // add new point if (0 == m_stroke.points.size()) // for start point of the curve line { m_stroke.points.push_back(rpt); m_stroke.points.push_back(rpt); m_stroke.points.push_back(rpt); //m_stroke.points.push_back(rpt); } else { m_stroke.points.push_back(rpt); if (m_bAutoDrawing) { Draw(); } } m_stroke.selection = m_stroke.points.size() - 1; return m_stroke.selection; }
int CPointBase::StepLinePath( const CPointBase & ptSrc, int iSteps ) { ADDTOCALLSTACK("CPointBase::StepLinePath"); // Take x steps toward this point. int dx = m_x - ptSrc.m_x; int dy = m_y - ptSrc.m_y; int iDist2D = GetDist( ptSrc ); if ( ! iDist2D ) return 0; m_x = static_cast<short>(ptSrc.m_x + IMULDIV( iSteps, dx, iDist2D )); m_y = static_cast<short>(ptSrc.m_y + IMULDIV( iSteps, dy, iDist2D )); return( iDist2D ); }
int CPointBase::GetDist3D( const CPointBase & pt ) const // Distance between points { ADDTOCALLSTACK("CPointBase::GetDist3D"); // OK, 1 unit of Z is not the same (real life) distance as 1 // unit of X (or Y) int dist = GetDist(pt); // Get the deltas and correct the Z for height first int dz = GetDistZAdj(pt); // Take player height into consideration return maximum(dz, dist); // What the heck? /*double realdist = sqrt(static_cast<double>((dist * dist) + (dz * dz))); return static_cast<int>(( (realdist - floor(realdist)) > 0.5 ) ? (ceil(realdist)) : (floor(realdist)));*/ }
void MIN_SPAN_TREE_PADS::AddTreeToRatsnest( std::vector<RATSNEST_ITEM> &aRatsnestList ) { std::vector<D_PAD*> & padsBuffer = *m_PadsList; int netcode = padsBuffer[0]->GetNet(); // Note: to get edges in minimum spanning tree, // the index value 0 is not used: it is just // the entry point of the minimum spanning tree. // The first edge (i.e. rastnest) starts at index 1 for( int ii = 1; ii < m_Size; ii++ ) { // Create the new ratsnest RATSNEST_ITEM net; net.SetNet( netcode ); net.m_Status = CH_ACTIF | CH_VISIBLE; net.m_Lenght = GetDist(ii); net.m_PadStart = padsBuffer[ii]; net.m_PadEnd = padsBuffer[ GetWhoTo(ii) ]; aRatsnestList.push_back( net ); } }
int CChar::NPC_GetAttackMotivation(CChar *pChar) const { ADDTOCALLSTACK("CChar::NPC_GetAttackMotivation"); // Some sort of monster. // Am I stronger than he is ? Should I continue fighting ? // Take into consideration AC, health, skills, etc.. // RETURN: // < 0 = dead meat. (run away) // 0 = I'm have no interest. // 50 = even match. // 100 = he's a push over. if ( !m_pNPC || !pChar || !pChar->m_pArea ) return 0; if ( pChar->m_pArea->IsFlag(REGION_FLAG_SAFE) ) return 0; int iMotivation = NPC_GetHostilityLevelToward(pChar); if ( iMotivation <= 0 ) return iMotivation; if ( !pChar->Fight_IsAttackable() ) return 0; if ( (m_pNPC->m_Brain == NPCBRAIN_BERSERK) || (m_pNPC->m_Brain == NPCBRAIN_GUARD) ) return 100; // Try to stay on one target if ( Fight_IsActive() && (m_Act_Targ == pChar->GetUID()) ) iMotivation += 10; // Less interested the further away they are iMotivation -= GetDist(pChar); if ( g_Cfg.m_fMonsterFear ) { if ( GetHealthPercent() < 50 ) iMotivation -= 50 + (Stat_GetAdjusted(STAT_INT) / 16); } return iMotivation; }
int DynTimeWarping(const double * prlz, int rlzSize, const double * pptn, int ptnSize, CONTRES* pcres) { long** M = new long*[rlzSize]; memset(M, 0, sizeof(long*) * rlzSize); for (int i = 0; i < rlzSize; i++) M[i] = new long[ptnSize]; double* buf_d = new double[rlzSize]; double* buf_t = new double[rlzSize]; int num = FrmVectSize; int i,j; long val[3]; int del; int res; int T[2][ptnSize]; // int** T = new int[2]; // T[0] = new int[ptnSize]; // T[0] = new int[ptnSize]; double koff; koff=256.0/ptnSize; del=num/3; // Word Spotting M[0][0]=GetDist(pptn,prlz,num); T[0][0]=0; for(j=1; j < ptnSize; j++) { M[0][j]=GetDist(pptn+num*j,prlz,num); M[0][j]+=(M[0][j-1]+(long)koff*(j-1)); T[0][j]=0; } if(M[0][ptnSize-1]/((long)ptnSize*del) > 255) *buf_d=255; else *buf_d=M[0][ptnSize-1]/((long)ptnSize*del); *buf_t=T[0][ptnSize-1]; res=0; for(i=1; i < rlzSize; i++) { M[i][0]=GetDist(pptn,prlz+num*i,num); T[1][0]=0; for(j=1; j < ptnSize; j++) { M[i][j]=GetDist(pptn+num*j,prlz+num*i,num); val[0]=M[i][j-1]; val[1]=M[i-1][j-1]; val[2]=M[i-1][j]; if(val[1] <= val[0] && val[1] <= val[2]) { M[i][j]+=(val[1]+(long)koff*abs(T[0][j-1]-j+1)); T[1][j]=T[0][j-1]+1; } else if(val[0] <= val[1] && val[0] <= val[2]) { M[i][j]+=(val[0]+(long)koff*abs(T[1][j-1]-j+1)); T[1][j]=T[1][j-1]; } else { M[i][j]+=(val[2]+(long)koff*abs(T[0][j]-j)); T[1][j]=T[0][j]+1; } } for(j=0; j < ptnSize; j++) T[0][j]=T[1][j]; if(M[i][ptnSize-1]/((long)ptnSize*del) > 255) *(buf_d+i)=255; else *(buf_d+i)=M[i][ptnSize-1]/((long)ptnSize*del); *(buf_t+i)=T[0][ptnSize-1]; if(*(buf_d+i) <= *(buf_d+res)) res=i; } if(*(buf_d+res) <= 250 && res > 0) { pcres->R=*(buf_d+res); pcres->pos[1]=res; // end of word pcres->pos[0]=res-(*(buf_t+res)); // beg of word pcres->key=1; } else pcres->key=0; delete buf_d; delete buf_t; for (int i = 0; i < rlzSize; i++) delete M[i]; delete M; return(*(buf_d+res)); }
//put into arrays, check orientation... then sort. int averageStoreDistances(double *dists, int *aSegs, double *aDists, double *vort) { //okay, go through the whole big array of distances, setting each on the first pass, then adding, then /2 //also store the distances and the point indices they connect int countStore = 0; for (int x = 0; x < nx; x++) { for (int y = 0; y < ny; y++) { for (int z = 0; z < nz; z++) { //fprintf(stderr, "another point %d %d %d\n", x, y, z); for (int boxX = 0; boxX < numDist; boxX++) { for (int boxY = 0; boxY < numDist; boxY++) { for (int boxZ = 0; boxZ < numDist; boxZ++) { if (!((0==boxX - localLevel)&&(0==boxY - localLevel)&&(0==boxZ - localLevel))) { double thisDist = GetDist(dists, x, y, z, (boxZ + numDist * (boxY + numDist * boxX)) ); //now find other distance this is to. int otherX = (nx + x + boxX - localLevel) % nx; int otherY = (ny + y + boxY - localLevel) % ny; int otherZ = (nz + z + boxZ - localLevel) % nz; int otherBoxX = numDist - boxX - 1; int otherBoxY = numDist - boxY - 1; int otherBoxZ = numDist - boxZ - 1; double otherDist = GetDist(dists, otherX, otherY, otherZ, (otherBoxZ + numDist * (otherBoxY + numDist * otherBoxX)) ); double newDist = (thisDist + otherDist)/2.0; SetDist(dists, newDist, x, y, z, (boxZ + numDist * (boxY + numDist * boxX))); SetDist(dists, newDist, otherX, otherY, otherZ, (otherBoxZ + numDist * (otherBoxY + numDist * otherBoxX)) ); if ((z + nz * (y + ny * x)) < (otherZ + nz * (otherY + ny * otherX)) ) { //fprintf(stderr, "(%d %d %d) (%d %d %d) %e\n", x, y, z, otherX, otherY, otherZ, newDist); //determine orientation now instead of later //throw out poorly defined orientations as well double vX = GetArray(vort, x, y, z, 0); double vY = GetArray(vort, x, y, z, 1); double vZ = GetArray(vort, x, y, z, 2); double signOrient = orientation(x,y,z,otherX,otherY,otherZ,vX,vY,vZ); vX = GetArray(vort, otherX, otherY, otherZ, 0); vY = GetArray(vort, otherX, otherY, otherZ, 1); vZ = GetArray(vort, otherX, otherY, otherZ, 2); double signBackOrient = orientation(otherX,otherY,otherZ,x,y,z,vX,vY,vZ); //fprintf(stderr, "%f %f \n", signOrient,signBackOrient); if (signOrient > 0.0 && signBackOrient < 0.0) { SetAlphaDist(aDists, newDist, countStore); SetAlphaSeg(aSegs, x, countStore, 0, 0); SetAlphaSeg(aSegs, y, countStore, 1, 0); SetAlphaSeg(aSegs, z, countStore, 2, 0); SetAlphaSeg(aSegs, otherX, countStore, 0, 1); SetAlphaSeg(aSegs, otherY, countStore, 1, 1); SetAlphaSeg(aSegs, otherZ, countStore, 2, 1); countStore++; } else if (signOrient < 0.0 && signBackOrient > 0.0) { SetAlphaDist(aDists, newDist, countStore); SetAlphaSeg(aSegs, otherX, countStore, 0, 0); SetAlphaSeg(aSegs, otherY, countStore, 1, 0); SetAlphaSeg(aSegs, otherZ, countStore, 2, 0); SetAlphaSeg(aSegs, x, countStore, 0, 1); SetAlphaSeg(aSegs, y, countStore, 1, 1); SetAlphaSeg(aSegs, z, countStore, 2, 1); countStore++; } } } } } } } } } return countStore; }
bool HullLibrary::CleanupVertices(unsigned int svcount, const btVector3 *svertices, unsigned int stride, unsigned int &vcount, // output number of vertices btVector3 *vertices, // location to store the results. btScalar normalepsilon, btVector3& scale) { if ( svcount == 0 ) return false; m_vertexIndexMapping.resize(0); #define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */ vcount = 0; btScalar recip[3]; if ( scale ) { scale[0] = 1; scale[1] = 1; scale[2] = 1; } btScalar bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; const char *vtx = (const char *) svertices; // if ( 1 ) { for (unsigned int i=0; i<svcount; i++) { const btScalar *p = (const btScalar *) vtx; vtx+=stride; for (int j=0; j<3; j++) { if ( p[j] < bmin[j] ) bmin[j] = p[j]; if ( p[j] > bmax[j] ) bmax[j] = p[j]; } } } btScalar dx = bmax[0] - bmin[0]; btScalar dy = bmax[1] - bmin[1]; btScalar dz = bmax[2] - bmin[2]; btVector3 center; center[0] = dx*btScalar(0.5) + bmin[0]; center[1] = dy*btScalar(0.5) + bmin[1]; center[2] = dz*btScalar(0.5) + bmin[2]; if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) { btScalar len = FLT_MAX; if ( dx > EPSILON && dx < len ) len = dx; if ( dy > EPSILON && dy < len ) len = dy; if ( dz > EPSILON && dz < len ) len = dz; if ( len == FLT_MAX ) { dx = dy = dz = btScalar(0.01); // one centimeter } else { if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. if ( dy < EPSILON ) dy = len * btScalar(0.05); if ( dz < EPSILON ) dz = len * btScalar(0.05); } btScalar x1 = center[0] - dx; btScalar x2 = center[0] + dx; btScalar y1 = center[1] - dy; btScalar y2 = center[1] + dy; btScalar z1 = center[2] - dz; btScalar z2 = center[2] + dz; addPoint(vcount,vertices,x1,y1,z1); addPoint(vcount,vertices,x2,y1,z1); addPoint(vcount,vertices,x2,y2,z1); addPoint(vcount,vertices,x1,y2,z1); addPoint(vcount,vertices,x1,y1,z2); addPoint(vcount,vertices,x2,y1,z2); addPoint(vcount,vertices,x2,y2,z2); addPoint(vcount,vertices,x1,y2,z2); return true; // return cube } else { if ( scale ) { scale[0] = dx; scale[1] = dy; scale[2] = dz; recip[0] = 1 / dx; recip[1] = 1 / dy; recip[2] = 1 / dz; center[0]*=recip[0]; center[1]*=recip[1]; center[2]*=recip[2]; } } vtx = (const char *) svertices; for (unsigned int i=0; i<svcount; i++) { const btVector3 *p = (const btVector3 *)vtx; vtx+=stride; btScalar px = p->getX(); btScalar py = p->getY(); btScalar pz = p->getZ(); if ( scale ) { px = px*recip[0]; // normalize py = py*recip[1]; // normalize pz = pz*recip[2]; // normalize } // if ( 1 ) { unsigned int j; for (j=0; j<vcount; j++) { /// XXX might be broken btVector3& v = vertices[j]; btScalar x = v[0]; btScalar y = v[1]; btScalar z = v[2]; btScalar dx = fabsf(x - px ); btScalar dy = fabsf(y - py ); btScalar dz = fabsf(z - pz ); if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon ) { // ok, it is close enough to the old one // now let us see if it is further from the center of the point cloud than the one we already recorded. // in which case we keep this one instead. btScalar dist1 = GetDist(px,py,pz,center); btScalar dist2 = GetDist(v[0],v[1],v[2],center); if ( dist1 > dist2 ) { v[0] = px; v[1] = py; v[2] = pz; } break; } } if ( j == vcount ) { btVector3& dest = vertices[vcount]; dest[0] = px; dest[1] = py; dest[2] = pz; vcount++; } m_vertexIndexMapping.push_back(j); } } // ok..now make sure we didn't prune so many vertices it is now invalid. // if ( 1 ) { btScalar bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; for (unsigned int i=0; i<vcount; i++) { const btVector3& p = vertices[i]; for (int j=0; j<3; j++) { if ( p[j] < bmin[j] ) bmin[j] = p[j]; if ( p[j] > bmax[j] ) bmax[j] = p[j]; } } btScalar dx = bmax[0] - bmin[0]; btScalar dy = bmax[1] - bmin[1]; btScalar dz = bmax[2] - bmin[2]; if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) { btScalar cx = dx*btScalar(0.5) + bmin[0]; btScalar cy = dy*btScalar(0.5) + bmin[1]; btScalar cz = dz*btScalar(0.5) + bmin[2]; btScalar len = FLT_MAX; if ( dx >= EPSILON && dx < len ) len = dx; if ( dy >= EPSILON && dy < len ) len = dy; if ( dz >= EPSILON && dz < len ) len = dz; if ( len == FLT_MAX ) { dx = dy = dz = btScalar(0.01); // one centimeter } else { if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. if ( dy < EPSILON ) dy = len * btScalar(0.05); if ( dz < EPSILON ) dz = len * btScalar(0.05); } btScalar x1 = cx - dx; btScalar x2 = cx + dx; btScalar y1 = cy - dy; btScalar y2 = cy + dy; btScalar z1 = cz - dz; btScalar z2 = cz + dz; vcount = 0; // add box addPoint(vcount,vertices,x1,y1,z1); addPoint(vcount,vertices,x2,y1,z1); addPoint(vcount,vertices,x2,y2,z1); addPoint(vcount,vertices,x1,y2,z1); addPoint(vcount,vertices,x1,y1,z2); addPoint(vcount,vertices,x2,y1,z2); addPoint(vcount,vertices,x2,y2,z2); addPoint(vcount,vertices,x1,y2,z2); return true; } } return true; }
bool CChar::Use_Train_ArcheryButte( CItem * pButte, bool fSetup ) { ADDTOCALLSTACK("CChar::Use_Train_ArcheryButte"); // IT_ARCHERY_BUTTE ASSERT(pButte); ITEMID_TYPE AmmoID; if ( GetDist(pButte) < 2 ) // if we are standing right next to the butte, retrieve the arrows/bolts { if ( pButte->m_itArcheryButte.m_AmmoCount == 0 ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_EMPTY); return true; } AmmoID = pButte->m_itArcheryButte.m_AmmoType; CItemBase *pAmmoDef = CItemBase::FindItemBase(AmmoID); if ( pAmmoDef ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REM), pAmmoDef->GetName(), (pButte->m_itArcheryButte.m_AmmoCount == 1) ? "" : g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REMS)); Emote(pszMsg); CItem *pRemovedAmmo = CItem::CreateBase(AmmoID); ASSERT(pRemovedAmmo); pRemovedAmmo->SetAmount(pButte->m_itArcheryButte.m_AmmoCount); ItemBounce(pRemovedAmmo); } // Clear the target pButte->m_itArcheryButte.m_AmmoType = ITEMID_NOTHING; pButte->m_itArcheryButte.m_AmmoCount = 0; return true; } SKILL_TYPE skill = Fight_GetWeaponSkill(); if ( !g_Cfg.IsSkillFlag(skill, SKF_RANGED) ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_WS); return true; } if ( Skill_GetBase(skill) > g_Cfg.m_iSkillPracticeMax ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_SKILL); return true; } // Make sure we have some ammo CItem *pWeapon = m_uidWeapon.ItemFind(); ASSERT(pWeapon); const CItemBase *pWeaponDef = pWeapon->Item_GetDef(); // Determine ammo type CVarDefCont *pVarAmmoType = pWeapon->GetDefKey("AMMOTYPE", true); RESOURCE_ID_BASE rid; LPCTSTR t_Str; if ( pVarAmmoType ) { t_Str = pVarAmmoType->GetValStr(); rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); } else { rid = pWeaponDef->m_ttWeaponBow.m_idAmmo; } AmmoID = static_cast<ITEMID_TYPE>(rid.GetResIndex()); // If there is a different ammo type on the butte currently, tell us to remove the current type first if ( (pButte->m_itArcheryButte.m_AmmoType != ITEMID_NOTHING) && (pButte->m_itArcheryButte.m_AmmoType != AmmoID) ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_X); return true; } // We need to be correctly aligned with the target before we can use it // For the south facing butte, we need to have the same X value and a Y > 2 // For the east facing butte, we need to have the same Y value and an X > 2 if ( !pButte->IsTopLevel() ) { badalign: SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_P); return true; } int targDistX = GetTopPoint().m_x - pButte->GetTopPoint().m_x; int targDistY = GetTopPoint().m_y - pButte->GetTopPoint().m_y; if ( (pButte->GetID() == ITEMID_ARCHERYBUTTE_S) || (pButte->GetID() == ITEMID_MONGBATTARGET_S) ) { if ( !(targDistX == 0 && targDistY > 2) ) goto badalign; } else { if ( !(targDistY == 0 && targDistX > 2) ) goto badalign; } if ( !CanSeeLOS(pButte, LOS_NB_WINDOWS) ) //we should be able to shoot through a window { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_BLOCK); return true; } if ( fSetup ) { if ( Skill_GetActive() == NPCACT_TRAINING ) return true; UpdateAnimate(ANIM_ATTACK_WEAPON); m_Act_TargPrv = m_uidWeapon; m_Act_Targ = pButte->GetUID(); Skill_Start(NPCACT_TRAINING); return true; } CVarDefCont *pCont = pWeapon->GetDefKey("AMMOCONT",true); if ( m_pPlayer && AmmoID ) { int iFound = 1; if ( pCont ) { //check for UID CGrayUID uidCont = static_cast<DWORD>(pCont->GetValNum()); CItemContainer *pNewCont = dynamic_cast<CItemContainer*>(uidCont.ItemFind()); if ( !pNewCont ) //if no UID, check for ITEMID_TYPE { t_Str = pCont->GetValStr(); RESOURCE_ID_BASE rContid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); ITEMID_TYPE ContID = static_cast<ITEMID_TYPE>(rContid.GetResIndex()); if ( ContID ) pNewCont = dynamic_cast<CItemContainer*>(ContentFind(rContid)); } if ( pNewCont ) iFound = pNewCont->ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); else iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); } else iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); if ( iFound ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_NOAMMO); return(true); } } // OK...go ahead and fire at the target // Check the skill bool fSuccess = Skill_UseQuick(skill, Calc_GetRandLLVal(40)); // determine animation parameters CVarDefCont *pVarAnim = pWeapon->GetDefKey("AMMOANIM", true); CVarDefCont *pVarAnimColor = pWeapon->GetDefKey("AMMOANIMHUE", true); CVarDefCont *pVarAnimRender = pWeapon->GetDefKey("AMMOANIMRENDER", true); ITEMID_TYPE AmmoAnim; DWORD AmmoHue; DWORD AmmoRender; if ( pVarAnim ) { t_Str = pVarAnim->GetValStr(); rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); AmmoAnim = static_cast<ITEMID_TYPE>(rid.GetResIndex()); } else AmmoAnim = static_cast<ITEMID_TYPE>(pWeaponDef->m_ttWeaponBow.m_idAmmoX.GetResIndex()); AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0; AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0; pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender); pButte->Sound(0x224); // Did we destroy the ammo? const CItemBase *pAmmoDef = NULL; if ( AmmoID ) pAmmoDef = CItemBase::FindItemBase(AmmoID); if ( !fSuccess ) { // Small chance of destroying the ammo if ( pAmmoDef && !Calc_GetRandVal(10) ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_DEST), pAmmoDef->GetName()); Emote(pszMsg, NULL, true); return true; } static LPCTSTR const sm_Txt_ArcheryButte_Failure[] = { g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_1), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_2), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_3), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_4) }; Emote(sm_Txt_ArcheryButte_Failure[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Failure))]); } else { // Very small chance of destroying another arrow if ( pAmmoDef && !Calc_GetRandVal(50) && pButte->m_itArcheryButte.m_AmmoCount ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_SPLIT), pAmmoDef->GetName()); Emote(pszMsg, NULL, true); return true; } static LPCTSTR const sm_Txt_ArcheryButte_Success[] = { g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_1), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_2), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_3), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_4) }; Emote(sm_Txt_ArcheryButte_Success[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Success))]); } // Update the target if ( AmmoID ) { pButte->m_itArcheryButte.m_AmmoType = AmmoID; pButte->m_itArcheryButte.m_AmmoCount++; } return true; }
bool CPointBase::r_WriteVal( LPCTSTR pszKey, CGString & sVal ) const { ADDTOCALLSTACK("CPointBase::r_WriteVal"); if ( !strnicmp( pszKey, "STATICS", 7 ) ) { pszKey += 7; const CGrayMapBlock * pBlock = g_World.GetMapBlock( *(this) ); if ( !pBlock ) return false; if ( *pszKey == '\0' ) { int iStaticQty = 0; for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); i++ ) { const CUOStaticItemRec * pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map ); if ( this->GetDist( ptTest ) > 0 ) continue; iStaticQty++; } sVal.FormatVal( iStaticQty ); return true; } SKIP_SEPARATORS( pszKey ); const CUOStaticItemRec * pStatic = NULL; int iStatic = 0; int type = 0; if ( !strnicmp( pszKey, "FINDID", 6 ) ) { pszKey += 6; SKIP_SEPARATORS( pszKey ); iStatic = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iStatic ); if ( type == 0 ) type = RES_ITEMDEF; SKIP_SEPARATORS( pszKey ); } else { iStatic = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iStatic ); } if ( type == RES_ITEMDEF ) { const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iStatic))); if ( !pItemDef ) { sVal.FormatVal( 0 ); return false; } for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ ) { pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map); if ( this->GetDist( ptTest ) > 0 ) continue; if ( pStatic->GetDispID() == pItemDef->GetDispID() ) break; } } else { for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ ) { pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map); if ( this->GetDist( ptTest ) > 0 ) continue; if ( iStatic == 0 ) break; iStatic--; } } if ( !pStatic ) { sVal.FormatHex(0); return true; } SKIP_SEPARATORS( pszKey ); if ( !*pszKey ) pszKey = "ID"; ITEMID_TYPE idTile = pStatic->GetDispID(); if ( !strnicmp( pszKey, "COLOR", 5 ) ) { sVal.FormatHex( pStatic->m_wHue ); return true; } else if ( !strnicmp( pszKey, "ID", 2 ) ) { sVal.FormatHex( idTile ); return true; } else if ( !strnicmp( pszKey, "Z", 1 ) ) { sVal.FormatVal( pStatic->m_z ); return true; } // Check the script def for the item. CItemBase * pItemDef = CItemBase::FindItemBase( idTile ); if ( pItemDef == NULL ) { DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile )); return false; } return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv ); } else if ( !strnicmp( pszKey, "COMPONENTS", 10) ) { pszKey += 10; CRegionLinks rlinks; const CRegionBase* pRegion = NULL; CItem* pItem = NULL; const CGrayMulti* pMulti = NULL; const CUOMultiItemRec2* pMultiItem = NULL; size_t iMultiQty = GetRegions(REGION_TYPE_MULTI, rlinks); if ( *pszKey == '\0' ) { int iComponentQty = 0; for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; iComponentQty++; } } sVal.FormatVal( iComponentQty ); return true; } SKIP_SEPARATORS( pszKey ); int iComponent = 0; int type = 0; if ( strnicmp( pszKey, "FINDID", 6 ) == 0 ) { pszKey += 6; SKIP_SEPARATORS( pszKey ); iComponent = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iComponent ); if ( type == 0 ) type = RES_ITEMDEF; SKIP_SEPARATORS( pszKey ); } else { iComponent = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iComponent ); } if ( type == RES_ITEMDEF ) { const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iComponent))); if ( pItemDef == NULL ) { sVal.FormatVal( 0 ); return false; } for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; const CItemBase* pMultiItemDef = CItemBase::FindItemBase(pMultiItem->GetDispID()); if (pMultiItemDef != NULL && pMultiItemDef->GetDispID() == pItemDef->GetDispID()) break; } if (pMultiItem != NULL) break; } } else { for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; if (iComponent == 0) break; iComponent--; } if (pMultiItem != NULL) break; } } if ( pMultiItem == NULL ) { sVal.FormatHex(0); return true; } SKIP_SEPARATORS( pszKey ); if ( !*pszKey ) pszKey = "ID"; ITEMID_TYPE idTile = pMultiItem->GetDispID(); if ( strnicmp( pszKey, "ID", 2 ) == 0 ) { sVal.FormatHex( idTile ); return true; } else if ( strnicmp( pszKey, "MULTI", 5 ) == 0 ) { pszKey += 5; if (*pszKey != '\0') { SKIP_SEPARATORS(pszKey); return pItem->r_WriteVal( pszKey, sVal, &g_Serv ); } sVal.FormatHex( pItem->GetUID() ); return true; } else if ( strnicmp( pszKey, "Z", 1 ) == 0 ) { sVal.FormatVal( pItem->GetTopZ() + pMultiItem->m_dz ); return true; } // Check the script def for the item. CItemBase * pItemDef = CItemBase::FindItemBase( idTile ); if ( pItemDef == NULL ) { DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile )); return false; } return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv ); } int index = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 ); if ( index < 0 ) return false; switch ( index ) { case PT_M: case PT_MAP: sVal.FormatVal(m_map); break; case PT_X: sVal.FormatVal(m_x); break; case PT_Y: sVal.FormatVal(m_y); break; case PT_Z: sVal.FormatVal(m_z); break; case PT_ISNEARTYPE: { pszKey += 10; SKIP_SEPARATORS( pszKey ); SKIP_ARGSEP( pszKey ); int iType = g_Cfg.ResourceGetIndexType( RES_TYPEDEF, pszKey ); int iDistance = 0; bool bCheckMulti = false; SKIP_IDENTIFIERSTRING( pszKey ); SKIP_SEPARATORS( pszKey ); SKIP_ARGSEP( pszKey ); if ( *pszKey ) iDistance = Exp_GetVal(pszKey); if ( *pszKey ) bCheckMulti = Exp_GetVal(pszKey) != 0; sVal.FormatVal( g_World.IsItemTypeNear(*this, static_cast<IT_TYPE>(iType), iDistance, bCheckMulti)); break; } case PT_REGION: { // Check that the syntax is correct. if ( pszKey[6] && pszKey[6] != '.' ) return false; CRegionWorld * pRegionTemp = dynamic_cast <CRegionWorld*>(this->GetRegion(REGION_TYPE_AREA | REGION_TYPE_MULTI)); if ( !pszKey[6] ) { // We're just checking if the reference is valid. sVal.FormatVal( pRegionTemp? 1:0 ); return true; } // We're trying to retrieve a property from the region. pszKey += 7; if ( pRegionTemp ) return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv ); return false; } case PT_ROOM: { if ( pszKey[4] && pszKey[4] != '.' ) return false; CRegionBase * pRegionTemp = this->GetRegion( REGION_TYPE_ROOM ); if ( !pszKey[4] ) { sVal.FormatVal( pRegionTemp? 1:0 ); return true; } pszKey += 5; if ( pRegionTemp ) return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv ); return false; } case PT_SECTOR: { if ( pszKey[6] == '.' ) { pszKey += 7; CSector * pSectorTemp = this->GetSector(); if (pSectorTemp) return pSectorTemp->r_WriteVal(pszKey, sVal, &g_Serv); } return false; } default: { const CUOMapMeter * pMeter = g_World.GetMapMeter(*this); if ( pMeter ) { switch( index ) { case PT_TYPE: { CItemTypeDef * pTypeDef = g_World.GetTerrainItemTypeDef( pMeter->m_wTerrainIndex ); if ( pTypeDef != NULL ) sVal = pTypeDef->GetResourceName(); else sVal = ""; } return true; case PT_TERRAIN: { pszKey += strlen(sm_szLoadKeys[index]); if ( *pszKey == '.' ) // do we have an argument? { SKIP_SEPARATORS( pszKey ); if ( !strnicmp( pszKey, "Z", 1 )) { sVal.FormatVal( pMeter->m_z ); return( true ); } return( false ); } else { sVal.FormatHex( pMeter->m_wTerrainIndex ); } } return true; } } return false; } } return true; }
double WorldModel::GetMeToBallDist() { return GetDist(m_vSelfPos, m_vBallPos); }
/* Route une piste du BOARD. Parametres: 1 face / 2 faces ( 0 / 1) coord source (row,col) coord destination (row,col) net_code pointeur sur le chevelu de reference Retourne : SUCCESS si route trouvee TRIVIAL_SUCCESS si pads connectes par superposition ( pas de piste a tirer) NOSUCCESS si echec STOP_FROM_ESC si Escape demande ERR_MEMORY defaut alloc RAM */ static int Route_1_Trace(WinEDA_PcbFrame * pcbframe, wxDC * DC, int two_sides, int row_source,int col_source, int row_target,int col_target, CHEVELU * pt_chevelu ) { int r, c, side , d, apx_dist, nr, nc; int result, skip; int i; LISTE_PAD * ptr; long curcell, newcell, buddy, lastopen, lastclos, lastmove; int newdist, olddir, _self; int current_net_code; int marge, via_marge; int pad_masque_layer_s; /* Masque des couches appartenant au pad de depart */ int pad_masque_layer_e; /* Masque des couches appartenant au pad d'arrivee */ int masque_layer_TOP = g_TabOneLayerMask[Route_Layer_TOP]; int masque_layer_BOTTOM = g_TabOneLayerMask[Route_Layer_BOTTOM]; int masque_layers; /* Masque des 2 couches de routage */ int tab_mask[2]; /* permet le calcul du Masque de la couche en cours de tst (side = TOP ou BOTTOM)*/ int start_mask_layer = 0; wxString msg; result = NOSUCCESS; marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentTrackWidth / 2); via_marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentViaSize / 2); /* clear direction flags */ i = Nrows * Ncols * sizeof(char); memset(Board.m_DirSide[TOP], FROM_NOWHERE, i ); memset(Board.m_DirSide[BOTTOM], FROM_NOWHERE, i ); lastopen = lastclos = lastmove = 0; /* Init tab_masque[side] pour tests de fin de routage */ tab_mask[TOP] = masque_layer_TOP; tab_mask[BOTTOM] = masque_layer_BOTTOM; /* Init masque des couches actives */ masque_layers = masque_layer_TOP | masque_layer_BOTTOM; pt_cur_ch = pt_chevelu; current_net_code = pt_chevelu->m_NetCode; pad_masque_layer_s = pt_cur_ch->pad_start->m_Masque_Layer; pad_masque_layer_e = pt_cur_ch->pad_end->m_Masque_Layer; /* Test 1 Si routage possible c.a.d si les pads sont accessibles sur les couches de routage */ if( (masque_layers & pad_masque_layer_s) == 0 ) goto end_of_route; if( (masque_layers & pad_masque_layer_e) == 0 ) goto end_of_route; /* Test 2 Si routage possible c.a.d si les pads sont accessibles sur la grille de routage ( 1 point de grille doit etre dans le pad)*/ { int cX = (pas_route * col_source) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.x; int cY = (pas_route * row_source) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y; int dx = pt_cur_ch->pad_start->m_Size.x / 2; int dy = pt_cur_ch->pad_start->m_Size.y / 2; int px = pt_cur_ch->pad_start->m_Pos.x; int py = pt_cur_ch->pad_start->m_Pos.y; if ( ((pt_cur_ch->pad_start->m_Orient/900)&1) != 0 ) EXCHG(dx,dy) ; if ( (abs(cX - px) > dx ) || (abs(cY - py) > dy) ) goto end_of_route; cX = (pas_route * col_target) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.x; cY = (pas_route * row_target) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y; dx = pt_cur_ch->pad_end->m_Size.x / 2; dy = pt_cur_ch->pad_end->m_Size.y / 2; px = pt_cur_ch->pad_end->m_Pos.x; py = pt_cur_ch->pad_end->m_Pos.y; if ( ((pt_cur_ch->pad_end->m_Orient/900)&1) != 0 ) EXCHG(dx,dy) ; if ( (abs(cX - px) > dx ) || (abs(cY - py) > dy) ) goto end_of_route; } /* Test du cas trivial: connection directe par superposition des pads */ if( (row_source == row_target) && (col_source == col_target) && ( pad_masque_layer_e & pad_masque_layer_s & g_TabAllCopperLayerMask[g_DesignSettings.m_CopperLayerCount-1]) ) { result = TRIVIAL_SUCCESS; goto end_of_route; } /* Placement du bit de suppression d'obstacle relative aux 2 pads a relier */ pcbframe->Affiche_Message( wxT("Gen Cells") ); Place_1_Pad_Board(pcbframe->m_Pcb, pt_cur_ch->pad_start,CURRENT_PAD ,marge,WRITE_OR_CELL); Place_1_Pad_Board(pcbframe->m_Pcb, pt_cur_ch->pad_end, CURRENT_PAD ,marge,WRITE_OR_CELL); /* Regenere les barrieres restantes (qui peuvent empieter sur le placement des bits precedents) */ ptr = (LISTE_PAD*) pcbframe->m_Pcb->m_Pads; i = pcbframe->m_Pcb->m_NbPads; for( ; i > 0 ; i-- , ptr++) { if((pt_cur_ch->pad_start != *ptr) && (pt_cur_ch->pad_end != *ptr) ) { Place_1_Pad_Board(pcbframe->m_Pcb, *ptr, ~CURRENT_PAD,marge,WRITE_AND_CELL); } } InitQueue(); /* initialize the search queue */ apx_dist = GetApxDist( row_source, col_source, row_target, col_target ); /* Init 1ere recherche */ if(two_sides) /* orientation preferentielle */ { if( abs(row_target-row_source) > abs(col_target-col_source) ) { if( pad_masque_layer_s & masque_layer_TOP ) { start_mask_layer = 2; if(SetQueue( row_source, col_source, TOP, 0, apx_dist, row_target, col_target ) == 0) { return(ERR_MEMORY); } } if( pad_masque_layer_s & masque_layer_BOTTOM ) { start_mask_layer |= 1; if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist, row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } } else { if( pad_masque_layer_s & masque_layer_BOTTOM ) { start_mask_layer = 1; if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist, row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } if( pad_masque_layer_s & masque_layer_TOP ) { start_mask_layer |= 2; if (SetQueue( row_source, col_source, TOP, 0, apx_dist, row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } } } else if( pad_masque_layer_s & masque_layer_BOTTOM ) { start_mask_layer = 1; if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist, row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } /* search until success or we exhaust all possibilities */ GetQueue( &r, &c, &side, &d, &apx_dist ); for ( ; r != ILLEGAL; GetQueue( &r, &c, &side, &d, &apx_dist ) ) { curcell = GetCell( r, c, side ); if(curcell & CURRENT_PAD) curcell &= ~HOLE ; if( (r == row_target) && (c == col_target) /* success si layer OK */ && ( tab_mask[side] & pad_masque_layer_e) ) { /* Efface Liaison */ GRSetDrawMode(DC, GR_XOR); GRLine(&pcbframe->DrawPanel->m_ClipBox, DC, segm_oX, segm_oY, segm_fX, segm_fY, WHITE); /* Generation de la trace */ if( Retrace(pcbframe, DC, row_source, col_source, row_target, col_target, side, current_net_code) ) { result = SUCCESS; /* Success : Route OK */ } break; /* Fin du routage */ } /* report every 300 new nodes or so */ if( (OpenNodes-lastopen > 300) || (ClosNodes-lastclos > 300) || (MoveNodes - lastmove > 300)) { lastopen = (OpenNodes/300)*300; lastclos = (ClosNodes/300)*300; lastmove = (MoveNodes/300)*300; if( pcbframe->DrawPanel->m_AbortRequest ) { result = STOP_FROM_ESC; break; } AFFICHE_ACTIVITE_ROUTE; } _self = 0; if (curcell & HOLE) { _self = 5; /* set 'present' bits */ for (i = 0; i < 8; i++) { selfok2[i].present = 0; if( (curcell & selfok2[i].trace) ) selfok2[i].present = 1; } } for (i = 0; i < 8; i++) /* consider neighbors */ { nr = r+delta[i][0]; nc = c+delta[i][1]; /* off the edge? */ if( nr < 0 || nr >= Nrows || nc < 0 || nc >= Ncols) continue; /* off the edge */ if (_self == 5 && selfok2[i].present) continue; newcell = GetCell( nr, nc, side ); if(newcell & CURRENT_PAD) newcell &= ~HOLE; /* check for non-target hole */ if (newcell & HOLE) { if (nr != row_target || nc != col_target) continue; } /* check for traces */ else if (newcell & HOLE & ~(newmask[i])) continue; /* check blocking on corner neighbors */ if (delta[i][0] && delta[i][1]) { /* check first buddy */ buddy = GetCell( r+blocking[i].r1, c+blocking[i].c1, side ); if(buddy & CURRENT_PAD) buddy &= ~HOLE; if (buddy & HOLE) continue; // if (buddy & (blocking[i].b1)) continue; /* check second buddy */ buddy = GetCell( r+blocking[i].r2, c+blocking[i].c2, side ); if(buddy & CURRENT_PAD) buddy &= ~HOLE; if (buddy & HOLE) continue; // if (buddy & (blocking[i].b2)) continue; } olddir = GetDir( r, c, side ); newdist = d + CalcDist( ndir[i], olddir, (olddir == FROM_OTHERSIDE) ? GetDir( r, c, 1-side ) : 0 , side); /* if (a) not visited yet, or (b) we have */ /* found a better path, add it to queue */ if (!GetDir( nr, nc, side )) { SetDir( nr, nc, side, ndir[i] ); SetDist( nr, nc, side, newdist ); if( SetQueue( nr, nc, side, newdist, GetApxDist( nr, nc, row_target, col_target ), row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } else if (newdist < GetDist( nr, nc, side )) { SetDir( nr, nc, side, ndir[i] ); SetDist( nr, nc, side, newdist ); ReSetQueue( nr, nc, side, newdist, GetApxDist( nr, nc, row_target, col_target ), row_target, col_target ); } } /** etude de l'autre couche **/ if( (two_sides) && ! g_No_Via_Route ) { olddir = GetDir( r, c, side ); if (olddir == FROM_OTHERSIDE) continue; /* useless move, so don't bother */ if (curcell) /* can't drill via if anything here */ continue; /* check for holes or traces on other side */ if( (newcell = GetCell( r, c, 1-side )) != 0 ) continue; /* check for nearby holes or traces on both sides */ for (skip = 0, i = 0; i < 8; i++) { nr = r + delta[i][0]; nc = c + delta[i][1]; if (nr < 0 || nr >= Nrows || nc < 0 || nc >= Ncols) continue; /* off the edge !! */ if (GetCell( nr, nc, side )/* & blocking2[i]*/) { skip = 1; /* can't drill via here */ break; } if (GetCell( nr, nc, 1-side )/* & blocking2[i]*/) { skip = 1; /* can't drill via here */ break; } } if (skip) /* neighboring hole or trace? */ continue; /* yes, can't drill via here */ newdist = d + CalcDist( FROM_OTHERSIDE, olddir, 0 , side); /* if (a) not visited yet, or (b) we have found a better path, add it to queue */ if (!GetDir( r, c, 1-side )) { SetDir( r, c, 1-side, FROM_OTHERSIDE ); SetDist( r, c, 1-side, newdist ); if( SetQueue( r, c, 1-side, newdist, apx_dist, row_target, col_target ) == 0 ) { return(ERR_MEMORY); } } else if (newdist < GetDist( r, c, 1-side )) { SetDir( r, c, 1-side, FROM_OTHERSIDE ); SetDist( r, c, 1-side, newdist ); ReSetQueue( r, c, 1-side, newdist, apx_dist, row_target, col_target ); } } /* Fin de l'exploration de l'autre couche */ } end_of_route: Place_1_Pad_Board(pcbframe->m_Pcb, pt_cur_ch->pad_start,~CURRENT_PAD ,marge,WRITE_AND_CELL); Place_1_Pad_Board(pcbframe->m_Pcb, pt_cur_ch->pad_end, ~CURRENT_PAD ,marge,WRITE_AND_CELL); AFFICHE_ACTIVITE_ROUTE; return(result); }