void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33){ //treat this as a standard move if the front isnt long enough for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit){ unit->commandAI->GiveCommand(*c); } } return; } float frontLength=centerPos.distance(rightPos)*2; sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
void CGroupAI::MakeFormationMove(Command* c) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(centerPos); if(c->params.size()==6) rightPos=float3(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); } int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
Coordinates CrossJoinArray::getRightPosition(Coordinates const& pos) const { Coordinates rightPos(nRightDims); for (size_t r = 0, i = nLeftDims; r < nRightDims; r++) { int l = rightJoinDims[r]; rightPos[r] = (l >= 0) ? pos[l] : pos[i++]; } return rightPos; }
static uint replacePairs(CRDS *crds, PAIR *target, CODE new_code) { uint i, j; uint num_replaced = 0; SEQ *seq = crds->seq; i = target->f_pos; while (i != DUMMY_POS) { j = seq[i].next; if (j == rightPos(crds, i)) { j = seq[j].next; } updateBlock(crds, new_code, i); i = j; num_replaced++; } return num_replaced; }
void CGroupAI::Update() { if(callback->IsSelected()){ const Command* c=callback->GetOrderPreview(); if(c->id==CMD_MOVE && c->params.size()==6){ //draw a preview of how the units will be ordered float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ float3 tempSideDir=centerPos-rightPos; tempSideDir.y=0; tempSideDir.Normalize(); float3 tempFrontDir=tempSideDir.cross(float3(0,1,0)); int tempNumColumns=(int)(frontLength/columnDist); int posNum=0; float rot=GetRotationFromVector(tempFrontDir); std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ int lineNum=posNum/tempNumColumns; int colNum=posNum-lineNum*tempNumColumns; float side=(0.25f+colNum*0.5f)*columnDist*(colNum&1 ? -1:1); float3 pos=centerPos-tempFrontDir*(float)lineNum*lineDist+tempSideDir*side; pos.y=aicb->GetElevation(pos.x,pos.z); const UnitDef* ud=aicb->GetUnitDef(oi->second); aicb->DrawUnit(ud->name.c_str(),pos,rot,1,aicb->GetMyTeam(),true,false); ++posNum; } } } } }
static void updateBlock(CRDS *crds, CODE new_code, uint target_pos) { SEQ *seq = crds->seq; uint l_pos, r_pos, rr_pos, nx_pos; CODE c_code, r_code, l_code, rr_code; PCODE c_pcode, r_pcode, l_pcode; PAIR *l_pair, *c_pair, *r_pair; l_pos = leftPos(crds, target_pos); r_pos = rightPos(crds, target_pos); rr_pos = rightPos(crds, r_pos); c_code = seq[target_pos].code; c_pcode = seq[target_pos].pcode; r_code = seq[r_pos].code; r_pcode = seq[r_pos].pcode; nx_pos = seq[target_pos].next; if (nx_pos == r_pos) { nx_pos = seq[nx_pos].next; } assert(c_code != DUMMY_CODE); assert(r_code != DUMMY_CODE); if (l_pos != DUMMY_POS) { l_code = seq[l_pos].code; l_pcode = seq[l_pos].pcode; assert(seq[l_pos].code != DUMMY_CODE); removeLink(crds, l_pos); if ((l_pair = locatePair(crds, l_pcode, l_code, c_code)) != NULL) { if (l_pair->f_pos == l_pos) { l_pair->f_pos = seq[l_pos].next; } decrementPair(crds, l_pair); } if ((l_pair = locatePair(crds, l_pcode, l_code, new_code)) == NULL) { seq[l_pos].prev = DUMMY_POS; seq[l_pos].next = DUMMY_POS; createPair(crds, l_pcode, l_code, new_code, l_pos); } else { seq[l_pos].prev = l_pair->b_pos; seq[l_pos].next = DUMMY_POS; seq[l_pair->b_pos].next = l_pos; l_pair->b_pos = l_pos; incrementPair(crds, l_pair); } } removeLink(crds, target_pos); removeLink(crds, r_pos); seq[target_pos].code = new_code; seq[r_pos].code = DUMMY_CODE; if (rr_pos != DUMMY_POS) { rr_code = seq[rr_pos].code; assert(rr_code != DUMMY_CODE); if ((r_pair = locatePair(crds, r_pcode, r_code, rr_code)) != NULL) { if (r_pair->f_pos == r_pos) { r_pair->f_pos = seq[r_pos].next; } decrementPair(crds, r_pair); } if (target_pos + 1 == rr_pos - 1) { seq[target_pos+1].prev = rr_pos; seq[target_pos+1].next = target_pos; } else { seq[target_pos+1].prev = rr_pos; seq[target_pos+1].next = DUMMY_POS; seq[rr_pos-1].prev = DUMMY_POS; seq[rr_pos-1].next = target_pos; } if (nx_pos > rr_pos) { if ((c_pair = locatePair(crds, c_pcode, new_code, rr_code)) == NULL) { seq[target_pos].prev = seq[target_pos].next = DUMMY_POS; createPair(crds, c_pcode, new_code, rr_code, target_pos); } else { seq[target_pos].prev = c_pair->b_pos; seq[target_pos].next = DUMMY_POS; seq[c_pair->b_pos].next = target_pos; c_pair->b_pos = target_pos; incrementPair(crds, c_pair); } } else { seq[target_pos].next = seq[target_pos].prev = DUMMY_POS; } } else if (target_pos < crds->txt_len - 1) { assert(seq[target_pos+1].code == DUMMY_CODE); seq[target_pos+1].prev = DUMMY_POS; seq[target_pos+1].next = target_pos; seq[r_pos].prev = seq[r_pos].next = DUMMY_POS; } }
// Interpolating between the 4 vertices of the square float HeightNode::evalHeight(Vertex2D & pos, int effMapSize, Biome* biomeMap) { // Getting the required informations Vertex2D tlPos = topLeftData.getPosition(); Vertex2D brPos = bottomRightData.getPosition(); Biome tlBiome = topLeftData.getBiome(); Biome trBiome = topRightData.getBiome(); Biome blBiome = bottomLeftData.getBiome(); Biome brBiome = bottomRightData.getBiome(); float tlHeight = topLeftData.getHeight(); float trHeight = topRightData.getHeight(); float blHeight = bottomLeftData.getHeight(); float brHeight = bottomRightData.getHeight(); // Computing the local coordinates to interpolate float x = pos.first - tlPos.first; float xMax = brPos.first - tlPos.first; float y = pos.second - brPos.second; float yMax = tlPos.second - brPos.second; // Interpolation coefficients to compute float u, uTop, uBottom, v, vLeft, vRight; /* * We do here a kind of distorted bilinear interpolation to compute * the height of a point given the height of the four vertices * of the square the point is in. * * Indeed, unlike the classical bilinear interpolation where the * four vertices have a symetric role, there, the four vertices are * charaterized by their nature (ie their biome). * Whereas a beach or a plain can be extended, thus affect the whole * square, a mountain must have a very local influence ie it must * not turn the surrounding plains into green mountains. * * Thus we compute the interpolation using the following strategy * that consider the four biomes. * * TL----uTop-------TR * | | * vLeft X vRight * | | ^ y * | | | * BL----uBot-------BR |__> x * * 1) The four coefficients on the previous schema are computed * ie an interpolation is done on each edge according to the rules * explained in MapUtils * 2) We use these coefficients to interpolate a height on each edge * 3) Then we interpolate on each axis : * heightVertical(heightTop, heightBottom) * heightHorizontal(heightLeft, heightRight) * 4) Finally we interpolate between the two heights */ // Interpolating on each edge // Left side vLeft = computeInterpolationCoefficient(m_mapParameters, blBiome, tlBiome, y, yMax); float leftHeight = vLeft * (blHeight) + (1 - vLeft) * (tlHeight); // Right side vRight = computeInterpolationCoefficient(m_mapParameters, brBiome, trBiome, y, yMax); float rightHeight = vRight * (brHeight) + (1 - vRight) * (trHeight); // Top side uTop = computeInterpolationCoefficient(m_mapParameters, tlBiome, trBiome, x, xMax); float topHeight = uTop * (tlHeight) + (1 - uTop) * (trHeight); // Bottom side uBottom = computeInterpolationCoefficient(m_mapParameters, blBiome, brBiome, x, xMax); float botHeight = uBottom * (blHeight) + (1 - uBottom) * (brHeight); // Interpolating on each axis // Vertical axis Vertex2D botPos(pos.first, brPos.second); Biome botBiome = findApproximativeBiome(botPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); Vertex2D topPos(pos.first, tlPos.second); Biome topBiome = findApproximativeBiome(topPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); u = computeInterpolationCoefficient(m_mapParameters, botBiome, topBiome, y, yMax); float vertHeight = u * botHeight + (1 - u) * topHeight; // Horizontal axis Vertex2D leftPos(tlPos.first, pos.second); Biome leftBiome = findApproximativeBiome(leftPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); Vertex2D rightPos(brPos.first, pos.second); Biome rightBiome = findApproximativeBiome(rightPos, effMapSize, biomeMap, m_mapParameters.getHeightmapScaling()); v = computeInterpolationCoefficient(m_mapParameters, leftBiome, rightBiome, x, xMax); float horiHeight = v * leftHeight + (1 - v) * rightHeight; return 0.5f*(vertHeight + horiHeight); }