/* ダンジョン生成 map : フィールドデータ */ void genDungeon(uchar map[FIELD_SZ][FIELD_SZ]){ uchar dir, x, y; uint plen = 0; uint max_plen = FIELD_SZ * FIELD_SZ * 4 / 9; uchar max[2], min[2]; srand(seed); // 初期化 for(y=0; y<FIELD_SZ; y++){ for(x=0; x<FIELD_SZ; x++){ map[y][x] = ID_WALL; } } x = rand() % (FIELD_SZ-1) + 1; // 初期ポイントを設定 y = rand() % (FIELD_SZ-1) + 1; map[y][x] = ID_PASSAGE; // 通路にする plen ++; max[0] = min[0] = x; // 範囲を更新 max[1] = min[1] = y; // 範囲を更新 // 生成する while(plen <= max_plen){ _wdt_reset(); if(scanAround(map, x, y)){ // 周りに進められるところがあるか dir = nextDir(); if(checkdig(map, x, y, dir)){ // その方向に進められるか dig(map, &x, &y, dir, &plen, max, min); // 進める } }else{ // ない findBranchPoint(map, &x, &y, max, min); // 分岐点を決定 } } }
bool AiTankController::think(float gameTime, float deltaTime, bool bAvoidTimeConsumingMethod) { deltaTime; if (!isAttached()) return false; if (target.getObj()) { Point2f posTank; Entity &e = entity->getEntity(); if (e.getStatus(Entity::ESI_Position, &posTank)) iRenderQueue::getSingleton().render(animPos, posTank, ARGB(255, 0, 0, 255)); } #ifdef PATH_FINDING_TOOL //#ifndef NDEBUG #endif if (!operates.empty()) { Operate &op = operates.back(); switch(op.commond) { case Operate::CI_MoveTo: if (!op.wayPoints.empty()) { Point2f lastPos = moveToPos; for (list<Point2f>::iterator ip = op.wayPoints.begin(); ip != op.wayPoints.end(); ++ip) { iRenderQueue::getSingleton().render(*ip, lastPos, ARGB(255, 128, 0, 0)); lastPos = *ip; } } break; } } // check for commands list if (bCheckMoveTo) { stepMoveTo(); } else if (!operates.empty()) { Operate &op = operates.front(); switch(op.commond) { case Operate::CI_MoveTo: if (!op.wayPoints.empty()) { Point2f pos = op.wayPoints.front(); op.wayPoints.pop_front(); if (op.wayPoints.empty()) moveTo(pos, pos); else moveTo(pos, op.wayPoints.front()); } else { operates.pop(); } break; } } int r = rand() % 1000; // query environments (for updating covers and enemies) // determine the currently most important task(to track enemies or to escape from the enemies or go to the nearest supply zone, etc.) // generate path bool bRet = false; if (r > 500 && !bAvoidTimeConsumingMethod) { bRet = scanAround(gameTime); } // attack or rest if (target.getObj()) { if (r < 5) { sendCommand(Tank::TCI_Fire, (void *)(bFire = !bFire)); } else if (r < 20) { sendCommand(Tank::TCI_Shoot, (void *)(bShoot = !bShoot)); } } else { // no target, seize fire if (bFire) sendCommand(Tank::TCI_Fire, (void *)(bFire = !bFire)); if (bShoot) sendCommand(Tank::TCI_Shoot, (void *)(bShoot = !bShoot)); } Entity *targetObj = (Entity *)target.getObj(); if (targetObj) { if (targetObj->isActive()) { Point2f posTank; Entity &e = entity->getEntity(); if (e.getStatus(Entity::ESI_Position, &posTank)) { Point2f ePos, eVel; if (targetObj->getStatus(Entity::ESI_Position, &ePos) && targetObj->getStatus(Entity::ESI_Velocity, &eVel)) { float distance = (ePos - posTank).Length(); if (distance < 300.f) { const float averWeaponSpeed = 300.0f; float time = distance / averWeaponSpeed; aimTo(ePos + eVel * time); } else { target.release(); } } } } else { target.release(); } } return bRet; }