TEST_F(MapInfoCreateMemoryTest, process_memory) { MapInfo info; info.start = 0x2000; info.end = 0x3000; info.offset = 0; // Verify that the the process_memory object is used, so seed it // with memory. std::vector<uint8_t> buffer(1024); for (size_t i = 0; i < buffer.size(); i++) { buffer[i] = i % 256; } memory_->SetMemory(info.start, buffer.data(), buffer.size()); std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); ASSERT_TRUE(memory.get() != nullptr); memset(buffer.data(), 0, buffer.size()); ASSERT_TRUE(memory->Read(0, buffer.data(), buffer.size())); for (size_t i = 0; i < buffer.size(); i++) { ASSERT_EQ(i % 256, buffer[i]) << "Failed at byte " << i; } // Try to read outside of the map size. ASSERT_FALSE(memory->Read(buffer.size(), buffer.data(), 1)); }
short BaseColumn::codeGen(Generator * generator) { // if this column has not been added to the map table or // it does not have a valid offset, and // it has an EIC list, then add it to the map table and // assign attributes from the one of the EIC values. MapInfo * mapInfo = generator->getMapInfoAsIs(getValueId()); if ((!mapInfo || !mapInfo->isOffsetAssigned()) && (!getEIC().isEmpty())) { MapInfo * index_col_map_info; short done = 0; for (ValueId val_id = getEIC().init(); !done && getEIC().next(val_id); getEIC().advance(val_id)) { if (index_col_map_info = generator->getMapInfoAsIs(val_id)) { Attributes * attr = generator->addMapInfo(getValueId(), 0)->getAttr(); attr->copyLocationAttrs(index_col_map_info->getAttr()); done = -1; } } } return 0; }
// A transformation method for protecting sequence functions from not // being evaluated due to short-circuit evaluation. This is the base // class implementation which simply recurses on the children unless // they have already been code-generated. // void ItemExpr::protectiveSequenceFunctionTransformation(Generator *generator) { for(Int32 i=0; i<getArity(); i++) { MapInfo *mapInfo = generator->getMapInfoAsIs(child(i)); if(!mapInfo || !mapInfo->isCodeGenerated()) child(i)->protectiveSequenceFunctionTransformation(generator); } }
short Aggregate::codeGen(Generator * generator) { Attributes ** attr; // If this Aggr has already been codeGenned, then bug out early. // MapInfo * aggrMapInfo = generator->getMapInfoAsIs(getValueId()); if (aggrMapInfo && aggrMapInfo->isCodeGenerated()) return 0; if (getOperatorType() != ITM_ONE_ROW) { if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+getArity()), -1) == 1) return 0; } ex_clause * clause = 0; switch (getOperatorType()) { case ITM_ONE_ROW: { Int32 degree = 0; findnumleaves(this, degree); // degree has number of leaves in the tree if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+degree), -1) == 1) return 0; clause = new(generator->getSpace()) ex_aggr_one_row_clause(getOperatorType(), (short)(1+degree), attr, generator->getSpace()); } break; case ITM_ANY_TRUE_MAX: { clause = new(generator->getSpace()) ex_aggr_any_true_max_clause(getOperatorType(), (short)(1+getArity()), attr, generator->getSpace()); } break; default: break; } GenAssert(clause, "Aggregate::codeGen -- missing clause!"); generator->getExpGenerator()->linkClause(this, clause); return 0; }
void TerrainEngineNode::onMapInfoEstablished( const MapInfo& mapInfo ) { // set up the CSN values mapInfo.getProfile()->getSRS()->populateCoordinateSystemNode( this ); // OSG's CSN likes a NULL ellipsoid to represent projected mode. if ( !mapInfo.isGeocentric() ) this->setEllipsoidModel( NULL ); }
void generateMarkedEntries(Generator *generator, ValueIdSet &marks) { for(ValueId vid = marks.init(); marks.next(vid); marks.advance(vid)) { MapInfo *mapInfo = generator->getMapInfoAsIs(vid); if(mapInfo) mapInfo->codeGenerated(); } }
void markGeneratedEntries(Generator *generator, ItemExpr *item, ValueIdSet &marks) { if(item) { MapInfo *mapInfo = generator->getMapInfoAsIs(item->getValueId()); if(mapInfo && mapInfo->isCodeGenerated()) marks += item->getValueId(); for(Int32 i = 0; i < item->getArity(); i++) { markGeneratedEntries(generator,item->child(i), marks); } } }
void unGenerate(Generator *generator, ItemExpr *item) { if(item) { MapInfo *mapInfo = generator->getMapInfoAsIs(item->getValueId()); if(mapInfo) mapInfo->resetCodeGenerated(); for(Int32 i = 0; i < item->getArity(); i++) { unGenerate(generator,item->child(i)); } } }
std::vector<MapInfo> Map::analyzePathsHelper(std::map<std::string, DotPairT*>::iterator map_it, MapInfo curMap, bool &found){ if (found){ std::vector<MapInfo> something; return something; } // Exception control; //std::cout<<"Analyze for "<<map_it->first<<std::endl; // Actual work; PathNodeT* tmp; std::vector<MapInfo> solutions; std::vector<MapInfo> tmpSol; for (std::vector<PathNodeT*>::iterator it = possiblePaths[map_it->first]->begin(); it != possiblePaths[map_it->first]->end(); ++it){ tmp = (*it); bool collide = false; MapInfo tmpMap = curMap; while(tmp){ if (tmpMap.find(std::pair<int, int>(tmp->cur.x, tmp->cur.y)) != tmpMap.end()){ collide = true; break; } else{ tmpMap.insert(std::pair<std::pair<int, int>, std::string>(std::pair<int, int>(tmp->cur.x, tmp->cur.y), map_it->first)); tmp = tmp->prev; } } if (!collide){ std::map<std::string, DotPairT*>::iterator tmpIt = map_it; ++tmpIt; if (tmpIt == DotsMap.end()){ solutions.push_back(tmpMap); found = true; return solutions; } else{ tmpSol = analyzePathsHelper(tmpIt, tmpMap, found); solutions.insert(solutions.end(), tmpSol.begin(), tmpSol.end()); if (found) return solutions; } } } return solutions; }
void MapScreen::enter() { if (this->m_init == false) { this->m_init = true; mapinfo.init(); } soundman.playSound("sounds/game/pause1.wav"); // center map on player if (mapinfo.tex != nullptr) { mapinfo.pos = mapinfo.generate_player_coords(); mapinfo.mask.update(mapinfo.pos); } else { mapinfo.pos = glm::vec2(0.0f); } }
SpriteScene::SpriteScene(QGraphicsView *parent) : QGraphicsView(parent) { this->_scene = new QGraphicsScene(0,0,800,600); this->setScene(this->_scene); this->setSceneRect(0,0,795,595); this->setWindowFlags(Qt::FramelessWindowHint); QString basefile("base1.png"); MapInfo* mapinfo = new MapInfo(basefile); QString map1data("ansi1.mdt"); mapinfo->readMap(map1data); MapManager* manager1 = new MapManager(this->_scene); manager1->initMap(mapinfo); //this->_scene->createItemGroup(this->_scene->items())->setPos(100,100); }
static const char *mapAddressToName(const void* pc, const char* def, void const** start) { uint64_t s; char const* name = sMapInfo.map_to_name(uint64_t(uintptr_t(pc)), def, &s); if (start) { *start = (void*)s; } return name; }
void GeometryPool::createKeyForTileKey(const TileKey& tileKey, unsigned size, const MapInfo& mapInfo, GeometryPool::GeometryKey& out) const { out.lod = tileKey.getLOD(); out.yMin = mapInfo.isGeocentric()? tileKey.getExtent().yMin() : 0.0; out.size = size; }
// ItmPersistentExpressionVar::codeGen // // Adds the persistent variable to the expression generator. // short ItmPersistentExpressionVar::codeGen(Generator * generator) { // If the variable has already been codeGenned, bug out... // MapInfo * mi = generator->getMapInfoAsIs(getValueId()); if (mi && mi->isCodeGenerated()) return 0; // Otherwise, generate the code and add it to the map table. // generator->getExpGenerator()->addPersistent(getValueId(), generator->getMapTable()); // Add the initial value to the persistent list in the ExpGenerator. // generator->getExpGenerator()->linkPersistent(this); // ok... // return 0; }
ex_expr * PhysSequence::generateChildProjectExpression(Generator *generator, MapTable *mapTable, MapTable *localMapTable, const ValueIdSet &childProjectIds) const { ex_expr * projectExpr = NULL; if(NOT childProjectIds.isEmpty()) { // Generate the clauses for the expression // generator->getExpGenerator()->generateSetExpr(childProjectIds, ex_expr::exp_ARITH_EXPR, &projectExpr); // Add the projected values to the local map table. // ValueId valId; for(valId = childProjectIds.init(); childProjectIds.next(valId); childProjectIds.advance(valId)) { // Get the attribute information from the convert destination. // Attributes *newAttr = mapTable->getMapInfo(valId)->getAttr(); // Add the original value to the local map table with the // attribute information from the convert desination. // MapInfo *mapInfo = localMapTable->addMapInfoToThis (valId.getItemExpr()->child(0)->getValueId(), newAttr); // Nothing more needs to be done for this item. // mapInfo->codeGenerated(); } } return projectExpr; } // PhysSequence::generateChildProjectExpression
short Assign::codeGen(Generator * generator) { Attributes ** attr; // If this Assign has already been codeGenned, then bug out early. // MapInfo * assignMapInfo = generator->getMapInfoAsIs(getValueId()); if (assignMapInfo && assignMapInfo->isCodeGenerated()) return 0; // If the left child (lvalue) is already in the map table, then // add the Assign value Id to the map table with the same attributes // as the let child. Mark the Assign node as codeGenned. Also, allocate // space for the attributes. // MapInfo *leftChildMapInfo = generator->getMapInfoAsIs (child(0)->castToItemExpr()->getValueId()); if (leftChildMapInfo) { if (! assignMapInfo) assignMapInfo = generator->addMapInfoToThis(generator->getLastMapTable(), getValueId(), leftChildMapInfo->getAttr()); assignMapInfo->codeGenerated(); attr = new(generator->wHeap()) Attributes*[2]; // Set the result attribute // attr[0] = assignMapInfo->getAttr(); } // Otherwise, go ahead and generate the Assign attributes (which also // allocates space for the Assign result). Add the left child to the // map table with the same attributes as the Assign node. // else { generator->getExpGenerator()->genItemExpr(this, &attr, 2, 0); generator->addMapInfoToThis(generator->getLastMapTable(), child(0)->castToItemExpr()->getValueId(), attr[0]); } attr[0]->resetShowplan(); // Now, generate code for the right child (rvalue). // generator->getExpGenerator()->setClauseLinked(FALSE); child(1)->codeGen(generator); attr[1] = generator->getAttr(child(1)); generator->getExpGenerator()->setClauseLinked(FALSE); ex_conv_clause * conv_clause = new(generator->getSpace()) ex_conv_clause (getOperatorType(), attr, generator->getSpace()); generator->getExpGenerator()->linkClause(this, conv_clause); return 0; }
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player* plr, uint32 instanceid) { // preteleport is where all the magic happens :P instance creation, etc. MapInfo* inf = WorldMapInfoStorage.LookupEntry(mapid); Group* pGroup; InstanceMap* instancemap; Instance* in; if(inf == NULL || mapid >= NUM_MAPS) return INSTANCE_ABORT_NOT_FOUND; // main continent check. if(inf->type == INSTANCE_NULL) { // this will be useful when clustering comes into play. // we can check if the destination world server is online or not and then cancel them before they load. return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND; } // shouldn't happen if(inf->type == INSTANCE_BATTLEGROUND) return INSTANCE_ABORT_NOT_FOUND; pGroup = plr->GetGroup(); // players without groups cannot enter raids and heroic instances if(pGroup == NULL && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; if(pGroup == NULL && (inf->type == INSTANCE_NONRAID && plr->iInstanceType == MODE_HEROIC) && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // players without raid groups cannot enter raid instances if(pGroup != NULL && pGroup->GetGroupType() != GROUP_TYPE_RAID && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // We deny transfer if we requested a heroic instance of a map that has no heroic mode // We are trying to enter into a non-multi instance with a heroic group, downscaling if(inf->type == INSTANCE_NONRAID && plr->GetDungeonDifficulty() == MODE_HEROIC) { plr->SetDungeonDifficulty(MODE_NORMAL); plr->SendDungeonDifficulty(); Group* grp = plr->GetGroup(); if(grp != NULL) grp->SetDungeonDifficulty(MODE_NORMAL); } // if it's not a normal / 10men normal then check if we even have this mode if(inf->type == INSTANCE_RAID && plr->GetRaidDifficulty() != MODE_NORMAL_10MEN) { uint32 newtype = 0; if(!inf->HasDifficulty(plr->GetRaidDifficulty())) { // no it doesn't so we will downscale it /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // This part is totally speculative, if you know how this is done actually then do change it // switch(plr->GetRaidDifficulty()) { case MODE_NORMAL_25MEN: case MODE_HEROIC_10MEN: { newtype = MODE_NORMAL_10MEN; break; } case MODE_HEROIC_25MEN: { newtype = MODE_NORMAL_25MEN; break; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // check if we have this mode if(!inf->HasDifficulty(newtype)) { //appearantly we don't so we set to 10men normal, which is the default for old raids too //regardless of their playerlimit newtype = MODE_NORMAL_10MEN; } // Setting the new mode on us and our group if(plr->GetRaidDifficulty() != newtype) { plr->SetRaidDifficulty(newtype); plr->SendRaidDifficulty(); Group* grp = plr->GetGroup(); if(grp != NULL) grp->SetRaidDifficulty(newtype); } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // If we are here, it means: // 1.) We're a simple non-raid and non-heroic dungeon // 2.) We're a multi-dungeon set to heroic and we are in a group // 3.) We're a raid, and we are in a raid group // 4.) We're a raid, we are in a raid group, and we have the right mode set // // So, first we have to check if they have an instance on this map already, if so, allow them to teleport to that. // Otherwise, we will try to create them a new one. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// m_mapLock.Acquire(); instancemap = m_instances[mapid]; // If there are no instances of this map yet, we need to create the map if(instancemap == NULL) { if(instanceid != 0) { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } m_instances[mapid] = new InstanceMap; instancemap = m_instances[mapid]; } else { InstanceMap::iterator itr; // this is the case when we enter an already existing instance ( with summons for example ) if(instanceid != 0) { itr = instancemap->find(instanceid); if(itr != instancemap->end()) { in = itr->second; if(!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... m_mapLock.Release(); sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if(pGroup) in->m_creatorGroup = pGroup->GetID(); m_mapLock.Release(); return INSTANCE_OK; } else { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } } else // this is the case when we enter the normal way (e.g. we enter thru the portal ) { in = NULL; if(pGroup != NULL) // we are in a group { uint32 grpdiff; // We want to use the raid difficulty for raids, and dungeon difficulty for dungeons if(inf->type == INSTANCE_RAID) grpdiff = pGroup->m_raiddifficulty; else grpdiff = pGroup->m_difficulty; if((inf->type == INSTANCE_MULTIMODE && grpdiff == MODE_HEROIC) || inf->type == INSTANCE_RAID) { // This is the case when we don't have this map on this difficulty saved yet for the player entering if(plr->GetPersistentInstanceId(mapid, grpdiff) == 0) { // The group has this instance saved already so we will use it if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]); } else if(sWorld.instance_TakeGroupLeaderID) { PlayerInfo* pLeaderInfo = pGroup->GetLeader(); if(pLeaderInfo) { pLeaderInfo->savedInstanceIdsLock.Acquire(); PlayerInstanceMap::iterator itrLeader = pLeaderInfo->savedInstanceIds[ grpdiff ].find(mapid); if(itrLeader != pLeaderInfo->savedInstanceIds[ grpdiff ].end()) { in = sInstanceMgr.GetInstanceByIds(mapid, (*itrLeader).second); } pLeaderInfo->savedInstanceIdsLock.Release(); } } } // If we have it saved to the player then use that if(in == NULL && plr->GetPersistentInstanceId(mapid, grpdiff) != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, plr->GetPersistentInstanceId(mapid, grpdiff)); } } else { if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]); } } } if(in == NULL) { // We are not in a group, so we will look for an instance that we own and has the right difficulty uint32 diff; if(inf->type == INSTANCE_RAID) diff = plr->GetRaidDifficulty(); else diff = plr->GetDungeonDifficulty(); for(itr = instancemap->begin(); itr != instancemap->end();) { in = itr->second; ++itr; if(in->m_difficulty == diff && PlayerOwnsInstance(in, plr)) break; in = NULL; } } // We've found an instance! if(in != NULL) { m_mapLock.Release(); // check the player count and in combat status. if(in->m_mapMgr) { if(in->m_mapMgr->IsCombatInProgress()) return INSTANCE_ABORT_ENCOUNTER; if(in->m_mapMgr->GetPlayerCount() >= inf->playerlimit) return INSTANCE_ABORT_FULL; } if(!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if(pGroup) in->m_creatorGroup = pGroup->GetID(); plr->SetInstanceID(in->m_instanceId); // found our instance, allow him in. return INSTANCE_OK; } } } // if we're here, it means we need to create a new instance. in = new Instance; in->m_creation = UNIXTIME; switch(inf->type) { case INSTANCE_NONRAID: case INSTANCE_MULTIMODE: in->m_difficulty = plr->GetDungeonDifficulty(); break; case INSTANCE_RAID: in->m_difficulty = plr->GetRaidDifficulty(); break; } in->m_instanceId = GenerateInstanceID(); in->m_mapId = mapid; in->m_mapInfo = inf; in->m_mapMgr = NULL; // always start off without a map manager, it is created in GetInstance() in->m_isBattleground = false; in->m_persistent = IS_PERSISTENT_INSTANCE(in) && objmgr.m_InstanceBossInfoMap[mapid] == NULL; in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID(); // creator guid is 0 if its owned by a group. in->m_creatorGroup = pGroup ? pGroup->GetID() : 0; if(sWorld.instance_SlidingExpiration) { if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_HEROIC) in->m_expiration = UNIXTIME + TIME_DAY; else in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } else { if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC) { in->m_expiration = UNIXTIME - (UNIXTIME % TIME_DAY) + ((UNIXTIME % TIME_DAY) > (sWorld.instance_DailyHeroicInstanceResetHour * TIME_HOUR) ? 82800 : -3600) + ((sWorld.instance_DailyHeroicInstanceResetHour - sWorld.GMTTimeZone) * TIME_HOUR); } else if(IS_PERSISTENT_INSTANCE(in)) { if(m_nextInstanceReset[in->m_mapId] == 0) { m_nextInstanceReset[in->m_mapId] = UNIXTIME - (UNIXTIME % TIME_DAY) - ((sWorld.GMTTimeZone + 1) * TIME_HOUR) + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId); CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } if(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME) { do { time_t tmp = m_nextInstanceReset[in->m_mapId]; if(tmp + (TIME_MINUTE * 15) < UNIXTIME) m_nextInstanceReset[in->m_mapId] = tmp + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); } while(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME); CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId); CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } in->m_expiration = m_nextInstanceReset[in->m_mapId]; } else { in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } } plr->SetInstanceID(in->m_instanceId); Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId); // save our new instance to the database. in->SaveToDB(); // apply it in the instance map instancemap->insert(InstanceMap::value_type(in->m_instanceId, in)); // Try to add instance ID to player plr->SetPersistentInstanceId(in); // instance created ok, i guess? return the ok for him to transport. m_mapLock.Release(); return INSTANCE_OK; }
int CPlayer::StartAttack( CPlayer* pDefender ) { int destroyCount = 0; int hitCount = 0; int turn = 0; int maxTurn = MAP_SIZE * MAP_SIZE; Position attackPosition = {0, }; HitResult result = MISS; MapInfo mapInfo; char string[255] = {0, }; m_MyMap.InitMapInfo(MI_All); InitGuessShipState(); while(turn < maxTurn) { mapInfo.Init(); ++turn; m_MyMap.InitMapInfo(MI_Probability); #ifdef TEST_FLAG // 공격 결과 출력 sprintf_s(string, " "); CUIManager::GetInstance()->BroadCast(string); m_MyMap.DisplayMap(MI_HitResult); #endif // 확률 계산 CalculateProbability(); // 최대값 찾기 attackPosition = GetBestPosition(); result = pDefender->HitCheck(attackPosition); #ifdef TEST_FLAG sprintf_s(string, " Attack Position : ( %c , %c ) ", attackPosition.x, attackPosition.y); CUIManager::GetInstance()->BroadCast(string); #endif switch (result) { case MISS: #ifdef TEST_FLAG sprintf_s(string, " Miss! - Turn : %d", turn); CUIManager::GetInstance()->BroadCast(string); sprintf_s(string, " - Hit : %d, Destroy : %d", hitCount, destroyCount); CUIManager::GetInstance()->BroadCast(string); #endif mapInfo.type = MI_HitResult; mapInfo.value.hitResult = MISS; m_MyMap.SetMapInfo(attackPosition, mapInfo); break; case HIT: ++hitCount; #ifdef TEST_FLAG sprintf_s(string, " Hit ! - Turn : %d", turn); CUIManager::GetInstance()->BroadCast(string); sprintf_s(string, " - Hit : %d, Destroy : %d", hitCount, destroyCount); CUIManager::GetInstance()->BroadCast(string); #endif mapInfo.type = MI_HitResult; mapInfo.value.hitResult = HIT; m_MyMap.SetMapInfo(attackPosition, mapInfo); break; case DESTROY_AIRCRAFT: case DESTROY_BATTLESHIP: case DESTROY_CRUISER: case DESTROY_DESTROYER: case DESTROY_SUBMARINE: mapInfo.type = MI_HitResult; mapInfo.value.hitResult = HIT; m_MyMap.SetMapInfo(attackPosition, mapInfo); #ifdef TEST_FLAG sprintf_s(string, " Destroy!!! - Turn : %d", turn); CUIManager::GetInstance()->BroadCast(string); sprintf_s(string, " - Hit : %d, Destroy : %d", hitCount, destroyCount); CUIManager::GetInstance()->BroadCast(string); #endif // 터진 배 추측 GuessDestroyedShip(result, attackPosition); ++hitCount; ++destroyCount; if(destroyCount >= sizeof(m_Ships) / sizeof(m_Ships[0])) { #ifdef TEST_FLAG m_MyMap.DisplayMap(MI_Probability, attackPosition.x, attackPosition.y); pDefender->m_MyMap.DisplayMap(MI_ShipType); #endif sprintf_s(string, " Victory !!! Turn : %d", turn); CUIManager::GetInstance()->BroadCast(string); #ifdef TEST_FLAG CUIManager::GetInstance()->Sound(4); Sleep(3000); CUIManager::GetInstance()->Clear(); #endif return turn; } break; default: // 이곳은 도달하면 안 됨. #ifdef TEST_FLAG sprintf_s(string, " Do not reach here! - Destroy error"); CUIManager::GetInstance()->BroadCast(string); #endif break; } #ifdef TEST_FLAG // 공격 결과 출력 m_MyMap.DisplayMap(MI_Probability, attackPosition.x, attackPosition.y); pDefender->m_MyMap.DisplayMap(MI_ShipType); switch(result) { case MISS: CUIManager::GetInstance()->Sound(1); break; case HIT: CUIManager::GetInstance()->Sound(2); break; case DESTROY_AIRCRAFT: case DESTROY_BATTLESHIP: case DESTROY_CRUISER: case DESTROY_DESTROYER: case DESTROY_SUBMARINE: CUIManager::GetInstance()->Sound(3); break; default: break; } Sleep(500); CUIManager::GetInstance()->Clear(); #endif } // Error return -9999; }
bool MapScreen::render(Renderer&, double elapsed) { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); const glm::vec3 top_cam(mapinfo.pos.x, mapinfo.pos.y + OFFSET_Y, -OFFSET_Z); const glm::vec3 bot_cam(mapinfo.pos.x, mapinfo.pos.y, 0.0); /// map image /// if (mapinfo.tex == nullptr) { // we cant do calculations without the base image return true; } auto& shd = shaders[Shaders::MAP]; shd.bind(); // create mvp matrix mapinfo.matmvp = glm::lookAt( top_cam, bot_cam, glm::vec3(0, -1, 0)); mapinfo.matmvp = mapinfo.projection * mapinfo.matmvp; shd.sendMatrix("matmvp", mapinfo.matmvp); shd.sendFloat("alpha", 1.0f); mapinfo.mapvao.bind(); // render map texture mapinfo.tex->bind(0); mapinfo.mapvao.renderIndexed(GL_TRIANGLES); // render map mask layer if (mapinfo.mask.enabled) { glEnable(GL_BLEND); mapinfo.mask.tex->bind(0); mapinfo.mapvao.renderIndexed(GL_TRIANGLES); glDisable(GL_BLEND); } /// map clouds & shadows /// for (size_t i = 0; i < mapinfo.border.size(); i++) { auto& layer = mapinfo.border.at(i); const float floatx = 0.005 * sin(6.28 * sin(i + elapsed * 0.25)); const float floaty = 0.05 * sin(6.28 * sin(i + elapsed * 0.5)); layer.matmvp = glm::lookAt( top_cam + glm::vec3(0, floatx, floaty), bot_cam + glm::vec3(0, floatx, 0), glm::vec3(0, -1, 0)); layer.matmvp = mapinfo.projection * layer.matmvp; } glEnable(GL_BLEND); shd.sendFloat("alpha", 0.7f); for (auto& layer : mapinfo.border) { if (layer.shadow != nullptr) { shd.sendMatrix("matmvp", layer.matmvp); layer.shadow->bind(0); mapinfo.mapvao.renderIndexed(GL_TRIANGLES); } } glDisable(GL_BLEND); shd.sendFloat("alpha", 1.0f); for (auto& layer : mapinfo.border) { if (layer.cloud != nullptr) { shd.sendMatrix("matmvp", layer.matmvp); layer.cloud->bind(0); mapinfo.mapvao.renderIndexed(GL_TRIANGLES); } } /// map icons /// const bool do_map_icons = uint64_t(elapsed * 2.0f) & 1; if (do_map_icons) { Shader& shdSprite = shaders[Shaders::OBJECTS]; shdSprite.bind(); shdSprite.sendMatrix("matmvp", mapinfo.matmvp); auto& spritegen = mapinfo.spritegen; spritegen.clear(); // player head const auto ptloc = mapinfo.generate_player_coords(); const auto frame = mapinfo.construct_frame(mapinfo.sprite_player, ptloc, 8); spritegen.generate(frame); // JSON-defined icons & script for (const auto& icon : mapinfo.icons) { const auto frame = mapinfo.construct_frame(icon.sprite, mapinfo.transform(icon.pos), 8); spritegen.generate(frame); } spritegen.sort(); spritegen.index(); // render lowest to high spritegen.render(Z_LOWEST, Z_HIGH); } return true; }
void MapScreen::update_mask() { if (mapinfo.mask.enabled) { mapinfo.mask.update(mapinfo.generate_player_coords()); } }
void MapScreen::load(const std::string& json_file) { mapinfo.load(json_file); }
ItemExpr *ItmSeqOlapFunction::preCodeGen(Generator *generator) { if (getOperatorType() != ITM_OLAP_MIN && getOperatorType() != ITM_OLAP_MAX) { GenAssert(0, "ItmSeqOlapFunction::preCodeGen -- Should never get here!"); return 0; } if (nodeIsPreCodeGenned()) return this; markAsPreCodeGenned(); // Get some local handles... // CollHeap *wHeap = generator->wHeap(); ItemExpr *itmChild = child(0)->castToItemExpr(); //ItemExpr *itmWindow = child(1)->castToItemExpr(); // What scalar operation needs to be done. // OperatorTypeEnum operation; if(getOperatorType() == ITM_OLAP_MIN) operation = ITM_SCALAR_MIN; else operation = ITM_SCALAR_MAX; // Allocate a HostVar for local storage of the index. // ItemExpr *itmLocalCounter = new(wHeap) HostVar("_sys_LocalCounter", new(wHeap) SQLInt(wHeap, TRUE,FALSE), TRUE); // Expression to initailize the iterator. // ItemExpr *itmLocalCounterInitialize = new(wHeap) Assign(itmLocalCounter, new(wHeap) ConstValue(frameStart_), FALSE); // Expression to increment the iterator. // ItemExpr *itmLocalCounterIncrement = new(wHeap) Assign(itmLocalCounter, new(wHeap) BiArith(ITM_PLUS, itmLocalCounter, new (wHeap) ConstValue(1)), FALSE); // Allocate a HostVar for referencing the result before it is computed. // ItemExpr *itmResult = new(wHeap) HostVar("_sys_Result", getValueId().getType().newCopy(wHeap), TRUE); // Expression to initialize the result. // ItemExpr *itmResultInitialize = new(wHeap) Assign(itmResult, new(wHeap) ConstValue()); // Expression to compute the min/max. // ItemExpr * invCouter= new(wHeap) BiArith(ITM_MINUS, new (wHeap) ConstValue(0), itmLocalCounter); ItemExpr * itmOffsetExpr = new(wHeap) ItmSeqOffset( itmChild, invCouter); //ItemExpr * itmOffsetIsNotNull = new (wHeap) UnLogic(ITM_IS_NOT_NULL, itmOffsetExpr); ((ItmSeqOffset *)itmOffsetExpr)->setIsOLAP(isOLAP()); ItemExpr *itmResultUpdate = new(wHeap) Assign(itmResult, new(wHeap) ItmScalarMinMax(operation, itmResult, itmOffsetExpr)); // Construct code blocks for the initialization and body for the while-loop // ItemExpr *itmInit = new(wHeap) ItmBlockFunction(itmLocalCounterInitialize, itmResultInitialize); ItemExpr *itmBody = new(wHeap) ItmBlockFunction(itmResultUpdate, itmLocalCounterIncrement); // Construct the While loop (i < window) // ItemExpr *itmLoopCondition = new(wHeap) BiRelat (ITM_LESS_EQ, itmLocalCounter, new(wHeap) ConstValue(frameEnd_)); if (isFrameEndUnboundedFollowing()) //(frameEnd_ == INT_MAX)// not needed in other cases -- can cause issues fo the preceding part { ItemExpr * itmOffset1 = new(wHeap) ItmSeqOffset( itmChild, invCouter,NULL,TRUE); ItemExpr * itmOffset1IsNotNull = new (wHeap) UnLogic(ITM_IS_NOT_NULL, itmOffset1); ((ItmSeqOffset *)itmOffset1)->setIsOLAP(isOLAP()); itmLoopCondition = itmOffset1IsNotNull; //new (wHeap) BiLogic( ITM_AND, // itmLoopCondition, // itmOffset1IsNotNull); } ItemExpr *itmWhile = new(wHeap) ItmWhileFunction(itmBody, itmLoopCondition); // Construct the blocks to contain the initialization and looping. // The result is the final value of the min/max. // ItemExpr *itmBlock = new(wHeap) ItmBlockFunction (new(wHeap) ItmBlockFunction(itmInit, itmWhile), itmResult); // Replace the item for this value id with the new item expression. // getValueId().replaceItemExpr(itmBlock); // Run the new expression through type and value Id synthesis. // itmBlock->synthTypeAndValueId(TRUE); // Map the reference to the result to the actual result in the map table. // Attributes *attr = generator->getMapInfo(itmBlock->getValueId())->getAttr(); MapInfo *mapInfo = generator->addMapInfo(itmResult->getValueId(), attr); itmResult->markAsPreCodeGenned(); mapInfo->codeGenerated(); // Return the preCodeGen of the new expression. // return itmBlock->preCodeGen(generator); }
void WorldSession::_HandleAreaTriggerOpcode(uint32 id) { DEBUG_LOG( "WorldSession","HandleAreaTriggerOpcode: %u", id); // Are we REALLY here? CHECK_INWORLD_RETURN; // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); AreaTrigger* pAreaTrigger = AreaTriggerStorage.LookupEntry( id ); sHookInterface.OnAreaTrigger(_player, id); CALL_INSTANCE_SCRIPT_EVENT( _player->GetMapMgr(), OnAreaTrigger )( _player, id ); // if in BG handle is triggers if( _player->m_bg ) { _player->m_bg->HookOnAreaTrigger(_player, id); return; } // Hook for Scripted Areatriggers _player->GetMapMgr()->HookOnAreaTrigger(_player, id); if( _player->GetSession()->CanUseCommand('z') ) { if( pAreaTrigger != NULL ) sChatHandler.BlueSystemMessage( this, "[%sSystem%s] |rEntered areatrigger: %s%u (%s).", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id, pAreaTrigger->Name ); else sChatHandler.BlueSystemMessage( this, "[%sSystem%s] |rEntered areatrigger: %s%u", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id); } if( pAreaTrigger == NULL ) { OUT_DEBUG("Missing AreaTrigger: %u", id); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(_player->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { MapInfo * pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); MapEntry* map = dbcMap.LookupEntry(pAreaTrigger->Mapid); if(!pMi) return; //do we meet the map requirements? uint8 reason = CheckTeleportPrerequsites(pAreaTrigger, this, _player, pAreaTrigger->Mapid); if(reason != AREA_TRIGGER_FAILURE_OK) { const char * pReason = AreaTriggerFailureMessages[reason]; char msg[200]; WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 50); data << uint32(0); switch (reason) { case AREA_TRIGGER_FAILURE_LEVEL: { snprintf(msg,200,pReason,pAreaTrigger->required_level); data << msg; }break; case AREA_TRIGGER_FAILURE_NO_ATTUNE_I: { ItemPrototype * pItem = ItemPrototypeStorage.LookupEntry(pMi->required_item); snprintf(msg, 200, pReason, pItem ? pItem->Name1 : "UNKNOWN"); data << msg; }break; case AREA_TRIGGER_FAILURE_NO_ATTUNE_Q: { Quest * pQuest = QuestStorage.LookupEntry(pMi->required_quest); snprintf(msg, 200, pReason, pQuest ? pQuest->title : "UNKNOWN"); data << msg; }break; case AREA_TRIGGER_FAILURE_NO_KEY: { string temp_msg[2]; string tmp_msg; for(uint32 i = 0; i < 2; ++i) { if (pMi->heroic_key[i] && _player->GetItemInterface()->GetItemCount(pMi->heroic_key[i], false)==0) { ItemPrototype * pKey = ItemPrototypeStorage.LookupEntry(pMi->heroic_key[i]); if(pKey) temp_msg[i] += pKey->Name1; else temp_msg[i] += "UNKNOWN"; } } tmp_msg += temp_msg[0]; if(temp_msg[0].size() && temp_msg[1].size()) tmp_msg += "\" and \""; tmp_msg += temp_msg[1]; snprintf(msg, 200, pReason, tmp_msg.c_str()); data << msg; }break; case AREA_TRIGGER_FAILURE_LEVEL_HEROIC: { snprintf(msg, 200, pReason, pMi->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70); data << msg; }break; default: { data << pReason; }break; } data << uint8(0); SendPacket(&data); return; } if( _player->IsMounted()) TO_UNIT(_player)->Dismount(); uint32 InstanceID = 0; // Try to find a saved instance and // do not handle Hyjal Inn (trigger 4319), since we need a unique mapid when generating our instance_id. if( id != 4319 && pMi && ( map->israid() || _player->iRaidType >= MODE_NORMAL_25MEN && pMi->type == INSTANCE_MULTIMODE ) ) { //Do we have a saved instance we should use? Instance * in = NULL; in = sInstanceMgr.GetSavedInstance( pMi->mapid,_player->GetLowGUID(), _player->iRaidType ); if( in != NULL && in->m_instanceId ) { //If we are the first to enter this instance, also set our current group id. if( in->m_mapMgr == NULL || (!in->m_mapMgr->HasPlayers() && _player->GetGroupID() != in->m_creatorGroup)) in->m_creatorGroup =_player->GetGroupID(); InstanceID = in->m_instanceId; } } //Save our entry point and try to teleport to our instance _player->SaveEntryPoint(pAreaTrigger->Mapid); _player->SafeTeleport(pAreaTrigger->Mapid, InstanceID, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { if( _player->IsMounted()) TO_UNIT(_player)->Dismount(); // Inn if (!_player->m_isResting) _player->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if( _player->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { if( _player->IsMounted() ) TO_UNIT(_player)->Dismount(); _player->SaveEntryPoint(pAreaTrigger->Mapid); _player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; default:break; } }
void OSGTerrainEngineNode::onMapInfoEstablished( const MapInfo& mapInfo ) { LoadingPolicy::Mode mode = *_terrainOptions.loadingPolicy()->mode(); OE_INFO << LC << "Loading policy mode = " << ( mode == LoadingPolicy::MODE_PREEMPTIVE ? "PREEMPTIVE" : mode == LoadingPolicy::MODE_SEQUENTIAL ? "SEQUENTIAL" : mode == LoadingPolicy::MODE_PARALLEL ? "PARALLEL" : "SERIAL/STANDARD" ) << std::endl; // create a factory for creating actual tile data _tileFactory = new OSGTileFactory( _uid, *_cull_mapf, _terrainOptions ); // go through and build the root nodesets. if ( !_isStreaming ) { _terrain = new Terrain( *_update_mapf, *_cull_mapf, _tileFactory.get(), *_terrainOptions.quickReleaseGLObjects() ); } else { _terrain = new StreamingTerrain( *_update_mapf, *_cull_mapf, _tileFactory.get(), *_terrainOptions.quickReleaseGLObjects() ); } this->addChild( _terrain ); // set the initial properties from the options structure: _terrain->setVerticalScale( _terrainOptions.verticalScale().value() ); _terrain->setSampleRatio ( _terrainOptions.heightFieldSampleRatio().value() ); if (_terrainOptions.enableBlending().value()) { _terrain->getOrCreateStateSet()->setMode(GL_BLEND , osg::StateAttribute::ON); } OE_INFO << LC << "Sample ratio = " << _terrainOptions.heightFieldSampleRatio().value() << std::endl; // install the proper layer composition technique: if ( _texCompositor->getTechnique() == TerrainOptions::COMPOSITING_MULTIPASS ) { _terrain->setTechniquePrototype( new MultiPassTerrainTechnique( _texCompositor.get() ) ); OE_INFO << LC << "Compositing technique = MULTIPASS" << std::endl; } else { CustomTerrainTechnique* tech = new SinglePassTerrainTechnique( _texCompositor.get() ); // prepare the interpolation technique for generating triangles: if ( mapInfo.getElevationInterpolation() == INTERP_TRIANGULATE ) tech->setOptimizeTriangleOrientation( false ); _terrain->setTechniquePrototype( tech ); } // install the shader program, if applicable: installShaders(); // calculate a good thread pool size for non-streaming parallel processing if ( !_isStreaming ) { unsigned num = 2 * OpenThreads::GetNumberOfProcessors(); if ( _terrainOptions.loadingPolicy().isSet() ) { if ( _terrainOptions.loadingPolicy()->numLoadingThreads().isSet() ) { num = *_terrainOptions.loadingPolicy()->numLoadingThreads(); } else if ( _terrainOptions.loadingPolicy()->numLoadingThreadsPerCore().isSet() ) { num = (unsigned)(*_terrainOptions.loadingPolicy()->numLoadingThreadsPerCore() * OpenThreads::GetNumberOfProcessors()); } } _tileService = new TaskService( "TileBuilder", num ); // initialize the tile builder _tileBuilder = new TileBuilder( getMap(), _terrainOptions, _tileService.get() ); // initialize a key node factory. switch( mode ) { case LoadingPolicy::MODE_SERIAL: _keyNodeFactory = new SerialKeyNodeFactory( _tileBuilder.get(), _terrainOptions, mapInfo, _terrain, _uid ); break; case LoadingPolicy::MODE_PARALLEL: _keyNodeFactory = new ParallelKeyNodeFactory( _tileBuilder.get(), _terrainOptions, mapInfo, _terrain, _uid ); break; default: break; } } // Build the first level of the terrain. // Collect the tile keys comprising the root tiles of the terrain. std::vector< TileKey > keys; _update_mapf->getProfile()->getRootKeys( keys ); for( unsigned i=0; i<keys.size(); ++i ) { osg::Node* node; if ( _keyNodeFactory.valid() ) node = _keyNodeFactory->createNode( keys[i] ); else node = _tileFactory->createSubTiles( *_update_mapf, _terrain, keys[i], true ); if ( node ) _terrain->addChild( node ); else OE_WARN << LC << "Couldn't make tile for root key: " << keys[i].str() << std::endl; } // we just added the root tiles, so mark the bound in need of recomputation. dirtyBound(); }
// ticks the game forward in time void GameInfo::Ticker() { tic++; // TODO read/write demo ticcmd's here // do main actions switch (state) { case GS_INTRO: if (--pagetic <= 0) AdvanceIntro(); break; case GS_LEVEL: if (!paused && currentcluster) currentcluster->Ticker(); if (!dedicated) { hud.Ticker(); automap.Ticker(); } break; case GS_INTERMISSION: wi.Ticker(); break; case GS_FINALE: F_Ticker(); break; case GS_NULL: default: // do nothing break; } MapInfo *m; PlayerInfo *p; if (state != GS_LEVEL) return; // manage players for (player_iter_t t = Players.begin(); t != Players.end(); ) { p = t->second; t++; // because "old t" may be invalidated if (p->playerstate == PST_REMOVE) { // the player is removed from the game (invalidates "old t") if (!p->mp) RemovePlayer(p->number); // first the maps throw out the removed player, then the game proper. // TODO purge the removed players from the frag maps of other players? } else p->Ticker(); } if (!server) return; // for (player_iter_t t = Players.begin(); t != Players.end(); t++) { p = t->second; if (p->playerstate == PST_NEEDMAP) { LConnection *conn = p->connection; if (conn && !conn->isGhostAvailable(p)) { // remote player, is it already being ghosted? if not, wait. CONS_Printf(" server waiting for client ghost\n"); continue; } // assign the player to a map CONS_Printf("Map request.."); if (p->requestmap == 0) { m = initial_map; // first map in game p->entrypoint = initial_ep; } else m = FindMapInfo(p->requestmap); if (!m) { // game ends currentcluster->Finish(p->requestmap, p->entrypoint); StartFinale(NULL); break; } else if (!m->found) m = currentcluster->maps[0]; // TODO or give an error? // cluster change? if (currentcluster->number != m->cluster) { // TODO minor thing: if several players exit maps on the same tick, // and someone besides the first one causes a cluster change, some // maps could be loaded in vain... // cluster change! currentcluster->Finish(p->requestmap, p->entrypoint); MapCluster *next = FindCluster(m->cluster); StartFinale(next); currentcluster = next; break; // this is important! no need to check the other players. } p->Reset(!currentcluster->keepstuff, true); // normal individual mapchange if (!m->Activate(p)) I_Error("Darn!\n"); if (conn) { CONS_Printf(" server sending rpc\n"); // nonlocal player enters a new map, notify client // send the EnterMap rpc only to the owning connection NetEvent *e = TNL_RPC_CONSTRUCT_NETEVENT(p, s2cEnterMap, (m->mapnumber)); conn->postNetEvent(e); } } } }
void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data, 4); uint32 id = 0; WorldPacket data(80); AreaTrigger *pAreaTrigger = NULL; recv_data >> id; sLog.outDebug("AreaTrigger: %u", id); pAreaTrigger = sWorld.GetAreaTrigger(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(pAreaTrigger && pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } if(pAreaTrigger) { bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; sprintf(lvltext, "at least level %d", pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(); //death system check. Corpse *pCorpse = NULL; CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = sWorld.GetMapInformation(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()); if(pCorpse) { pMapinfo = sWorld.GetMapInformation(pCorpse->GetMapId()); if(pMapinfo) { if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } else if(pMapinfo->type != INSTANCE_NONRAID) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } sWorldCreator.CheckInstanceForObject(static_cast<Object*>(_player), pMapinfo); _player->SaveEntryPoint(); _player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { _player->SaveEntryPoint(); _player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = sWorld.GetMapInformation(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } } }
void WorldSession::_HandleAreaTriggerOpcode(uint32 id) { sLog.outDebug("AreaTrigger: %u", id); WorldPacket data(80); AreaTrigger * pAreaTrigger = AreaTriggerStorage.LookupEntry(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(GetPermissionCount()) { sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u.", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id); } /* if we don't have an areatrigger, create one on the stack to use for gm scripts :p */ if(!pAreaTrigger) { AreaTrigger tmpTrigger; tmpTrigger.AreaTriggerID = id; ScriptSystem->OnActivateAreaTrigger(&tmpTrigger, _player); return; } /* script prerequsites */ if(ScriptSystem->OnActivateAreaTrigger(pAreaTrigger, _player) == false) return; if(pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; snprintf(lvltext, 30, "at least level %d", (int)pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); //death system check. Corpse *pCorpse = NULL; // CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->iInstanceType == MODE_HEROIC && pMapinfo->type != INSTANCE_NULL) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Heroic mode is not available for this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && GetPlayer()->InGroup() && GetPlayer()->GetGroup()->GetGroupType() != GROUP_TYPE_RAID) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && !GetPlayer()->InGroup()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_quest && !_player->HasFinishedQuest(pMapinfo->required_quest)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_item && !_player->GetItemInterface()->GetItemCount(pMapinfo->required_item, true)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetGUIDLow()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(GetPlayer()->InGroup()) { MapMgr * groupinstance = sWorldCreator.GetInstanceByGroup(GetPlayer()->GetGroup(), GetPlayer(), pMapinfo); if (groupinstance) { if(groupinstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); GetPlayer()->ResurrectPlayer(); return; } } } //if its a raid instance and corpse is inside and player is not in a group, ressurect if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } //if its a instance and player is trying to enter when corpse is on a diferent instance, repop back else if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pCorpse->GetMapId() != pAreaTrigger->Mapid) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } bool result = sWorldCreator.CheckInstanceForObject(static_cast<Object*>(GetPlayer()), pMapinfo); if(result) { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } }
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player* plr, uint32 instanceid) { // preteleport is where all the magic happens :P instance creation, etc. MapInfo * inf = LimitedMapInfoStorage.LookupEntry(mapid); MapEntry* map = dbcMap.LookupEntry(mapid); InstanceMap * instancemap; Instance * in = NULL; //is the map vaild? if(inf == NULL || mapid >= NUM_MAPS) return INSTANCE_ABORT_NOT_FOUND; // main continent check. if(inf->type == INSTANCE_NULL) // we can check if the destination world server is online or not and then cancel them before they load. return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND; // shouldn't happen if(inf->type == INSTANCE_PVP) return INSTANCE_ABORT_NOT_FOUND; if(map->israid()) // check that heroic mode is available if the player has requested it. { if(plr->iRaidType > 1 && inf->type != INSTANCE_MULTIMODE) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; } else if(plr->iInstanceType && inf->type != INSTANCE_MULTIMODE) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; //do we need addition raid/heroic checks? Group * pGroup = plr->GetGroup() ; if( !plr->triggerpass_cheat ) { // players without groups cannot enter raid instances (no soloing them:P) if( pGroup == NULL && (map->israid() || inf->type == INSTANCE_MULTIMODE)) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; //and has the required level if( plr->getLevel() < 80) { if(!map->israid()) { //otherwise we still need to be lvl 70/80 for heroic. if( plr->iInstanceType && plr->getLevel() < uint32(inf->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70)) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; } else //otherwise we still need to be lvl 70/80 for heroic. if( plr->iRaidType > 1 && plr->getLevel() < uint32(inf->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70)) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; //and we might need a key too. bool reqkey = (inf->heroic_key[0] || inf->heroic_key[1])? true : false; bool haskey = (plr->GetItemInterface()->GetItemCount(inf->heroic_key[0], false) || plr->GetItemInterface()->GetItemCount(inf->heroic_key[1], false))? true : false; if(reqkey && !haskey) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; } } // if we are here, it means: // 1) we're a non-raid instance // 2) we're a raid instance, and the person is in a group. // so, first we have to check if they have an instance on this map already, if so, allow them to teleport to that. // next we check if there is a saved instance belonging to him. // otherwise, we can create them a new one. m_mapLock.Acquire(); //find all instances for our map instancemap = m_instances[mapid]; if(instancemap) { InstanceMap::iterator itr; // do we have a specific instance id we should enter (saved or active). // don't bother looking for saved instances, if we had one we found it in areatrigger.cpp if(instanceid != 0) { itr = instancemap->find(instanceid); if(itr != instancemap->end()) { in = itr->second; //we have an instance,but can we enter it? uint8 owns = PlayerOwnsInstance( in, plr ); if( owns >= OWNER_CHECK_OK ) { // If the map is active and has players if(in->m_mapMgr && in->m_mapMgr->HasPlayers() && !plr->triggerpass_cheat) { //check if combat is in progress if( in->m_mapMgr->IsCombatInProgress()) { m_mapLock.Release(); return INSTANCE_ABORT_ENCOUNTER; } // check if we are full if( in->m_mapMgr->GetPlayerCount() >= inf->playerlimit ) { m_mapLock.Release(); return INSTANCE_ABORT_FULL; } } uint32 plrdiff = map->israid() ? plr->iRaidType : plr->iInstanceType; if(in->m_difficulty == plrdiff) { //wakeup call for saved instances if(!in->m_mapMgr) in->m_mapMgr = _CreateInstance(in); if(owns == OWNER_CHECK_SAVED_OK && !in->m_mapMgr->HasPlayers()) { if(plr->GetGroup()) in->m_creatorGroup = plr->GetGroupID(); } m_mapLock.Release(); return INSTANCE_OK; } else { m_mapLock.Release(); return INSTANCE_ABORT_TOO_MANY; } } else DEBUG_LOG("InstanceMgr","Check failed %s, return code %u",plr->GetName(), owns); } m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } else { // search all active instances and see if we have one here. for(itr = instancemap->begin(); itr != instancemap->end();) { in = itr->second; ++itr; //we have an instance,but do we own it? uint8 owns = PlayerOwnsInstance(in, plr); if( owns >= OWNER_CHECK_OK ) { // check the player count and in combat status. if(in->m_mapMgr && in->m_mapMgr->HasPlayers() && !plr->triggerpass_cheat) { if( in->m_mapMgr->IsCombatInProgress()) { m_mapLock.Release(); return INSTANCE_ABORT_ENCOUNTER; } // check if we are full if( in->m_mapMgr->GetPlayerCount() >= inf->playerlimit ) { m_mapLock.Release(); return INSTANCE_ABORT_FULL; } } uint32 plrdiff = map->israid() ? plr->iRaidType : plr->iInstanceType; if(in->m_difficulty == plrdiff) { //wakeup call for saved instances if(!in->m_mapMgr) in->m_mapMgr = _CreateInstance(in); if(owns == OWNER_CHECK_SAVED_OK && !in->m_mapMgr->HasPlayers()) { if(plr->GetGroup()) in->m_creatorGroup = plr->GetGroupID(); } // found our instance, allow him in. m_mapLock.Release(); return INSTANCE_OK; } } else DEBUG_LOG("InstanceMgr","Check failed %s, return code %u",plr->GetName(), owns); } } } else { if(instanceid != 0) { // wtf, how can we have an instance_id for a mapid which doesn't even exist? m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } // this mapid hasn't been added yet, so we gotta create the hashmap now. m_instances[mapid] = new InstanceMap; instancemap = m_instances[mapid]; } // if we're here, it means we need to create a new instance. bool raid = map->israid(); in = new Instance; in->m_creation = UNIXTIME; in->m_expiration = (raid ? UNIXTIME + inf->cooldown : 0); // expire time 0 is 10 minutes after last player leaves in->m_creatorGuid = plr->GetLowGUID(); in->m_creatorGroup = (pGroup ? pGroup->GetID() : 0); in->m_difficulty = (raid ? plr->iRaidType : plr->iInstanceType); in->m_instanceId = GenerateInstanceID(); in->m_mapId = mapid; in->m_mapMgr = NULLMAPMGR; // always start off without a map manager, it is created in _CreateInstance(in) //crash fix; GM's without group will start up raid instances as if they where nonraids //this to avoid exipring check, this is mainly for developers purpose; GM's should NOT invite any players here! if( plr->triggerpass_cheat && !plr->GetGroup() && raid) { const char * message = "Started this instance for development purposes only, do not invite players!!"; sEventMgr.AddEvent( plr, &Player::_Warn, message, EVENT_UNIT_SENDMESSAGE, 5000, 1, 0); } in->m_mapInfo = inf; in->m_dbcMap = map; in->m_isBattleground = false; plr->SetInstanceID(in->m_instanceId); DEBUG_LOG("InstanceMgr", "Prepared new %s %u for player %u and group %u on map %u with difficulty %u. (%u)", raid ? "Raid" : "Instance" ,in->m_instanceId, in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_difficulty, in->m_instanceId); // apply it in the instance map instancemap->insert( InstanceMap::value_type( in->m_instanceId, in ) ); // create the actual instance (if we don't GetInstance() won't be able to access it). in->m_mapMgr = _CreateInstance(in); // instance created ok, i guess? return the ok for him to transport. m_mapLock.Release(); return INSTANCE_OK; }
// ItmSeqMovingFunction::preCodeGen // // All of the moving sequence functions have been transformed away at this // point except min and max. Transform these operations to a while-loop which // iterates over the past rows testing the min/max condition for each row. // Use the ItmScalarMin/Max functions for computing the min/max. // ItemExpr *ItmSeqMovingFunction::preCodeGen(Generator *generator) { if (nodeIsPreCodeGenned()) return this; markAsPreCodeGenned(); // Get some local handles... // CollHeap *wHeap = generator->wHeap(); ItemExpr *itmChild = child(0)->castToItemExpr(); ItemExpr *itmWindow = child(1)->castToItemExpr(); // What scalar operation needs to be done. // OperatorTypeEnum operation; if(getOperatorType() == ITM_MOVING_MIN) operation = ITM_SCALAR_MIN; else operation = ITM_SCALAR_MAX; // Allocate a HostVar for local storage of the index. // ItemExpr *itmLocalCounter = new(wHeap) HostVar("_sys_LocalCounter", new(wHeap) SQLInt(wHeap, TRUE,FALSE), TRUE); // Expression to initailize the iterator. // ItemExpr *itmLocalCounterInitialize = new(wHeap) Assign(itmLocalCounter, new(wHeap) ConstValue(0), FALSE); // Expression to increment the iterator. // ItemExpr *itmLocalCounterIncrement = new(wHeap) Assign(itmLocalCounter, new(wHeap) BiArith(ITM_PLUS, itmLocalCounter, new (wHeap) ConstValue(1)), FALSE); // Allocate a HostVar for referencing the result before it is computed. // ItemExpr *itmResult = new(wHeap) HostVar("_sys_Result", getValueId().getType().newCopy(wHeap), TRUE); // Expression to initialize the result. // ItemExpr *itmResultInitialize = new(wHeap) Assign(itmResult, new(wHeap) ConstValue()); // Expression to compute the min/max. // ItemExpr *itmOffsetExpr = new(wHeap) ItmSeqOffset( itmChild, itmLocalCounter); ((ItmSeqOffset *)itmOffsetExpr)->setIsOLAP(isOLAP()); ItemExpr *itmResultUpdate = new(wHeap) Assign(itmResult, new(wHeap) ItmScalarMinMax(operation, itmResult, itmOffsetExpr)); // Construct code blocks for the initialization and body for the while-loop // ItemExpr *itmInit = new(wHeap) ItmBlockFunction(itmLocalCounterInitialize, itmResultInitialize); ItemExpr *itmBody = new(wHeap) ItmBlockFunction(itmResultUpdate, itmLocalCounterIncrement); // Construct the While loop (i < window) // ItemExpr *itmLoopCondition = new(wHeap) BiRelat (ITM_LESS, itmLocalCounter, itmWindow); ItemExpr *itmWhile = new(wHeap) ItmWhileFunction(itmBody, itmLoopCondition); // Construct the blocks to contain the initialization and looping. // The result is the final value of the min/max. // ItemExpr *itmBlock = new(wHeap) ItmBlockFunction (new(wHeap) ItmBlockFunction(itmInit, itmWhile), itmResult); // Replace the item for this value id with the new item expression. // getValueId().replaceItemExpr(itmBlock); // Run the new expression through type and value Id synthesis. // itmBlock->synthTypeAndValueId(TRUE); // Map the reference to the result to the actual result in the map table. // Attributes *attr = generator->getMapInfo(itmBlock->getValueId())->getAttr(); MapInfo *mapInfo = generator->addMapInfo(itmResult->getValueId(), attr); itmResult->markAsPreCodeGenned(); mapInfo->codeGenerated(); // Return the preCodeGen of the new expression. // return itmBlock->preCodeGen(generator); }
// ItmSeqRunningFunction::preCodeGen // // Transforms the running sequence functions into scalar expressions // that use offset to reference the previous value of the function. // ItemExpr *ItmSeqRunningFunction::preCodeGen(Generator *generator) { if (nodeIsPreCodeGenned()) return this; markAsPreCodeGenned(); // Get some local handles... // CollHeap *wHeap = generator->wHeap(); ItemExpr *itmChild = child(0)->castToItemExpr(); // Allocate a HostVar for referencing the result before it is computed. // ItemExpr *itmResult = new(wHeap) HostVar("_sys_Result", getValueId().getType().newCopy(wHeap), TRUE); // Create an item expression to reference the previous // value of this running sequence function. // ItemExpr *offExpr = new(wHeap) ItmSeqOffset(itmResult, 1); ((ItmSeqOffset *)offExpr)->setIsOLAP(isOLAP()); // Add the sequence function specific computation. // ItemExpr *itmNewSeqFunc = 0; switch(getOperatorType()) { case ITM_RUNNING_COUNT: { // By this point ITM_RUNNING_COUNT is count(column). The count // is one more than the previous count if the current column is // not null, otherwise, it is the previous count. // // Create the increment value. For non-nullable values, this // is always 1, essentially runningcount(*). // ItemExpr *incr; if(itmChild->getValueId().getType().supportsSQLnullLogical()) { incr = generator->getExpGenerator()->createExprTree ("CASE WHEN @A1 IS NULL THEN @A3 ELSE @A2 END", 0, 3, itmChild, new(wHeap) ConstValue(1), new(wHeap) ConstValue(0)); } else { incr = new(wHeap) ConstValue(1); } ((ItmSeqOffset *)offExpr)->setNullRowIsZero(TRUE); ItemExpr *src = offExpr; // Do the increment. // itmNewSeqFunc = new(wHeap) BiArith(ITM_PLUS, src, incr); } break; case ITM_RUNNING_SUM: { // SUM(sum from previous row, child) // itmNewSeqFunc = new(wHeap) BiArithSum(ITM_PLUS, offExpr, itmChild); } break; case ITM_RUNNING_MIN: { // MIN(min from previous rows, child) // itmNewSeqFunc = new(wHeap) ItmScalarMinMax(ITM_SCALAR_MIN, offExpr, itmChild); } break; case ITM_RUNNING_MAX: { // MAX(max from previous row, child) // itmNewSeqFunc = new(wHeap) ItmScalarMinMax(ITM_SCALAR_MAX, offExpr, itmChild); } break; case ITM_LAST_NOT_NULL: { // If the current value is null then use the previous value // of last not null. // itmNewSeqFunc = generator->getExpGenerator()->createExprTree ("CASE WHEN @A2 IS NOT NULL THEN @A2 ELSE @A1 END", 0, 2, offExpr, itmChild); } break; case ITM_RUNNING_CHANGE: { // The running change (or 'rows since changed') can have a // composite child (a list of values) // Convert the list of values to a list of offset of values. // ItemExpr *offChild = itmChild; if (itmChild->getOperatorType() == ITM_ITEM_LIST) { // child is a multi-valued expression, transform into multiple // ExprValueId treePtr = itmChild; ItemExprTreeAsList changeValues(&treePtr, ITM_ITEM_LIST, RIGHT_LINEAR_TREE); offChild = new(wHeap) ItmSeqOffset( changeValues[0], 1); ((ItmSeqOffset *)offChild)->setIsOLAP(isOLAP()); // add Offset expressions for all the items of the list // CollIndex nc = changeValues.entries(); for (CollIndex i = 1; i < nc; i++) { ItemExpr *off = new(generator->wHeap()) ItmSeqOffset( changeValues[i], 1); ((ItmSeqOffset *)off)->setIsOLAP(isOLAP()); offChild = new(generator->wHeap()) ItemList(offChild, off); } } else { offChild = new(wHeap) ItmSeqOffset( offChild, 1); ((ItmSeqOffset *)offChild)->setIsOLAP(isOLAP()); } ((ItmSeqOffset *)offExpr)->setNullRowIsZero(TRUE); ItemExpr *prevValue = offExpr; // Compare the value(s) to the previous value(s). Use special // NULLs flags to treat NULLs as values. Two NULL values are // considered equal here. // ItemExpr *pred = new (wHeap) BiRelat(ITM_EQUAL, itmChild, offChild, TRUE); // Special NULLs // running change = // (value(s) == prev(value(s))) ? prev(running change)+1 : 1 // // Compute base value. // itmNewSeqFunc = new (wHeap) IfThenElse(pred, prevValue, new (wHeap) SystemLiteral(0)); itmNewSeqFunc = new (wHeap) Case(NULL, itmNewSeqFunc); // Force the evaluation of the offset expression so that the // result can be reused by subsequent references. // itmNewSeqFunc = new(wHeap) ItmBlockFunction(offChild, itmNewSeqFunc); // Increment the base value. // itmNewSeqFunc = new (wHeap) BiArith(ITM_PLUS, itmNewSeqFunc, new(wHeap) SystemLiteral(1)); } break; } // Get value Ids and types for all of the items. Must do this typing before // replacing this value Id's item expression -- otherwise, the typing // will give a result different than the type already computed for this // sequence function. // GenAssert(itmNewSeqFunc, "ItmSeqRunningFunction::preCodeGen -- Unexpected Operator Type!"); itmNewSeqFunc->synthTypeAndValueId(TRUE); // Replace the original value ID with the new expression. // getValueId().replaceItemExpr(itmNewSeqFunc); // Map the reference to the result to the actual result in the map table. // Attributes *attr = generator->getMapInfo (itmNewSeqFunc->getValueId())->getAttr(); MapInfo *mapInfo = generator->addMapInfo(itmResult->getValueId(), attr); itmResult->markAsPreCodeGenned(); mapInfo->codeGenerated(); // Return the preCodeGen of the new expression. // return itmNewSeqFunc->preCodeGen(generator); }