Пример #1
0
/** Packages image and elevation layers as a TMS. */
int TMSExporter::exportTMS(MapNode* mapNode, const std::string& path, std::vector< osgEarth::Bounds >& bounds, const std::string& outEarth, bool overwrite, const std::string& extension)
{
  if ( !mapNode )
  {
    _errorMessage = "Invalid MapNode";
    if (_progress.valid()) _progress->onCompleted();
    return 0;
  }

  // folder to which to write the TMS archive.
  std::string rootFolder = path;

  osg::ref_ptr<osgDB::Options> options = new osgDB::Options(_dbOptions);

  // create a folder for the output
  osgDB::makeDirectory(rootFolder);
  if ( !osgDB::fileExists(rootFolder) )
  {
    _errorMessage = "Failed to create root output folder";
    if (_progress.valid()) _progress->onCompleted();
    return 0;
  }

  Map* map = mapNode->getMap();

  // new map for an output earth file if necessary.
  osg::ref_ptr<Map> outMap = 0L;
  if ( !outEarth.empty() )
  {
      // copy the options from the source map first
      outMap = new Map(map->getInitialMapOptions());
  }

  // establish the output path of the earth file, if applicable:
  std::string outEarthName = osgDB::getSimpleFileName(outEarth);
  if (outEarthName.length() > 0 && osgEarth::toLower(osgDB::getFileExtension(outEarthName)) != "earth")
    outEarthName += ".earth";

  std::string outEarthFile = osgDB::concatPaths(rootFolder, outEarthName);
  

  // semaphore and tasks collection for multithreading
  osgEarth::Threading::MultiEvent semaphore;
  osgEarth::TaskRequestVector tasks;
  int taskCount = 0;


  // package any image layers that are enabled and visible
  ImageLayerVector imageLayers;
  map->getImageLayers( imageLayers );

  unsigned imageCount = 0;
  for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i, ++imageCount )
  {
      ImageLayer* layer = i->get();

      if ( layer->getEnabled() && layer->getVisible() )
      {
          std::string layerFolder = toLegalFileName( layer->getName() );
          if ( layerFolder.empty() )
              layerFolder = Stringify() << "image_layer_" << imageCount;

          ParallelTask<PackageLayer>* task = new ParallelTask<PackageLayer>( &semaphore );
          task->init(map, layer, options, rootFolder, layerFolder, true, overwrite, _keepEmpties, _maxLevel, extension, bounds);
          task->setProgressCallback(new PackageLayerProgressCallback(this));
          tasks.push_back(task);
          taskCount++;
      }
  }

  // package any elevation layers that are enabled and visible
  ElevationLayerVector elevationLayers;
  map->getElevationLayers( elevationLayers );

  int elevCount = 0;
  for( ElevationLayerVector::iterator i = elevationLayers.begin(); i != elevationLayers.end(); ++i, ++elevCount )
  {
      ElevationLayer* layer = i->get();
      if ( layer->getEnabled() && layer->getVisible() )
      {
          std::string layerFolder = toLegalFileName( layer->getName() );
          if ( layerFolder.empty() )
              layerFolder = Stringify() << "elevation_layer_" << elevCount;

          ParallelTask<PackageLayer>* task = new ParallelTask<PackageLayer>( &semaphore );
          task->init(map, layer, options, rootFolder, layerFolder, true, overwrite, _keepEmpties, _maxLevel, extension, bounds);
          task->setProgressCallback(new PackageLayerProgressCallback(this));
          tasks.push_back(task);
          taskCount++;
      }
  }


  // Run all the tasks in parallel
  _totalTasks = taskCount;
  _completedTasks = 0;

  semaphore.reset( _totalTasks );

  for( TaskRequestVector::iterator i = tasks.begin(); i != tasks.end(); ++i )
        _taskService->add( i->get() );

  // Wait for them to complete
  semaphore.wait();


  // Add successfully packaged layers to the new map object and
  // write out the .earth file (if requested)
  if (outMap.valid())
  {
    for( TaskRequestVector::iterator i = tasks.begin(); i != tasks.end(); ++i )
    {
      PackageLayer* p = dynamic_cast<PackageLayer*>(i->get());
      if (p)
      {
        if (p->_packageResult.ok)
        {
          TMSOptions tms;
          tms.url() = URI(osgDB::concatPaths(p->_layerFolder, "tms.xml"), outEarthFile );

          if (p->_imageLayer.valid())
          {
            ImageLayerOptions layerOptions( p->_imageLayer->getName(), tms );
            layerOptions.mergeConfig( p->_imageLayer->getInitialOptions().getConfig(true) );
            layerOptions.cachePolicy() = CachePolicy::NO_CACHE;

            outMap->addImageLayer( new ImageLayer(layerOptions) );
          }
          else
          {
            ElevationLayerOptions layerOptions( p->_elevationLayer->getName(), tms );
            layerOptions.mergeConfig( p->_elevationLayer->getInitialOptions().getConfig(true) );
            layerOptions.cachePolicy() = CachePolicy::NO_CACHE;

            outMap->addElevationLayer( new ElevationLayer(layerOptions) );
          }
        }
        else
        {
          OE_WARN << LC << p->_packageResult.message << std::endl;
        }
      }
    }
  }

  if ( outMap.valid() )
  {
      MapNodeOptions outNodeOptions = mapNode->getMapNodeOptions();
      osg::ref_ptr<MapNode> outMapNode = new MapNode(outMap.get(), outNodeOptions);
      if ( !osgDB::writeNodeFile(*outMapNode.get(), outEarthFile) )
      {
          OE_WARN << LC << "Error writing earth file to \"" << outEarthFile << "\"" << std::endl;
      }
      else
      {
          OE_NOTICE << LC << "Wrote earth file to \"" << outEarthFile << "\"" << std::endl;
      }
  }


  // Mark the progress callback as completed
  if (_progress.valid()) _progress->onCompleted();

  return elevCount + imageCount;
}
Пример #2
0
void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/)
{
    if (!creature)
        creature = me;

    if (!creature->CanHaveThreatList())
        return;

    Map* map = creature->GetMap();
    if (!map->IsDungeon())                                  //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
    {
        sLog->outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
        return;
    }

    if (!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
    {
        if (Unit* nearTarget = creature->SelectNearestTarget(maxRangeToNearestTarget))
            creature->AI()->AttackStart(nearTarget);
        else if (creature->isSummon())
        {
            if (Unit* summoner = creature->ToTempSummon()->GetSummoner())
            {
                Unit* target = summoner->getAttackerForHelper();
                if (!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty())
                    target = summoner->getThreatManager().getHostilTarget();
                if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target)))
                    creature->AI()->AttackStart(target);
            }
        }
    }

    if (!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
    {
        sLog->outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry());
        return;
    }

    Map::PlayerList const& playerList = map->GetPlayers();

    if (playerList.isEmpty())
        return;

    for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
    {
        if (Player* player = itr->getSource())
        {
            if (player->isGameMaster())
                continue;

            if (player->isAlive())
            {
                creature->SetInCombatWith(player);
                player->SetInCombatWith(creature);
                creature->AddThreat(player, 0.0f);
            }

            /* Causes certain things to never leave the threat list (Priest Lightwell, etc):
            for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
            {
                creature->SetInCombatWith(*itr);
                (*itr)->SetInCombatWith(creature);
                creature->AddThreat(*itr, 0.0f);
            }*/
        }
    }
}
Пример #3
0
PropertyStream::Map::Map (std::string const& key, Map& map)
    : m_stream (map.stream())
{
    m_stream.map_begin (key);
}
Пример #4
0
void SurfaceItem::render(const Map &map, const Camera &camera)
{
    int zone = map.zone(vertices().at(0));

    GLuint tex = textureId();

    if (zone < 0)
        return;

    m_program->bind();
    m_program->setUniformValue(m_matrixUniform, camera.viewProjectionMatrix());

    QSize size = surface()->size();
    m_program->setUniformValue(m_pixelSizeUniform, 5. / size.width(), 5. / size.height());
    m_program->setUniformValue(m_eyeUniform, camera.viewPos());
    m_program->setUniformValue(m_focusColorUniform, GLfloat(m_opacity));
    m_program->setUniformValueArray(m_lightsUniform, map.lights(zone).constData(), map.lights(zone).size());
    m_program->setUniformValue(m_numLightsUniform, map.lights(zone).size());

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);

    QVector<QVector3D> v = vertices();

    QVector3D va = v[0];
    QVector3D vb = v[1];
    QVector3D vc = v[2];
    QVector3D vd = v[3];

    QVector<QVector3D> vertexBuffer;
    vertexBuffer << va << vb << vd << vd << vb << vc;

    qreal y1 = 0;
    qreal y2 = 1;

    if (surface()->origin() == QWaylandSurface::OriginTopLeft)
        qSwap(y1, y2);

    QVector<QVector2D> texCoordBuffer;
    texCoordBuffer << QVector2D(0, y2) << QVector2D(1, y2)
                   << QVector2D(0, y1) << QVector2D(0, y1)
                   << QVector2D(1, y2) << QVector2D(1, y1);

    m_program->setUniformValue(m_normalUniform, -QVector3D::crossProduct(vb - va, vc - va).normalized());

    m_program->enableAttributeArray(m_vertexAttr);
    m_program->setAttributeArray(m_vertexAttr, vertexBuffer.constData());
    m_program->enableAttributeArray(m_texCoordAttr);
    m_program->setAttributeArray(m_texCoordAttr, texCoordBuffer.constData());

    glEnable(GL_BLEND);
    glDisable(GL_CULL_FACE);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    glDrawArrays(GL_TRIANGLES, 0, 6);

    glDisable(GL_BLEND);

    m_program->disableAttributeArray(m_texCoordAttr);
    m_program->disableAttributeArray(m_vertexAttr);

#if 0
    QOpenGLPaintDevice device(camera.viewSize());
    QPainter p(&device);

    va = camera.viewProjectionMatrix().map(va);
    vb = camera.viewProjectionMatrix().map(vb);
    vc = camera.viewProjectionMatrix().map(vc);
    vd = camera.viewProjectionMatrix().map(vd);

    QVector3D c(camera.viewSize().width() * 0.5, camera.viewSize().height() * 0.5, 0);
    va = c + c * va * QVector3D(1, -1, 0);
    vb = c + c * vb * QVector3D(1, -1, 0);
    vc = c + c * vc * QVector3D(1, -1, 0);
    vd = c + c * vd * QVector3D(1, -1, 0);

    QPointF pa(va.x(), va.y());
    QPointF pb(vb.x(), vb.y());
    QPointF pc(vc.x(), vc.y());
    QPointF pd(vd.x(), vd.y());

    p.drawLine(pa, pb);
    p.drawLine(pb, pc);
    p.drawLine(pc, pd);
    p.drawLine(pd, pa);

    extern QVector3D debug;

    QVector3D d = camera.viewProjectionMatrix().map(debug);
    d = c + c * d * QVector3D(1, -1, 0);

    static QVector3D old;
    if (debug != old)
        old = debug;

    p.setPen(Qt::NoPen);
    p.setBrush(Qt::red);
    p.drawEllipse(QRectF(d.x() - 2, d.y() - 2, 4, 4));

    p.end();
#endif
}
Пример #5
0
        void UpdateAI(const uint32 diff)
        {
            //Check if we have a target
            if (!UpdateVictim())
            {
                //No target so we'll use this section to do our random wispers instance wide
                //WisperTimer
                if (WisperTimer <= diff)
                {
                    Map* map = me->GetMap();
                    if (!map->IsDungeon())
                        return;

                    //Play random sound to the zone
                    Map::PlayerList const &PlayerList = map->GetPlayers();

                    if (!PlayerList.isEmpty())
                    {
                        for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
                        {
                            if (Player* pPlr = itr->getSource())
                                pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER, pPlr);
                        }
                    }

                    //One random wisper every 90 - 300 seconds
                    WisperTimer = urand(90000, 300000);
                } else WisperTimer -= diff;

                return;
            }

            me->SetTarget(0);

            //No instance
            if (!instance)
                return;

            uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE);
            if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK)
            {
                // EyeTentacleTimer
                if (EyeTentacleTimer <= diff)
                {
                    //Spawn the 8 Eye Tentacles in the corret spots
                    SpawnEyeTentacle(0, 20);                //south
                    SpawnEyeTentacle(10, 10);               //south west
                    SpawnEyeTentacle(20, 0);                //west
                    SpawnEyeTentacle(10, -10);              //north west

                    SpawnEyeTentacle(0, -20);               //north
                    SpawnEyeTentacle(-10, -10);             //north east
                    SpawnEyeTentacle(-20, 0);               // east
                    SpawnEyeTentacle(-10, 10);              // south east

                    EyeTentacleTimer = 30000; // every 30sec in phase 2
                } else EyeTentacleTimer -= diff;
            }

            switch (currentPhase)
            {
                //Transition phase
                case PHASE_CTHUN_TRANSITION:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Switch to c'thun model
                        me->InterruptNonMeleeSpells(false);
                        DoCast(me, SPELL_TRANSFORM, false);
                        me->SetFullHealth();

                        me->SetVisible(true);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);

                        //Emerging phase
                        //AttackStart(Unit::GetUnit(*me, HoldpPlayer));
                        DoZoneInCombat();

                        //Place all units in threat list on outside of stomach
                        Stomach_Map.clear();

                        for (std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i)
                            Stomach_Map[(*i)->getUnitGuid()] = false;   //Outside stomach

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;

                //Body Phase
                case PHASE_CTHUN_STOMACH:
                    //Remove Target field
                    me->SetTarget(0);

                    //Weaken
                    if (FleshTentaclesKilled > 1)
                    {
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK);

                        DoScriptText(EMOTE_WEAKENED, me);
                        PhaseTimer = 45000;

                        DoCast(me, SPELL_PURPLE_COLORATION, true);

                        UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin();

                        //Kick all players out of stomach
                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = Unit::GetUnit(*me, i->first);

                            //Only move units in stomach
                            if (unit && i->second == true)
                            {
                                //Teleport each player out
                                DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6));

                                //Cast knockback on them
                                DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                //Remove the acid debuff
                                unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                i->second = false;
                            }
                            ++i;
                        }

                        return;
                    }

                    //Stomach acid
                    if (StomachAcidTimer <= diff)
                    {
                        //Apply aura to all players in stomach
                        UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin();

                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = Unit::GetUnit(*me, i->first);

                            //Only apply to units in stomach
                            if (unit && i->second == true)
                            {
                                //Cast digestive acid on them
                                DoCast(unit, SPELL_DIGESTIVE_ACID, true);

                                //Check if player should be kicked from stomach
                                if (unit->IsWithinDist3d(&KickPos, 15.0f))
                                {
                                    //Teleport each player out
                                    DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6));

                                    //Cast knockback on them
                                    DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                    //Remove the acid debuff
                                    unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                    i->second = false;
                                }
                            }
                            ++i;
                        }

                        StomachAcidTimer = 4000;
                    } else StomachAcidTimer -= diff;

                    //Stomach Enter Timer
                    if (StomachEnterTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Set target in stomach
                            Stomach_Map[target->GetGUID()] = true;
                            target->InterruptNonMeleeSpells(false);
                            target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID());
                            StomachEnterTarget = target->GetGUID();
                            StomachEnterVisTimer = 3800;
                        }

                        StomachEnterTimer = 13800;
                    } else StomachEnterTimer -= diff;

                    if (StomachEnterVisTimer && StomachEnterTarget)
                    {
                        if (StomachEnterVisTimer <= diff)
                        {
                            //Check for valid player
                            Unit* unit = Unit::GetUnit(*me, StomachEnterTarget);

                            if (unit)
                            {
                                DoTeleportPlayer(unit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O);
                            }

                            StomachEnterTarget = 0;
                            StomachEnterVisTimer = 0;
                        } else StomachEnterVisTimer -= diff;
                    }

                    //GientClawTentacleTimer
                    if (GiantClawTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(MOB_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant claw tentacle every minute
                        GiantClawTentacleTimer = 60000;
                    } else GiantClawTentacleTimer -= diff;

                    //GiantEyeTentacleTimer
                    if (GiantEyeTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(MOB_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant eye tentacle every minute
                        GiantEyeTentacleTimer = 60000;
                    } else GiantEyeTentacleTimer -= diff;

                    break;

                //Weakened state
                case PHASE_CTHUN_WEAK:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Remove purple coloration
                        me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION);

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;
            }
        }
Пример #6
0
    void SetData(uint32 type, uint32 data)
    {
        switch (type)
        {
        case DATA_RAGEWINTERCHILLEVENT:
            Encounters[0] = data;
            break;
        case DATA_ANETHERONEVENT:
            Encounters[1] = data;
            break;
        case DATA_KAZROGALEVENT:
            Encounters[2] = data;
            break;
        case DATA_AZGALOREVENT:
            {
                Encounters[3] = data;
                if (data == DONE)
                {
                    if (ArchiYell)break;
                    ArchiYell = true;

                    Creature* pCreature = instance->GetCreature(Azgalor);
                    if (pCreature)
                    {
                        Creature* pUnit = pCreature->SummonCreature(21987, pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);

                        Map* pMap = pCreature->GetMap();
                        if (pMap->IsDungeon() && pUnit)
                        {
                            pUnit->SetVisibility(VISIBILITY_OFF);
                            Map::PlayerList const& PlayerList = pMap->GetPlayers();
                            if (PlayerList.isEmpty())
                                return;

                            for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                            {
                                if (i->getSource())
                                {
                                    WorldPacket data(SMSG_MESSAGECHAT, 200);
                                    pUnit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->getSource()->GetGUID());
                                    i->getSource()->GetSession()->SendPacket(&data);

                                    WorldPacket data2(SMSG_PLAY_SOUND, 4);
                                    data2 << 10986;
                                    i->getSource()->GetSession()->SendPacket(&data2);
                                }
                            }
                        }
                    }
                }
            }
            break;
        case DATA_ARCHIMONDEEVENT:
            Encounters[4] = data;
            break;
        case DATA_RESET_TRASH_COUNT:
            Trash = 0;
            break;

        case DATA_TRASH:
            if (data) Trash = data;
            else     Trash--;
            UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash);
            break;
        case DATA_ALLIANCE_RETREAT:
            allianceRetreat = data;
            OpenDoor(HordeGate, true);
            SaveToDB();
            break;
        case DATA_HORDE_RETREAT:
            hordeRetreat = data;
            OpenDoor(ElfGate, true);
            SaveToDB();
            break;
        case DATA_RAIDDAMAGE:
            RaidDamage += data;
            if (RaidDamage >= MINRAIDDAMAGE)
                RaidDamage = MINRAIDDAMAGE;
            break;
        case DATA_RESET_RAIDDAMAGE:
            RaidDamage = 0;
            break;
        }

        debug_log("OSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data);

        if (data == DONE)
            SaveToDB();
    }
Пример #7
0
    static bool HandleWpModifyCommand(ChatHandler* handler, const char* args)
    {
        if (!*args)
            return false;

        // first arg: add del text emote spell waittime move
        char* show_str = strtok((char*)args, " ");
        if (!show_str)
        {
            return false;
        }

        std::string show = show_str;
        // Check
        // Remember: "show" must also be the name of a column!
        if ((show != "delay") && (show != "action") && (show != "action_chance")
            && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd")
            )
        {
            return false;
        }

        // Next arg is: <PATHID> <WPNUM> <ARGUMENT>
        char* arg_str = NULL;

        // Did user provide a GUID
        // or did the user select a creature?
        // -> variable lowguid is filled with the GUID of the NPC
        uint32 pathid = 0;
        uint32 point = 0;
        uint32 wpGuid = 0;
        Creature* target = handler->getSelectedCreature();

        if (!target || target->GetEntry() != VISUAL_WAYPOINT)
        {
            handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r");
            return false;
        }

        // The visual waypoint
        Creature* wpCreature = NULL;
        wpGuid = target->GetGUIDLow();

        // Did the user select a visual spawnpoint?
        if (wpGuid)
            wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
        // attempt check creature existence by DB data
        else
        {
            handler->PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, wpGuid);
            return false;
        }
        // User did select a visual waypoint?
        // Check the creature
        if (wpCreature->GetEntry() == VISUAL_WAYPOINT)
        {
            QueryResult result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE wpguid = %u", wpGuid);

            if (!result)
            {
                handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
                // Select waypoint number from database
                // Since we compare float values, we have to deal with
                // some difficulties.
                // Here we search for all waypoints that only differ in one from 1 thousand
                // (0.001) - There is no other way to compare C++ floats with mySQL floats
                // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
                const char* maxDIFF = "0.01";
                result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s) and (abs(position_y - %f) <= %s) and (abs(position_z - %f) <= %s)",
                    wpCreature->GetPositionX(), maxDIFF, wpCreature->GetPositionY(), maxDIFF, wpCreature->GetPositionZ(), maxDIFF);
                if (!result)
                {
                    handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
                    return true;
                }
            }

            do
            {
                Field* fields = result->Fetch();
                pathid = fields[0].GetUInt32();
                point  = fields[1].GetUInt32();
            }
            while (result->NextRow());

            // We have the waypoint number and the GUID of the "master npc"
            // Text is enclosed in "<>", all other arguments not
            arg_str = strtok((char*)NULL, " ");
        }

        // Check for argument
        if (show != "del" && show != "move" && arg_str == NULL)
        {
            handler->PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
            return false;
        }

        if (show == "del" && target)
        {
            handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);

            // wpCreature
            Creature* wpCreature = NULL;

            if (wpGuid != 0)
            {
                wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
                wpCreature->CombatStop();
                wpCreature->DeleteFromDB();
                wpCreature->AddObjectToRemoveList();
            }

            WorldDatabase.PExecute("DELETE FROM waypoint_data WHERE id='%u' AND point='%u'",
                pathid, point);
            WorldDatabase.PExecute("UPDATE waypoint_data SET point=point-1 WHERE id='%u' AND point>'%u'",
                pathid, point);

            handler->PSendSysMessage(LANG_WAYPOINT_REMOVED);
            return true;
        }                                                       // del

        if (show == "move" && target)
        {
            handler->PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid);

            Player* chr = handler->GetSession()->GetPlayer();
            Map* map = chr->GetMap();
            {
                // wpCreature
                Creature* wpCreature = NULL;
                // What to do:
                // Move the visual spawnpoint
                // Respawn the owner of the waypoints
                if (wpGuid != 0)
                {
                    wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
                    wpCreature->CombatStop();
                    wpCreature->DeleteFromDB();
                    wpCreature->AddObjectToRemoveList();
                    // re-create
                    Creature* wpCreature2 = new Creature;
                    if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
                    {
                        handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
                        delete wpCreature2;
                        return false;
                    }

                    wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
                    // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
                    wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
                    map->Add(wpCreature2);
                    //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2);
                }

                WorldDatabase.PExecute("UPDATE waypoint_data SET position_x = '%f', position_y = '%f', position_z = '%f' where id = '%u' AND point='%u'",
                    chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), pathid, point);

                handler->PSendSysMessage(LANG_WAYPOINT_CHANGED);
            }
            return true;
        }                                                       // move

        const char *text = arg_str;

        if (text == 0)
        {
            // show_str check for present in list of correct values, no sql injection possible
            WorldDatabase.PExecute("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'",
                show_str, pathid, point);
        }
        else
        {
            // show_str check for present in list of correct values, no sql injection possible
            std::string text2 = text;
            WorldDatabase.EscapeString(text2);
            WorldDatabase.PExecute("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'",
                show_str, text2.c_str(), pathid, point);
        }

        handler->PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
        return true;
    }
Пример #8
0
void ChunkGenerator::setPalmTree(Map& map, int x, int z, int xi, int zj, int noise) {
	// Baummstumpf
  int k = noise + 1;

  // Baummhöhe
  int height = 9;

  // Baumstamm
  for(int l = 0; l <= height; l++) {
  	map.getChunk({x, z}).setBlockType({xi, k+l, zj}, BlockType::Wood);
  }  

  // 3th row
  k = k + height - 1;
  map.getChunk({x, z}).setBlockType({xi-4, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-5, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-6, k, zj}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi+4, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+5, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+6, k, zj}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi-4, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-5, k, zj-1}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi-4, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-5, k, zj+1}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi+4, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+5, k, zj-1}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi+4, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+5, k, zj+1}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj-4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi, k, zj-5}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi, k, zj-6}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj+4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi, k, zj+5}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi, k, zj+6}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi-1, k, zj+4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj+5}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi+1, k, zj+4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj+5}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi-1, k, zj-4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj-5}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi+1, k, zj-4}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj-5}, BlockType::Sand);

  // Coconuts
  map.getChunk({x, z}).setBlockType({xi+1, k, zj}, BlockType::Stone);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj}, BlockType::Stone);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj-1}, BlockType::Stone);
  map.getChunk({x, z}).setBlockType({xi, k, zj+1}, BlockType::Stone);


  // 2nd row
  k++;
  map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Wood);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-2, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-3, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+2, k, zj}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+3, k, zj}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-2, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-3, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+2, k, zj-1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+3, k, zj-1}, BlockType::Sand);

	map.getChunk({x, z}).setBlockType({xi, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-2, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-3, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+2, k, zj+1}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+3, k, zj+1}, BlockType::Sand);


  map.getChunk({x, z}).setBlockType({xi, k, zj-2}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj-2}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj-2}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj+2}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj+2}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj+2}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj-3}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj-3}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj-3}, BlockType::Sand);

  map.getChunk({x, z}).setBlockType({xi, k, zj+3}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi-1, k, zj+3}, BlockType::Sand);
  map.getChunk({x, z}).setBlockType({xi+1, k, zj+3}, BlockType::Sand);

  // 1st row
  k++;
  map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Sand);
}
Пример #9
0
 int getVar(cchar* name) {
     int ret;
     if (!name2index.peek(name, ret)){
         index2name.push(xstrdup(name));
         ret = name2index.set(index2name.last(), index2name.size()-1); }
     return ret; }
Пример #10
0
void ChunkGenerator::setSpruceTree(Map& map, int x, int z, int xi, int zj, int noise) {

	// Baummstumpf
    int k = noise + 1;

    // Baummhöhe
    int height = 2;

    // Baumstamm
    for(int l = 0; l <= height; l++) {
    	map.getChunk({x, z}).setBlockType({xi, k+l, zj}, BlockType::Spruce);
    }

    // 4th row
   	k = k + height;
   	map.getChunk({x, z}).setBlockType({xi, k+1, zj}, BlockType::Spruce);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-2, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+2, k+1, zj}, BlockType::SpruceLeaves);

  	map.getChunk({x, z}).setBlockType({xi, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-2, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+2, k+1, zj+1}, BlockType::SpruceLeaves);

  	map.getChunk({x, z}).setBlockType({xi, k+1, zj-1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj-1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj-1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-2, k+1, zj-1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+2, k+1, zj-1}, BlockType::SpruceLeaves);


  	map.getChunk({x, z}).setBlockType({xi, k+1, zj-2}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj-2}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj-2}, BlockType::SpruceLeaves);

  	map.getChunk({x, z}).setBlockType({xi, k+1, zj+2}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj+2}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj+2}, BlockType::SpruceLeaves);

  	// 3rd row
   	k++;
   	map.getChunk({x, z}).setBlockType({xi, k+1, zj}, BlockType::Spruce);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi, k+1, zj-1}, BlockType::SpruceLeaves);

  	// 2nd row
   	k++;;
   	map.getChunk({x, z}).setBlockType({xi, k+1, zj}, BlockType::SpruceLeaves);

  	// 1st row
   	k++;;
   	map.getChunk({x, z}).setBlockType({xi, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi-1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi+1, k+1, zj}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi, k+1, zj+1}, BlockType::SpruceLeaves);
  	map.getChunk({x, z}).setBlockType({xi, k+1, zj-1}, BlockType::SpruceLeaves);

  	// top row
  	k++;
		map.getChunk({x, z}).setBlockType({xi, k+1, zj}, BlockType::SpruceLeaves);
}
Пример #11
0
void ChunkGenerator::setCactusTree(Map& map, int x, int z, int xi, int zj, int noise) {

	// Baummstumpf
  int k = noise + 1;

  // Baummhöhe
  int height = 7;

  // Baumstamm
  for(int l = 0; l <= height; l++) {
  	map.getChunk({x, z}).setBlockType({xi, k+l, zj}, BlockType::Cactus);
  }

  // 1st arm
  k += 1;
  map.getChunk({x, z}).setBlockType({xi+1, k, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi+2, k, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi+2, k+1, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi+2, k+2, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi+2, k+3, zj}, BlockType::Cactus);

  // 2nd arm
  map.getChunk({x, z}).setBlockType({xi, k+2, zj+1}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+2, zj+2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+3, zj+2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+4, zj+2}, BlockType::Cactus);

  // 3rd arm
  map.getChunk({x, z}).setBlockType({xi, k+1, zj-1}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+1, zj-2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+2, zj-2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+3, zj-2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+4, zj-2}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi, k+5, zj-2}, BlockType::Cactus);

  // 4th arm
  map.getChunk({x, z}).setBlockType({xi-1, k+4, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi-2, k+4, zj}, BlockType::Cactus);
  map.getChunk({x, z}).setBlockType({xi-2, k+5, zj}, BlockType::Cactus);
}
Пример #12
0
void ChunkGenerator::chunkGeneration(Map& map, Vec3i spectatorPos, MapView& mapView) {

  // chunkPos ist Position des Chunks, in dem der Spectator steht in Chunkkoordinaten
  Vec2i chunkPos = map.getChunkPos(spectatorPos);

  for(int x = chunkPos.x - 8; x <= chunkPos.x + 8; x++) {
    for(int z = chunkPos.y - 8; z <= chunkPos.y + 8; z++) {

      if(!map.exists({x * 16, 0, z * 16})) {

        map.addChunk({x, z});
        Chunk chunk = map.getChunk({x, z});
        double simpBiomeNoise = SimplexNoise::noise(0.01*x, 0.01*z, m_biome_seed);
        int biomeNoise = SimplexNoise::noiseInt(0, 126, simpBiomeNoise);

        if(0 <= biomeNoise && biomeNoise <= 44){
          chunk.setBiomeType(BiomeType::Desert);
        }
        if(45 <= biomeNoise && biomeNoise <= 46){
          chunk.setBiomeType(BiomeType::DesertPlain);
        }
        if(47 <= biomeNoise && biomeNoise <= 54){
          chunk.setBiomeType(BiomeType::Plains);
        }
        if(55 <= biomeNoise && biomeNoise <= 56){
          chunk.setBiomeType(BiomeType::PlainForest);
        }
        if(57 <= biomeNoise && biomeNoise <= 69){
          chunk.setBiomeType(BiomeType::Forest);
        }
        // Biome ohne Wasser 
        if(!m_setWater) {
          if(70 <= biomeNoise && biomeNoise <= 74){
            chunk.setBiomeType(BiomeType::Hillside);
          }
          if(75 <= biomeNoise && biomeNoise <= 126){
            chunk.setBiomeType(BiomeType::Mountains);
          } 
        } else {
          if(70 <= biomeNoise && biomeNoise <= 74){
            chunk.setBiomeType(BiomeType::WaterHillside);
          }
          if(75 <= biomeNoise && biomeNoise <= 126){
            chunk.setBiomeType(BiomeType::WaterMountains);
          } 
        }
        
        
        
        
        setBiomes(map, chunk, x, z, biomeNoise);
        
        Vec2i chuPos = Vec2i(x + 1, z);
        if(mapView.exists(chuPos)) {
          mapView.deleteChunkView(chuPos);
        }
        chuPos = Vec2i(x - 1, z);
        if(mapView.exists(chuPos)) {
          mapView.deleteChunkView(chuPos);
        }
        chuPos = Vec2i(x, z + 1);
        if(mapView.exists(chuPos)) {
          mapView.deleteChunkView(chuPos);
        }
        chuPos = Vec2i(x,   z - 1);
        if(mapView.exists(chuPos)) {
          mapView.deleteChunkView(chuPos);
        }
      }
    }
  }
}
Пример #13
0
void ChunkGenerator::setBlockHeight(Map& map, BiomeType type, int x, int z, int xi, int zj, int noise, int biomeNoise) {
  for(int k = 0; k < 128; k++) {
    switch(type) {
      case BiomeType::Desert:
        if(k == noise) {
        	// Bäume setzen
          if(m_setTrees && xi >= 2 && xi <= 13 && zj >= 3 && zj <= 13) {
            int treeDist = rand() % 10000;
          	if(treeDist <= 20) {
            	setCactusTree(map, x, z, xi, zj, noise);	
          	}
      		}
      		// Boden erzeugen
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Sand);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Sand); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

      case BiomeType::DesertPlain:
        if(k == noise) {
        	// Bäume setzen
          if(m_setTrees && xi >= 2 && xi <= 13 && zj >= 3 && zj <= 13) {
            int treeDist = rand() % 10000;
          	if(treeDist <= 5) {
            	setCactusTree(map, x, z, xi, zj, noise);	
          	}
      		}
      		// Boden erzeugen
          int random = rand() % 512;
          if(random < 267){
            map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Sand);
          }else map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Sand); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

        case BiomeType::Plains:
        if(k == noise) {
        	// Bäume setzen
          if(m_setTrees && xi >= 6 && xi <= 9 && zj >= 6 && zj <= 9) {
          	int treeDist = rand() % 10000;
            if(treeDist <= 30) {
            	setPalmTree(map, x, z, xi, zj, noise);	
          	}
      		}
      		// Boden erzeugen
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Dirt); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

      case BiomeType::PlainForest:
        if(k == noise) {
        	// Bäume setzen
          bool isTree = ChunkGenerator::isTreeInNeighborhood(map, x, z, xi, zj, noise+1); // Baum in Umgebung?
          if(m_setTrees && xi >= 3 && xi <= 13 && zj >= 3 && zj <= 13 && isTree == false) {
            int treeDist = rand() % 10000;
          	if(treeDist <= 100) {
            	setSpruceTree(map, x, z, xi, zj, noise);	
          	}
      			if(131 <= treeDist && treeDist <= 160) {
      				setBirchTree(map, x, z, xi, zj, noise);	
      			}
      		}
      		// Boden erzeugen
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Dirt); //  Unter dem Noise-Wert gibt es nur Dirt
        }
        break;

        case BiomeType::Forest:
        if(k == noise) {
          // Bäume setzen
          bool isTree = ChunkGenerator::isTreeInNeighborhood(map, x, z, xi, zj, noise+1); // Baum in Umgebung?
          if(m_setTrees && xi >= 2 && xi <= 13 && zj >= 3 && zj <= 13 && isTree == false) {
            int treeDist = rand() % 10000;
          	if(treeDist <= 100) {
            	setSpruceTree(map, x, z, xi, zj, noise);	
          	}
      			if(101 <= treeDist && treeDist <= 200) {
      				setBirchTree(map, x, z, xi, zj, noise);	
      			}
      		}
      		// Boden erzeugen
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
          // FLussüberlauf
          if(55 <= biomeNoise && biomeNoise <= 69 && noise <= m_waterHeight && m_setWater == true) {
            for(int i = noise; i <= m_waterHeight; i++) {
              map.getChunk({x, z}).setBlockType({xi, i, zj}, BlockType::Water);
            }
          }
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Dirt); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

      case BiomeType::Hillside:
        if(k == noise && noise <= 80) {
          int random = rand() % 512;
          if(random < 350){ 
            map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
          } else map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone);
        } else if (k == noise && noise > 80){
          map.getChunk({x,z}).setBlockType({xi,k,zj}, BlockType::Stone);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Dirt); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

        case BiomeType::Mountains:
        if(k == noise && noise > 75) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone);
        } else if(k == noise && noise <= 75){
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

        case BiomeType::WaterHillside:
        if(k == noise && noise <= 80) {
          int random = rand() % 512;
          if(random < 350){ 
            map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
          } else map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone);
          // Fluss in Hillside
          for(int i = noise; i <= m_waterHeight; i++) {
            map.getChunk({x, z}).setBlockType({xi, i, zj}, BlockType::Water);
          }
        } else if (k == noise && noise > 80){
          map.getChunk({x,z}).setBlockType({xi,k,zj}, BlockType::Stone);
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Dirt); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;

        case BiomeType::WaterMountains:
        if(k == noise && noise > 75) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone);
        } else if(k == noise && noise <= 75){
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Grass);
          // Seen in den Bergen
          for(int i = noise; i <= m_waterHeight; i++) {
            map.getChunk({x, z}).setBlockType({xi, i, zj}, BlockType::Water);
          }
        } else if(k <= noise && k >= noise - 3) {
          map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone); //  Unter dem Noise-Wert gibt es nur Dirt
        } 
        break;
      default: break;
    }
    
    //untere Ebenen werden gleich generiert
    if(k < (noise - 3)) {
      map.getChunk({x, z}).setBlockType({xi, k, zj}, BlockType::Stone);
    }
  }
}
Пример #14
0
    //spawn go
    static bool HandleGameObjectAddCommand(ChatHandler* handler, char const* args)
    {
        if (!*args)
            return false;

        // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
        char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry");
        if (!id)
            return false;

        uint32 objectId = atol(id);
        if (!objectId)
            return false;

        char* spawntimeSecs = strtok(NULL, " ");

        const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId);

        if (!objectInfo)
        {
            handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId);
            handler->SetSentErrorMessage(true);
            return false;
        }

        if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId))
        {
            // report to DB errors log as in loading case
            TC_LOG_ERROR(LOG_FILTER_SQL, "Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.", objectId, objectInfo->type, objectInfo->displayId);
            handler->PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA, objectId);
            handler->SetSentErrorMessage(true);
            return false;
        }

        Player* player = handler->GetSession()->GetPlayer();
        float x = float(player->GetPositionX());
        float y = float(player->GetPositionY());
        float z = float(player->GetPositionZ());
        float o = float(player->GetOrientation());
        Map* map = player->GetMap();

        GameObject* object = new GameObject;
        uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);

        if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
        {
            delete object;
            return false;
        }

        if (spawntimeSecs)
        {
            uint32 value = atoi((char*)spawntimeSecs);
            object->SetRespawnTime(value);
        }

        // fill the gameobject data and save to the db
        object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());

        // this will generate a new guid if the object is in an instance
        if (!object->LoadGameObjectFromDB(guidLow, map))
        {
            delete object;
            return false;
        }

        /// @todo is it really necessary to add both the real and DB table guid here ?
        sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow));

        handler->PSendSysMessage(LANG_GAMEOBJECT_ADD, objectId, objectInfo->name.c_str(), guidLow, x, y, z);
        return true;
    }
Пример #15
0
void CutTool::pathFinished(PathObject* split_path)
{
	Map* map = this->map();
	
	// Get path endpoint and check if it is on the area boundary
	const MapCoordVector& path_coords = split_path->getRawCoordinateVector();
	MapCoord path_end = path_coords.at(path_coords.size() - 1);
	
	PathObject* edited_path = reinterpret_cast<PathObject*>(edit_object);
	PathCoord end_path_coord;
	float distance_sq;
	edited_path->calcClosestPointOnPath(MapCoordF(path_end), distance_sq, end_path_coord);
	
	float click_tolerance_map = 0.001 * edit_widget->getMapView()->pixelToLength(clickTolerance());
	if (distance_sq > click_tolerance_map*click_tolerance_map)
	{
		QMessageBox::warning(window(), tr("Error"), tr("The split line must end on the area boundary!"));
		pathAborted();
		return;
	}
	else if (drag_part_index != edited_path->findPartIndexForIndex(end_path_coord.index))
	{
		QMessageBox::warning(window(), tr("Error"), tr("Start and end of the split line are at different parts of the object!"));
		pathAborted();
		return;
	}
	else if (drag_start_len == end_path_coord.clen)
	{
		QMessageBox::warning(window(), tr("Error"), tr("Start and end of the split line are at the same position!"));
		pathAborted();
		return;
	}
	
	Q_ASSERT(split_path->parts().size() == 1);
	split_path->parts().front().setClosed(false);
	split_path->setCoordinate(split_path->getCoordinateCount() - 1, MapCoord(end_path_coord.pos));
	
	// Do the splitting
	const double split_threshold = 0.01;
	
	MapPart* part = map->getCurrentPart();
	AddObjectsUndoStep* add_step = new AddObjectsUndoStep(map);
	add_step->addObject(part->findObjectIndex(edited_path), edited_path);
	map->removeObjectFromSelection(edited_path, false);
	map->deleteObject(edited_path, true);
	map->setObjectsDirty();
	
	DeleteObjectsUndoStep* delete_step = new DeleteObjectsUndoStep(map);
	
	PathObject* holes = nullptr; // if the edited path contains holes, they are saved in this temporary object
	if (edited_path->parts().size() > 1)
	{
		holes = edited_path->duplicate()->asPath();
		holes->deletePart(0);
	}
	
	bool ok; Q_UNUSED(ok); // "ok" is only used in Q_ASSERT.
	PathObject* parts[2] = { new PathObject { edited_path->parts().front() }, nullptr };
	const PathPart& drag_part = edited_path->parts()[drag_part_index];
	if (drag_part.isClosed())
	{
		parts[1] = new PathObject { *parts[0] };
		
		parts[0]->changePathBounds(drag_part_index, drag_start_len, end_path_coord.clen);
		ok = parts[0]->connectIfClose(split_path, split_threshold);
		Q_ASSERT(ok);

		parts[1]->changePathBounds(drag_part_index, end_path_coord.clen, drag_start_len);
		ok = parts[1]->connectIfClose(split_path, split_threshold);
		Q_ASSERT(ok);
	}
	else
	{
		float min_cut_pos = qMin(drag_start_len, end_path_coord.clen);
		float max_cut_pos = qMax(drag_start_len, end_path_coord.clen);
		float path_len = drag_part.path_coords.back().clen;
		if (min_cut_pos <= 0 && max_cut_pos >= path_len)
		{
			ok = parts[0]->connectIfClose(split_path, split_threshold);
			Q_ASSERT(ok);
			
			parts[1] = new PathObject { *split_path };
			parts[1]->setSymbol(edited_path->getSymbol(), false);
		}
		else if (min_cut_pos <= 0 || max_cut_pos >= path_len)
		{
			float cut_pos = (min_cut_pos <= 0) ? max_cut_pos : min_cut_pos;
			parts[1] = new PathObject { *parts[0] };
			
			parts[0]->changePathBounds(drag_part_index, 0, cut_pos);
			ok = parts[0]->connectIfClose(split_path, split_threshold);
			Q_ASSERT(ok);
			
			parts[1]->changePathBounds(drag_part_index, cut_pos, path_len);
			ok = parts[1]->connectIfClose(split_path, split_threshold);
			Q_ASSERT(ok);
		}
		else
		{
			parts[1] = new PathObject { *parts[0] };
			PathObject* temp_path = new PathObject { *parts[0] };
			
			parts[0]->changePathBounds(drag_part_index, min_cut_pos, max_cut_pos);
			ok = parts[0]->connectIfClose(split_path, split_threshold);
			Q_ASSERT(ok);
			
			parts[1]->changePathBounds(drag_part_index, 0, min_cut_pos);
			ok = parts[1]->connectIfClose(split_path, split_threshold);
			Q_ASSERT(ok);
			
			temp_path->changePathBounds(drag_part_index, max_cut_pos, path_len);
			ok = parts[1]->connectIfClose(temp_path, split_threshold);
			Q_ASSERT(ok);
			
			delete temp_path;
		}
	}
	
	// If the object had holes, check into which parts they go
	if (holes)
	{
		for (const auto& hole : holes->parts())
		{
			PathPartVector::size_type part_index = (parts[0]->isPointOnPath(MapCoordF(holes->getCoordinate(hole.first_index)), 0, false, false) != Symbol::NoSymbol) ? 0 : 1;
			parts[part_index]->getCoordinate(parts[part_index]->getCoordinateCount() - 1).setHolePoint(true);
			parts[part_index]->appendPathPart(hole);
		}
	}
	
	for (auto& object : parts)
	{
		map->addObject(object);
		delete_step->addObject(part->findObjectIndex(object));
		map->addObjectToSelection(object, false);
	}
	
	CombinedUndoStep* undo_step = new CombinedUndoStep(map);
	undo_step->push(add_step);
	undo_step->push(delete_step);
	map->push(undo_step);
	map->setObjectsDirty();
	
	pathAborted();
}
Пример #16
0
/**
 * \brief Sets the map of this entity.
 *
 * Warning: as this function is called when initializing the map,
 * the current map of the game is still the old one.
 *
 * \param map the map
 */
void DynamicTile::set_map(Map &map) {

  MapEntity::set_map(map);
  this->tile_pattern = &map.get_tileset().get_tile_pattern(tile_pattern_id);
}
Пример #17
0
//
// NOTE: run this sample from the repo/tests directory.
//
int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);

    osgViewer::Viewer viewer(arguments);
    s_viewer = &viewer;

    // Start by creating the map:
    s_mapNode = MapNode::load(arguments);
    if ( !s_mapNode )
    {
        Map* map = new Map();

        // Start with a basemap imagery layer; we'll be using the GDAL driver
        // to load a local GeoTIFF file:
        GDALOptions basemapOpt;
        basemapOpt.url() = "../data/world.tif";
        map->addImageLayer( new ImageLayer( ImageLayerOptions("basemap", basemapOpt) ) );

        // That's it, the map is ready; now create a MapNode to render the Map:
        MapNodeOptions mapNodeOptions;
        mapNodeOptions.enableLighting() = false;

        s_mapNode = new MapNode( map, mapNodeOptions );
    }
    s_mapNode->setNodeMask( 0x01 );

        
    // Define a style for the feature data. Since we are going to render the
    // vectors as lines, configure the line symbolizer:
    StyleSheet* styleSheet = buildStyleSheet( Color::Yellow, 2.0f );

    s_source = new FeatureListSource();

    LineString* line = new LineString();
    line->push_back( osg::Vec3d(-60, 20, 0) );
    line->push_back( osg::Vec3d(-120, 20, 0) );
    line->push_back( osg::Vec3d(-120, 60, 0) );
    line->push_back( osg::Vec3d(-60, 60, 0) );
    Feature *feature = new Feature(s_fid++);
    feature->setGeometry( line );
    s_source->insertFeature( feature );
    s_activeFeature = feature;
  
    s_root = new osg::Group;
    s_root->addChild( s_mapNode.get() );

    Session* session = new Session(s_mapNode->getMap(), styleSheet);

    FeatureModelGraph* graph = new FeatureModelGraph( 
        s_source.get(), 
        FeatureModelSourceOptions(), 
        new GeomFeatureNodeFactory(),
        session );

    graph->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    graph->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

    s_root->addChild( graph );

    //Setup the controls
    ControlCanvas* canvas = ControlCanvas::get( &viewer );
    s_root->addChild( canvas );
    Grid *toolbar = createToolBar( );
    canvas->addControl( toolbar );
    canvas->setNodeMask( 0x1 << 1 );



    int col = 0;
    LabelControl* addVerts = new LabelControl("Add Verts");
    toolbar->setControl(col++, 0, addVerts );    
    addVerts->addEventHandler( new AddVertsModeHandler( graph ));
    
    LabelControl* edit = new LabelControl("Edit");
    toolbar->setControl(col++, 0, edit );    
    edit->addEventHandler(new EditModeHandler( graph ));

    unsigned int row = 0;
    Grid *styleBar = createToolBar( );
    styleBar->setPosition(0, 50);
    canvas->addControl( styleBar );
    
    //Make a list of styles
    styleBar->setControl(0, row++, new LabelControl("Styles") );    

    unsigned int numStyles = 8;
    for (unsigned int i = 0; i < numStyles; ++i)
    {
        float w = 50;
        osg::Vec4 color = randomColor();

        float widths[3] = {2, 4, 8};

        unsigned int r = row++;
        for (unsigned int j = 0; j < 3; j++) 
        {
            Control* l = new Control();            
            l->setBackColor( color );
            l->addEventHandler(new ChangeStyleHandler(graph, buildStyleSheet( color, widths[j] ) ));
            l->setSize(w,5 * widths[j]);
            styleBar->setControl(j, r, l);
        }
    }
   
    
    viewer.setSceneData( s_root.get() );
    viewer.setCameraManipulator( new EarthManipulator() );

    if ( s_mapNode )
        viewer.getCamera()->addCullCallback( new osgEarth::Util::AutoClipPlaneCullCallback(s_mapNode->getMap()) );

    // add some stock OSG handlers:
    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

    return viewer.run();
}
Пример #18
0
bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)
{
    if (spellId == SI_SILITHYST_FLAG)
    {
        // if it was dropped away from the player's turn-in point, then create a silithyst mound, if it was dropped near the areatrigger, then it was dispelled by the outdoorpvp, so do nothing
        switch (player->GetTeam())
        {
        case ALLIANCE:
            {
                AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_A);
                if (atEntry)
                {
                    // 5.0f is safe-distance
                    if (player->GetDistance(atEntry->x, atEntry->y, atEntry->z) > 5.0f + atEntry->radius)
                    {
                        // he dropped it further, summon mound
                        GameObject* go = new GameObject;
                        Map* map = player->GetMap();
                        if (!map)
                        {
                            delete go;
                            return true;
                        }

                        if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY))
                        {
                            delete go;
                            return true;
                        }

                        go->SetRespawnTime(0);

                        if (!map->AddToMap(go))
                        {
                            delete go;
                            return true;
                        }
                    }
                }
            }
            break;
        case HORDE:
            {
                AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_H);
                if (atEntry)
                {
                    // 5.0f is safe-distance
                    if (player->GetDistance(atEntry->x, atEntry->y, atEntry->z) > 5.0f + atEntry->radius)
                    {
                        // he dropped it further, summon mound
                        GameObject* go = new GameObject;
                        Map* map = player->GetMap();
                        if (!map)
                        {
                            delete go;
                            return true;
                        }

                        if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY))
                        {
                            delete go;
                            return true;
                        }

                        go->SetRespawnTime(0);

                        if (!map->AddToMap(go))
                        {
                            delete go;
                            return true;
                        }
                    }
                }
            }
            break;
        }
        return true;
    }
    return false;
}
Пример #19
0
Corpse*
ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
{
    Corpse *corpse = GetCorpseForPlayerGUID(player_guid);
    if(!corpse)
    {
        //in fact this function is called from several places
        //even when player doesn't have a corpse, not an error
        //sLog.outError("Try remove corpse that not in map for GUID %ul", player_guid);
        return NULL;
    }

    DEBUG_LOG("Deleting Corpse and spawning bones.");

    Map *map = corpse->FindMap();

    // remove corpse from player_guid -> corpse map
    RemoveCorpse(corpse);

    // done in removecorpse
    // remove resurrectable corpse from grid object registry (loaded state checked into call)
    // do not load the map if it's not loaded
    //Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId());
    //if(map)
    //    map->Remove(corpse, false);

    // remove corpse from DB
    corpse->DeleteFromDB();

    Corpse *bones = NULL;
    // create the bones only if the map and the grid is loaded at the corpse's location
    // ignore bones creating option in case insignia
    if (map && (insignia ||
        (map->IsBattleGroundOrArena() ? sWorld.getConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld.getConfig(CONFIG_DEATH_BONES_WORLD))) &&
        !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
    {
        // Create bones, don't change Corpse
        bones = new Corpse;
        bones->Create(corpse->GetGUIDLow(), map);

        for (int i = 3; i < CORPSE_END; ++i)                    // don't overwrite guid and object type
            bones->SetUInt32Value(i, corpse->GetUInt32Value(i));

        bones->SetGrid(corpse->GetGrid());
        // bones->m_time = m_time;                              // don't overwrite time
        // bones->m_inWorld = m_inWorld;                        // don't overwrite world state
        // bones->m_type = m_type;                              // don't overwrite type
        bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
        bones->SetPhaseMask(corpse->GetPhaseMask(), false);

        bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
        bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);

        for (int i = 0; i < EQUIPMENT_SLOT_END; ++i)
        {
            if(corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
                bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
        }

        // add bones in grid store if grid loaded where corpse placed
        map->Add(bones);
    }

    // all references to the corpse should be removed at this point
    delete corpse;

    return bones;
}
Пример #20
0
        void SetData(uint32 type, uint32 data)
        {
            switch(type)
            {
                case DATA_RAGEWINTERCHILLEVENT: m_auiEncounter[0] = data; break;
                case DATA_ANETHERONEVENT:
                    m_auiEncounter[1] = data;
                    break;
                case DATA_KAZROGALEVENT:        m_auiEncounter[2] = data; break;
                case DATA_AZGALOREVENT:
                    {
                        m_auiEncounter[3] = data;
                        if(data == DONE)
                        {
                            if(ArchiYell)break;
                            ArchiYell = true;

                            Creature* creature = instance->GetCreature(Azgalor);
                            if(creature)
                            {
                                Creature* pUnit = creature->SummonCreature(21987, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);

                                Map* pMap = creature->GetMap();
                                if(pMap->IsDungeon() && pUnit)
                                {
                                    pUnit->SetVisible(false);
                                    Map::PlayerList const &PlayerList = pMap->GetPlayers();
                                    if(PlayerList.isEmpty())
                                         return;

                                    for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                                    {
                                         if(i->getSource())
                                         {
                                            WorldPacket data(SMSG_MESSAGECHAT, 200);
                                            pUnit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->getSource()->GetGUID());
                                            i->getSource()->GetSession()->SendPacket(&data);

                                            WorldPacket data2(SMSG_PLAY_SOUND, 4);
                                            data2 << 10986;
                                            i->getSource()->GetSession()->SendPacket(&data2);
                                         }
                                    }
                                }
                            }
                        }
                    }
                    break;
                case DATA_ARCHIMONDEEVENT:      m_auiEncounter[4] = data; break;
                case DATA_RESET_TRASH_COUNT:    Trash = 0;            break;
                case DATA_TRASH:
                    if(data) Trash = data;
                    else     Trash--;
                    DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash);
                    break;
                case TYPE_RETREAT:
                    if(data == SPECIAL)
                    {
                        if(!m_uiAncientGemGUID.empty())
                        {
                            for(std::list<uint64>::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr)
                            {
                                //don't know how long it expected
                                DoRespawnGameObject(*itr, DAY);
                            }
                        }
                    }
                    break;
                case DATA_ALLIANCE_RETREAT:
                    allianceRetreat = data;
                    HandleGameObject(HordeGate, true);
                    SaveToDB();
                    break;
                case DATA_HORDE_RETREAT:
                    hordeRetreat = data;
                    HandleGameObject(ElfGate, true);
                    SaveToDB();
                    break;
                case DATA_RAIDDAMAGE:
                    RaidDamage += data;
                    if(RaidDamage >= MINRAIDDAMAGE)
                        RaidDamage = MINRAIDDAMAGE;
                    break;
                case DATA_RESET_RAIDDAMAGE:
                    RaidDamage = 0;
                    break;
            }

             sLog->outDebug(LOG_FILTER_TSCR, "TSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data);

            if(data == DONE)
            {
                OUT_SAVE_INST_DATA;

                std::ostringstream saveStream;
                saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
                    << m_auiEncounter[3] << " " << m_auiEncounter[4]
                    << " " << allianceRetreat << " " << hordeRetreat
                    << " " << RaidDamage;

                str_data = saveStream.str();

                SaveToDB();
                OUT_SAVE_INST_DATA_COMPLETE;
            }

        }
Пример #21
0
    static bool HandleWpShowCommand(ChatHandler* handler, const char* args)
    {
        if (!*args)
            return false;

        // first arg: on, off, first, last
        char* show_str = strtok((char*)args, " ");
        if (!show_str)
            return false;

        // second arg: GUID (optional, if a creature is selected)
        char* guid_str = strtok((char*)NULL, " ");

        uint32 pathid = 0;
        Creature* target = handler->getSelectedCreature();

        // Did player provide a PathID?

        if (!guid_str)
        {
            // No PathID provided
            // -> Player must have selected a creature

            if (!target)
            {
                handler->SendSysMessage(LANG_SELECT_CREATURE);
                handler->SetSentErrorMessage(true);
                return false;
            }

            pathid = target->GetWaypointPath();
        }
        else
        {
            // PathID provided
            // Warn if player also selected a creature
            // -> Creature selection is ignored <-
            if (target)
                handler->SendSysMessage(LANG_WAYPOINT_CREATSELECTED);

            pathid = atoi((char*)guid_str);
        }

        std::string show = show_str;
        uint32 Maxpoint;

        //handler->PSendSysMessage("wpshow - show: %s", show);

        // Show info for the selected waypoint
        if (show == "info")
        {
            // Check if the user did specify a visual waypoint
            if (target->GetEntry() != VISUAL_WAYPOINT)
            {
                handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
                handler->SetSentErrorMessage(true);
                return false;
            }

            QueryResult result = WorldDatabase.PQuery("SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow());

            if (!result)
            {
                handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM);
                return true;
            }

            handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r");
            do
            {
                Field* fields = result->Fetch();
                pathid                  = fields[0].GetUInt32();
                uint32 point            = fields[1].GetUInt32();
                uint32 delay            = fields[2].GetUInt32();
                uint32 flag             = fields[3].GetUInt32();
                uint32 ev_id            = fields[4].GetUInt32();
                uint32 ev_chance        = fields[5].GetUInt32();

                handler->PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid);
                handler->PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay);
                handler->PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag);
                handler->PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id);
                handler->PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance);
            }
            while (result->NextRow());

            return true;
        }

        if (show == "on")
        {
            QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = '%u'", pathid);

            if (!result)
            {
                handler->SendSysMessage("|cffff33ffPath no found.|r");
                handler->SetSentErrorMessage(true);
                return false;
            }

            handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid);

            // Delete all visuals for this NPC
            QueryResult result2 = WorldDatabase.PQuery("SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid);

            if (result2)
            {
                bool hasError = false;
                do
                {
                    Field* fields = result2->Fetch();
                    uint32 wpguid = fields[0].GetUInt32();
                    Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid, VISUAL_WAYPOINT, HIGHGUID_UNIT));

                    if (!creature)
                    {
                        handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
                        hasError = true;
                        WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", wpguid);
                    }
                    else
                    {
                        creature->CombatStop();
                        creature->DeleteFromDB();
                        creature->AddObjectToRemoveList();
                    }

                }
                while (result2->NextRow());

                if (hasError)
                {
                    handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
                    handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
                    handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
                }
            }

            do
            {
                Field* fields = result->Fetch();
                uint32 point    = fields[0].GetUInt32();
                float x         = fields[1].GetFloat();
                float y         = fields[2].GetFloat();
                float z         = fields[3].GetFloat();

                uint32 id = VISUAL_WAYPOINT;

                Player* chr = handler->GetSession()->GetPlayer();
                Map* map = chr->GetMap();
                float o = chr->GetOrientation();

                Creature* wpCreature = new Creature;
                if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
                {
                    handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
                    delete wpCreature;
                    return false;
                }

                // set "wpguid" column to the visual waypoint
                WorldDatabase.PExecute("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);

                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
                wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
                map->Add(wpCreature);

                if (target)
                {
                    wpCreature->SetDisplayId(target->GetDisplayId());
                    wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
                    wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point);
                }
            }
            while (result->NextRow());

            handler->SendSysMessage("|cff00ff00Showing the current creature's path.|r");
            return true;
        }

        if (show == "first")
        {
            handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid);

            QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z FROM waypoint_data WHERE point='1' AND id = '%u'", pathid);
            if (!result)
            {
                handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
                handler->SetSentErrorMessage(true);
                return false;
            }

            Field* fields = result->Fetch();
            float x         = fields[0].GetFloat();
            float y         = fields[1].GetFloat();
            float z         = fields[2].GetFloat();
            uint32 id = VISUAL_WAYPOINT;

            Player* chr = handler->GetSession()->GetPlayer();
            float o = chr->GetOrientation();
            Map* map = chr->GetMap();

            Creature* creature = new Creature;
            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
            {
                handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
                delete creature;
                return false;
            }

            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
            creature->LoadFromDB(creature->GetDBTableGUIDLow(), map);
            map->Add(creature);

            if (target)
            {
                creature->SetDisplayId(target->GetDisplayId());
                creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
            }

            return true;
        }

        if (show == "last")
        {
            handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid);

            QueryResult result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'", pathid);
            if (result)
                Maxpoint = (*result)[0].GetUInt32();
            else
                Maxpoint = 0;

            result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z FROM waypoint_data WHERE point ='%u' AND id = '%u'", Maxpoint, pathid);
            if (!result)
            {
                handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid);
                handler->SetSentErrorMessage(true);
                return false;
            }
            Field* fields = result->Fetch();
            float x         = fields[0].GetFloat();
            float y         = fields[1].GetFloat();
            float z         = fields[2].GetFloat();
            uint32 id = VISUAL_WAYPOINT;

            Player* chr = handler->GetSession()->GetPlayer();
            float o = chr->GetOrientation();
            Map* map = chr->GetMap();

            Creature* creature = new Creature;
            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
            {
                handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
                delete creature;
                return false;
            }

            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
            creature->LoadFromDB(creature->GetDBTableGUIDLow(), map);
            map->Add(creature);

            if (target)
            {
                creature->SetDisplayId(target->GetDisplayId());
                creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
            }

            return true;
        }

        if (show == "off")
        {
            QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1);
            if (!result)
            {
                handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
                handler->SetSentErrorMessage(true);
                return false;
            }
            bool hasError = false;
            do
            {
                Field* fields = result->Fetch();
                uint32 guid = fields[0].GetUInt32();
                Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
                if (!creature)
                {
                    handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
                    hasError = true;
                    WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", guid);
                }
                else
                {
                    creature->CombatStop();
                    creature->DeleteFromDB();
                    creature->AddObjectToRemoveList();
                }
            }
            while (result->NextRow());
            // set "wpguid" column to "empty" - no visual waypoint spawned
            WorldDatabase.PExecute("UPDATE waypoint_data SET wpguid = '0'");
            //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");

            if (hasError)
            {
                handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
                handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
                handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
            }

            handler->SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
            return true;
        }

        handler->PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r");
        return true;
    }
Пример #22
0
void subtract(const Map& m1, const Map& m2, Map& result)
{
      // Guard against the case that result is an alias for m1 or m2
      // (i.e., that result is a reference to the same map that m1 or m2
      // refers to) by building the answer in a local variable res.  When
      // done, swap res with result; the old value of result (now in res) will
      // be destroyed when res is destroyed.

    if (m1.size() <= m2.size())
    {
          // If m1 is smaller, if an item in m1 should be in the result because
          // its key is not in m2, add it

        Map res;
        for (int n = 0; n < m1.size(); n++)
        {
            KeyType k;
            ValueType v;
            m1.get(n, k, v);
            if (!m2.contains(k))
                res.insert(k, v);
        }
        result.swap(res);
    }
    else
    {
          // If m1 is larger, copy it to the result and remove from result
          // keys that are in m2

        Map res(m1);
        for (int n = 0; n < m2.size(); n++)
        {
            KeyType k;
            ValueType v;
            m2.get(n, k, v);
            res.erase(k);
        }
        result.swap(res);
    }
}
Пример #23
0
void SurfaceItem::initialize(const Map &map, QObject *parent)
{
    QByteArray vsrc =
        "attribute highp vec4 vertexAttr;\n"
        "attribute highp vec2 texCoordAttr;\n"
        "uniform mediump mat4 matrix;\n"
        "varying highp vec2 texCoord;\n"
        "varying mediump vec3 p;\n"
        "void main(void)\n"
        "{\n"
        "    texCoord = texCoordAttr;\n"
        "    p = vertexAttr.xyz;\n"
        "    gl_Position = matrix * vertexAttr;\n"
        "}\n";

    QByteArray fsrc =
        useSimpleShading() ?
        "uniform sampler2D texture;\n"
        "varying highp vec2 texCoord;\n"
        "uniform lowp float focusColor;\n"
        "void main(void)\n"
        "{\n"
        "    lowp vec4 tex = texture2D(texture, texCoord);\n"
        "    gl_FragColor = tex * 0.9 * focusColor * tex.a;\n"
        "}\n"
        :
        "uniform sampler2D texture;\n"
        "uniform highp vec2 pixelSize;\n"
        "uniform lowp vec3 normal;\n"
        "varying highp vec2 texCoord;\n"
        "varying highp vec3 p;\n"
        "uniform int numLights;\n"
        "uniform highp vec3 lights[NUM_LIGHTS];\n"
        "uniform highp vec3 eye;\n"
        "uniform lowp float focusColor;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 tex = texture2D(texture, texCoord);\n"
        "    highp vec2 dt = abs(texCoord - vec2(0.5));\n"
        "    highp vec3 toEyeN = normalize(eye - p);\n"
        "    highp vec4 result = tex * 0.9;\n" // light source
        "    for (int i = 0; i < NUM_LIGHTS; ++i) {\n"
        "        highp vec3 toLight = lights[i] - p;\n"
        "        highp vec3 toLightN = normalize(toLight);\n"
        "        highp float normalDotLight = dot(toLightN, normal);\n"
        "        highp float lightDistance = length(toLight);\n"
        "        highp float reflectionDotView = max(0.0, dot(normalize(((2.0 * normal) * normalDotLight) - toLightN), toEyeN));\n"
        "        highp vec3 specular = 0.5 * vec3(0.75 * pow(reflectionDotView, 8.0) / max(1.5, 0.8 * lightDistance));\n"
        "        if (i < numLights)\n"
        "            result += vec4(specular, 1.0);\n"
        "    }\n"
        "    highp vec4 blend = mix(vec4(0.0), result * tex.a, (1.0 - smoothstep(0.5 - pixelSize.x, 0.5, dt.x)) * (1.0 - smoothstep(0.5 - pixelSize.y, 0.5, dt.y)));\n"
        "    gl_FragColor = mix(min(blend, vec4(1.0)) * focusColor, tex, focusColor);\n"
        "}\n";

    fsrc.replace("NUM_LIGHTS", QByteArray::number(map.maxLights()));

    m_program = generateShaderProgram(parent, vsrc, fsrc);

    m_vertexAttr = m_program->attributeLocation("vertexAttr");
    m_texCoordAttr = m_program->attributeLocation("texCoordAttr");
    m_matrixUniform = m_program->uniformLocation("matrix");
    m_focusColorUniform = m_program->uniformLocation("focusColor");
    m_pixelSizeUniform = m_program->uniformLocation("pixelSize");
    m_eyeUniform = m_program->uniformLocation("eye");
    m_normalUniform = m_program->uniformLocation("normal");
    m_lightsUniform = m_program->uniformLocation("lights");
    m_numLightsUniform = m_program->uniformLocation("numLights");
}
Пример #24
0
    bool dump_suspended_threads(std::size_t num_thread,
        Map& tm, boost::int64_t& idle_loop_count, bool running)
    {
#if !HPX_THREAD_MINIMAL_DEADLOCK_DETECTION
        (void)tm;
        (void)idle_loop_count;
        (void)running;
        return false;
#else
        if (HPX_LIKELY(idle_loop_count++ < HPX_IDLE_LOOP_COUNT_MAX))
            return false;

        // reset idle loop count
        idle_loop_count = 0;

        bool result = false;
        bool collect_suspended = true;

        bool logged_headline = false;
        typename Map::const_iterator end = tm.end();
        for (typename Map::const_iterator it = tm.begin(); it != end; ++it)
        {
            threads::thread_data const* thrd = (*it).second;
            threads::thread_state state = thrd->get_state();
            threads::thread_state marked_state = thrd->get_marked_state();

            if (state != marked_state) {
                // log each thread only once
                if (!logged_headline) {
                    if (running) {
                        LTM_(error)
                            << "Listing suspended threads while queue ("
                            << num_thread << ") is empty:";
                    }
                    else {
                        LHPX_CONSOLE_(hpx::util::logging::level::error)
                            << "  [TM] Listing suspended threads while queue ("
                            << num_thread << ") is empty:\n";
                    }
                    logged_headline = true;
                }

                if (running) {
                    LTM_(error) << "queue(" << num_thread << "): "
                                << get_thread_state_name(state)
                                << "(" << std::hex << std::setw(8)
                                    << std::setfill('0') << (*it).first
                                << "." << std::hex << std::setw(2)
                                    << std::setfill('0') << thrd->get_thread_phase()
                                << "/" << std::hex << std::setw(8)
                                    << std::setfill('0') << thrd->get_component_id()
                                << ")"
#if HPX_THREAD_MAINTAIN_PARENT_REFERENCE
                                << " P" << std::hex << std::setw(8)
                                    << std::setfill('0') << thrd->get_parent_thread_id()
#endif
                                << ": " << thrd->get_description()
                                << ": " << thrd->get_lco_description();
                }
                else {
                    LHPX_CONSOLE_(hpx::util::logging::level::error) << "  [TM] "
                                << "queue(" << num_thread << "): "
                                << get_thread_state_name(state)
                                << "(" << std::hex << std::setw(8)
                                    << std::setfill('0') << (*it).first
                                << "." << std::hex << std::setw(2)
                                    << std::setfill('0') << thrd->get_thread_phase()
                                << "/" << std::hex << std::setw(8)
                                    << std::setfill('0') << thrd->get_component_id()
                                << ")"
#if HPX_THREAD_MAINTAIN_PARENT_REFERENCE
                                << " P" << std::hex << std::setw(8)
                                    << std::setfill('0') << thrd->get_parent_thread_id()
#endif
                                << ": " << thrd->get_description()
                                << ": " << thrd->get_lco_description() << "\n";
                }
                thrd->set_marked_state(state);

                // result should be true if we found only suspended threads
                if (collect_suspended) {
                    switch(state.get_state()) {
                    case threads::suspended:
                        result = true;    // at least one is suspended
                        break;

                    case threads::pending:
                    case threads::active:
                        result = false;   // one is active, no deadlock (yet)
                        collect_suspended = false;
                        break;

                    default:
                        // If the thread is terminated we don't care too much
                        // anymore.
                        break;
                    }
                }
            }
        }
        return result;
#endif
    }
Пример #25
0
void SpawnerMgr::load(const string& root_dir, const string& index_fn)
{
	AutoLock lock(_lock);
	if (_inited)
		return;

	_root_dir = root_dir;
	_index_fn = index_fn;

	ifstream file(index_fn.c_str());

	if (!file.good())
	{
		LogError(LN, "Could not open spaners conf : %s", index_fn.c_str());
		return;
	}

	_inited = true;

	string buf;
	while (getline(file, buf))
	{
		if (buf.empty())
			continue; // empty line.
		int i = 0;
		
		while ((buf[i] == ' ' || buf[i] == '\t')&& i < buf.size())
		{
			++i;
		}

		if (i == buf.size())
			continue; // only has space.

		if (buf[i] == '#')
			continue; //commented.

		LogDebug(LN, "Processing %s", buf.c_str());
		LogDebug(LN, "start from : %d", i);
		if (buf[i] == '[')
		{
			SMF_Node node;
			int j = buf.find(']', i);
			if (j == buf.npos)
			{
				LogDebug(LN, "Can not found ]");
				continue;
			}

			node._index = conversion_cast<unsigned int>(buf.substr(i + 1, j));
			if (read_node(file, node))
			{
				// load spawner.
				int id = 0 - node._index;
				if(_smf_nodes.find(id) == _smf_nodes.end())
				{
					Spawner* s = new Spawner(id);
					string path = root_dir + "/";
					path += node._file_name;
					s->load(path);
					// TODO:
					_spawners.push_back(s);
					_smf_nodes.insert(make_pair<int, SMF_Node>(id, node));
				}
				else
				{
					//TODO:
				}
			}
		}
		else
		{
			LogError(LN, "Incorrect formate found!!");
		}
	}
	Updater* updater = WorldMgr::get_singleton().get_updater();
	MapMgr* map_mgr = MapMgr::get_instance();
	for (std::list<Spawner*>::iterator ptr = _spawners.begin(); ptr != _spawners.end(); ++ptr)
	{
		Map* map = map_mgr->get_map((*ptr)->get_spawn_info()._map);
		if (!map)
			continue;
		map->add_unit(*ptr);
		updater->add(*ptr);
	}
	LogSuccess(LN, "Loaded spawner conf successful, count : %u", _smf_nodes.size());
}
Пример #26
0
void WorldSession::HandleMoveWorldportAckOpcode()
{
    // ignore unexpected far teleports
    if (!GetPlayer()->IsBeingTeleportedFar())
        return;

    // get the teleport destination
    WorldLocation &loc = GetPlayer()->GetTeleportDest();

    // possible errors in the coordinate validity check
    if (!MapManager::IsValidMapCoord(loc))
    {
        LogoutPlayer(false);
        return;
    }

    // get the destination map entry, not the current one, this will fix homebind and reset greeting
    MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
    InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.GetMapId());

    // reset instance validity, except if going to an instance inside an instance
    if (GetPlayer()->m_InstanceValid == false && !mInstance)
        GetPlayer()->m_InstanceValid = true;

    GetPlayer()->SetSemaphoreTeleportFar(false);

    Map * oldMap = GetPlayer()->GetMap();
    ASSERT(oldMap);
    if (GetPlayer()->IsInWorld())
    {
        sLog.outCrash("Player is still in world when teleported from map %u! to new map %u", oldMap->GetId(), loc.GetMapId());
        oldMap->Remove(GetPlayer(), false);
    }

    // relocate the player to the teleport destination
    Map * newMap = sMapMgr.CreateMap(loc.GetMapId(), GetPlayer(), 0);
    // the CanEnter checks are done in TeleporTo but conditions may change
    // while the player is in transit, for example the map may get full
    if (!newMap || !newMap->CanEnter(GetPlayer()))
    {
        sLog.outError("Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow());
        GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
        return;
    }
    else
        GetPlayer()->Relocate(&loc);

    GetPlayer()->ResetMap();
    GetPlayer()->SetMap(newMap);

    GetPlayer()->SendInitialPacketsBeforeAddToMap();
    if (!GetPlayer()->GetMap()->Add(GetPlayer()))
    {
        sLog.outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.GetMapId());
        GetPlayer()->ResetMap();
        GetPlayer()->SetMap(oldMap);
        GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
        return;
    }

    // battleground state prepare (in case join to BG), at relogin/tele player not invited
    // only add to bg group and object, if the player was invited (else he entered through command)
    if (_player->InBattleGround())
    {
        // cleanup setting if outdated
        if (!mEntry->IsBattleGroundOrArena())
        {
            // We're not in BG
            _player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE);
            // reset destination bg team
            _player->SetBGTeam(0);
        }
        // join to bg case
        else if (BattleGround *bg = _player->GetBattleGround())
        {
            if (_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
                bg->AddPlayer(_player);
        }
    }

    GetPlayer()->SendInitialPacketsAfterAddToMap();

    // flight fast teleport case
    if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
    {
        if (!_player->InBattleGround())
        {
            // short preparations to continue flight
            FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
            flight->Initialize(*GetPlayer());
            return;
        }

        // battleground state prepare, stop flight
        GetPlayer()->GetMotionMaster()->MovementExpired();
        GetPlayer()->CleanupAfterTaxiFlight();
    }

    // resurrect character at enter into instance where his corpse exist after add to map
    Corpse *corpse = GetPlayer()->GetCorpse();
    if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId())
    {
        if (mEntry->IsDungeon())
        {
            GetPlayer()->ResurrectPlayer(0.5f,false);
            GetPlayer()->SpawnCorpseBones();
        }
    }

    bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattleGroundOrArena();
    if (mInstance)
    {
        Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
        if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID,diff))
        {
            if (mapDiff->resetTime)
            {
                if (uint32 timeReset = sInstanceSaveManager.GetResetTimeFor(mEntry->MapID,diff))
                {
                    uint32 timeleft = timeReset - time(NULL);
                    GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft);
                }
            }
        }
        allowMount = mInstance->allowMount;
    }

    // mount allow check
    if (!allowMount)
        _player->RemoveAurasByType(SPELL_AURA_MOUNTED);

    // update zone immediately, otherwise leave channel will cause crash in mtmap
    uint32 newzone, newarea;
    GetPlayer()->GetZoneAndAreaId(newzone, newarea);
    GetPlayer()->UpdateZone(newzone, newarea);

    // honorless target
    if (GetPlayer()->pvpInfo.inHostileArea)
        GetPlayer()->CastSpell(GetPlayer(), 2479, true);
    // in friendly area
    else if (GetPlayer()->IsPvP() && !GetPlayer()->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_IN_PVP))
        GetPlayer()->UpdatePvP(false, false);

    // resummon pet
    GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();

    //lets process all delayed operations on successful teleport
    GetPlayer()->ProcessDelayedOperations();
}
Пример #27
0
        void WaypointReached(uint32 i)
        {
            if (!pInstance)
                return;

            switch (i)
            {
                case 8:
                    SetRun(false);
                    me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 9:
                    DoScriptText(SAY_TH_ARMORY, me);
                    me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
                    me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
                    break;
                case 10:
                    me->SetDisplayId(THRALL_MODEL_EQUIPPED);
                    break;
                case 11:
                    SetRun();
                    break;
                case 15:
                    me->SummonCreature(MOB_ENTRY_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 21:
                    me->SummonCreature(MOB_ENTRY_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 25:
                    me->SummonCreature(MOB_ENTRY_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 29:
                    DoScriptText(SAY_TH_SKARLOC_MEET, me);
                    me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
                    //temporary, skarloc should rather be triggered to walk up to thrall
                    break;
                case 30:
                    SetEscortPaused(true);
                    me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    SetRun(false);
                    break;
                case 31:
                    DoScriptText(SAY_TH_MOUNTS_UP, me);
                    DoMount();
                    SetRun();
                    break;
                case 37:
                    //possibly regular patrollers? If so, remove this and let database handle them
                    me->SummonCreature(MOB_ENTRY_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 59:
                    me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10000);
                    DoUnmount();
                    HadMount = false;
                    SetRun(false);
                    break;
                case 60:
                    me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
                    //make horsie run off
                    SetEscortPaused(true);
                    me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    pInstance->SetData(TYPE_THRALL_PART2, DONE);
                    SetRun();
                    break;
                case 64:
                    SetRun(false);
                    break;
                case 68:
                    me->SummonCreature(MOB_ENTRY_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 71:
                    SetRun();
                    break;
                case 81:
                    SetRun(false);
                    break;
                case 83:
                    me->SummonCreature(MOB_ENTRY_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(MOB_ENTRY_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    break;
                case 84:
                    DoScriptText(SAY_TH_CHURCH_END, me);
                    SetRun();
                    break;
                case 91:
                    me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
                    SetRun(false);
                    break;
                case 93:
                    me->SummonCreature(MOB_ENTRY_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 94:
                    if (uint64 TarethaGUID = pInstance->GetData64(DATA_TARETHA))
                    {
                        if (Unit* Taretha = Unit::GetUnit((*me), TarethaGUID))
                            DoScriptText(SAY_TA_ESCAPED, Taretha, me);
                    }
                    break;
                case 95:
                    DoScriptText(SAY_TH_MEET_TARETHA, me);
                    pInstance->SetData(TYPE_THRALL_PART3, DONE);
                    SetEscortPaused(true);
                    break;
                case 96:
                    DoScriptText(SAY_TH_EPOCH_WONDER, me);
                    break;
                case 97:
                    DoScriptText(SAY_TH_EPOCH_KILL_TARETHA, me);
                    SetRun();
                    break;
                case 98:
                    //trigger epoch Yell("Thrall! Come outside and face your fate! ....")
                    //from here, thrall should not never be allowed to move to point 106 which he currently does.
                    break;

                case 106:
                    {
                        //trigger taretha to run down outside
                        if (Creature* Taretha = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TARETHA)))
                        {
                            if (Player* player = GetPlayerForEscort())
                                CAST_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID());
                        }

                        //kill credit Creature for quest
                        Map* pMap = me->GetMap();
                        Map::PlayerList const& players = pMap->GetPlayers();
                        if (!players.isEmpty() && pMap->IsDungeon())
                        {
                            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                            {
                                if (Player* player = itr->getSource())
                                    player->KilledMonsterCredit(20156, 0);
                            }
                        }

                        //alot will happen here, thrall and taretha talk, erozion appear at spot to explain
                        me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 120000);
                    }
                    break;
                case 108:
                    //last waypoint, just set Thrall invisible, respawn is turned off
                    me->SetVisible(false);
                    break;
            }
        }
Пример #28
0
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
		f32 pos_max_d, const aabb3f &box_0,
		f32 stepheight, f32 dtime,
		v3f &pos_f, v3f &speed_f,
		v3f &accel_f,ActiveObject* self,
		bool collideWithObjects)
{
	Map *map = &env->getMap();
	//TimeTaker tt("collisionMoveSimple");
    ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG);

	collisionMoveResult result;

	/*
		Calculate new velocity
	*/
	if( dtime > 0.5 ) {
		infostream<<"collisionMoveSimple: WARNING: maximum step interval exceeded, lost movement details!"<<std::endl;
		dtime = 0.5;
	}
	speed_f += accel_f * dtime;

	// If there is no speed, there are no collisions
	if(speed_f.getLength() == 0)
		return result;

	// Limit speed for avoiding hangs
	speed_f.Y=rangelim(speed_f.Y,-5000,5000);
	speed_f.X=rangelim(speed_f.X,-5000,5000);
	speed_f.Z=rangelim(speed_f.Z,-5000,5000);

	/*
		Collect node boxes in movement range
	*/
	std::vector<aabb3f> cboxes;
	std::vector<bool> is_unloaded;
	std::vector<bool> is_step_up;
	std::vector<bool> is_object;
	std::vector<int> bouncy_values;
	std::vector<v3s16> node_positions;
	{
	//TimeTaker tt2("collisionMoveSimple collect boxes");
    ScopeProfiler sp(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG);

	v3s16 oldpos_i = floatToInt(pos_f, BS);
	v3s16 newpos_i = floatToInt(pos_f + speed_f * dtime, BS);
	s16 min_x = MYMIN(oldpos_i.X, newpos_i.X) + (box_0.MinEdge.X / BS) - 1;
	s16 min_y = MYMIN(oldpos_i.Y, newpos_i.Y) + (box_0.MinEdge.Y / BS) - 1;
	s16 min_z = MYMIN(oldpos_i.Z, newpos_i.Z) + (box_0.MinEdge.Z / BS) - 1;
	s16 max_x = MYMAX(oldpos_i.X, newpos_i.X) + (box_0.MaxEdge.X / BS) + 1;
	s16 max_y = MYMAX(oldpos_i.Y, newpos_i.Y) + (box_0.MaxEdge.Y / BS) + 1;
	s16 max_z = MYMAX(oldpos_i.Z, newpos_i.Z) + (box_0.MaxEdge.Z / BS) + 1;

	for(s16 x = min_x; x <= max_x; x++)
	for(s16 y = min_y; y <= max_y; y++)
	for(s16 z = min_z; z <= max_z; z++)
	{
		v3s16 p(x,y,z);

		bool is_position_valid;
		MapNode n = map->getNodeNoEx(p, &is_position_valid);

		if (is_position_valid) {
			// Object collides into walkable nodes

			const ContentFeatures &f = gamedef->getNodeDefManager()->get(n);
			if(f.walkable == false)
				continue;
			int n_bouncy_value = itemgroup_get(f.groups, "bouncy");

			std::vector<aabb3f> nodeboxes = n.getCollisionBoxes(gamedef->ndef());
			for(std::vector<aabb3f>::iterator
					i = nodeboxes.begin();
					i != nodeboxes.end(); i++)
			{
				aabb3f box = *i;
				box.MinEdge += v3f(x, y, z)*BS;
				box.MaxEdge += v3f(x, y, z)*BS;
				cboxes.push_back(box);
				is_unloaded.push_back(false);
				is_step_up.push_back(false);
				bouncy_values.push_back(n_bouncy_value);
				node_positions.push_back(p);
				is_object.push_back(false);
			}
		}
		else {
			// Collide with unloaded nodes
			aabb3f box = getNodeBox(p, BS);
			cboxes.push_back(box);
			is_unloaded.push_back(true);
			is_step_up.push_back(false);
			bouncy_values.push_back(0);
			node_positions.push_back(p);
			is_object.push_back(false);
		}
	}
	} // tt2

	if(collideWithObjects)
	{
		ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
		//TimeTaker tt3("collisionMoveSimple collect object boxes");

		/* add object boxes to cboxes */


		std::vector<ActiveObject*> objects;
#ifndef SERVER
		ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
		if (c_env != 0) {
			f32 distance = speed_f.getLength();
			std::vector<DistanceSortedActiveObject> clientobjects;
			c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
			for (size_t i=0; i < clientobjects.size(); i++) {
				if ((self == 0) || (self != clientobjects[i].obj)) {
					objects.push_back((ActiveObject*)clientobjects[i].obj);
				}
			}
		}
		else
#endif
		{
			ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
			if (s_env != 0) {
				f32 distance = speed_f.getLength();
				std::vector<u16> s_objects;
				s_env->getObjectsInsideRadius(s_objects, pos_f, distance * 1.5);
				for (std::vector<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++) {
					ServerActiveObject *current = s_env->getActiveObject(*iter);
					if ((self == 0) || (self != current)) {
						objects.push_back((ActiveObject*)current);
					}
				}
			}
		}

		for (std::vector<ActiveObject*>::const_iterator iter = objects.begin();
				iter != objects.end(); ++iter) {
			ActiveObject *object = *iter;

			if (object != NULL) {
				aabb3f object_collisionbox;
				if (object->getCollisionBox(&object_collisionbox) &&
						object->collideWithObjects()) {
					cboxes.push_back(object_collisionbox);
					is_unloaded.push_back(false);
					is_step_up.push_back(false);
					bouncy_values.push_back(0);
					node_positions.push_back(v3s16(0,0,0));
					is_object.push_back(true);
				}
			}
		}
	} //tt3

	assert(cboxes.size() == is_unloaded.size());    // post-condition
	assert(cboxes.size() == is_step_up.size());     // post-condition
	assert(cboxes.size() == bouncy_values.size());  // post-condition
	assert(cboxes.size() == node_positions.size()); // post-condition
	assert(cboxes.size() == is_object.size());      // post-condition

	/*
		Collision detection
	*/

	/*
		Collision uncertainty radius
		Make it a bit larger than the maximum distance of movement
	*/
	f32 d = pos_max_d * 1.1;
	// A fairly large value in here makes moving smoother
	//f32 d = 0.15*BS;

	// This should always apply, otherwise there are glitches
	assert(d > pos_max_d);	// invariant

	int loopcount = 0;

	while(dtime > BS*1e-10)
	{
		//TimeTaker tt3("collisionMoveSimple dtime loop");
        ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);

		// Avoid infinite loop
		loopcount++;
		if(loopcount >= 100)
		{
			infostream<<"collisionMoveSimple: WARNING: Loop count exceeded, aborting to avoid infiniite loop"<<std::endl;
			dtime = 0;
			break;
		}

		aabb3f movingbox = box_0;
		movingbox.MinEdge += pos_f;
		movingbox.MaxEdge += pos_f;

		int nearest_collided = -1;
		f32 nearest_dtime = dtime;
		u32 nearest_boxindex = -1;

		/*
			Go through every nodebox, find nearest collision
		*/
		for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
		{
			// Ignore if already stepped up this nodebox.
			if(is_step_up[boxindex])
				continue;

			// Find nearest collision of the two boxes (raytracing-like)
			f32 dtime_tmp;
			int collided = axisAlignedCollision(
					cboxes[boxindex], movingbox, speed_f, d, dtime_tmp);

			if(collided == -1 || dtime_tmp >= nearest_dtime)
				continue;

			nearest_dtime = dtime_tmp;
			nearest_collided = collided;
			nearest_boxindex = boxindex;
		}

		if(nearest_collided == -1)
		{
			// No collision with any collision box.
			pos_f += speed_f * dtime;
			dtime = 0;  // Set to 0 to avoid "infinite" loop due to small FP numbers
		}
		else
		{
			// Otherwise, a collision occurred.

			const aabb3f& cbox = cboxes[nearest_boxindex];

			// Check for stairs.
			bool step_up = (nearest_collided != 1) && // must not be Y direction
					(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
					(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
					(!wouldCollideWithCeiling(cboxes, movingbox,
							cbox.MaxEdge.Y - movingbox.MinEdge.Y,
							d));

			// Get bounce multiplier
			bool bouncy = (bouncy_values[nearest_boxindex] >= 1);
			float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0;

			// Move to the point of collision and reduce dtime by nearest_dtime
			if(nearest_dtime < 0)
			{
				// Handle negative nearest_dtime (can be caused by the d allowance)
				if(!step_up)
				{
					if(nearest_collided == 0)
						pos_f.X += speed_f.X * nearest_dtime;
					if(nearest_collided == 1)
						pos_f.Y += speed_f.Y * nearest_dtime;
					if(nearest_collided == 2)
						pos_f.Z += speed_f.Z * nearest_dtime;
				}
			}
			else
			{
				pos_f += speed_f * nearest_dtime;
				dtime -= nearest_dtime;
			}
			
			bool is_collision = true;
			if(is_unloaded[nearest_boxindex])
				is_collision = false;

			CollisionInfo info;
			if (is_object[nearest_boxindex]) {
				info.type = COLLISION_OBJECT;
			}
			else {
				info.type = COLLISION_NODE;
			}
			info.node_p = node_positions[nearest_boxindex];
			info.bouncy = bouncy;
			info.old_speed = speed_f;

			// Set the speed component that caused the collision to zero
			if(step_up)
			{
				// Special case: Handle stairs
				is_step_up[nearest_boxindex] = true;
				is_collision = false;
			}
			else if(nearest_collided == 0) // X
			{
				if(fabs(speed_f.X) > BS*3)
					speed_f.X *= bounce;
				else
					speed_f.X = 0;
				result.collides = true;
				result.collides_xz = true;
			}
			else if(nearest_collided == 1) // Y
			{
				if(fabs(speed_f.Y) > BS*3)
					speed_f.Y *= bounce;
				else
					speed_f.Y = 0;
				result.collides = true;
			}
			else if(nearest_collided == 2) // Z
			{
				if(fabs(speed_f.Z) > BS*3)
					speed_f.Z *= bounce;
				else
					speed_f.Z = 0;
				result.collides = true;
				result.collides_xz = true;
			}

			info.new_speed = speed_f;
			if(info.new_speed.getDistanceFrom(info.old_speed) < 0.1*BS)
				is_collision = false;

			if(is_collision){
				result.collisions.push_back(info);
			}
		}
	}

	/*
		Final touches: Check if standing on ground, step up stairs.
	*/
	aabb3f box = box_0;
	box.MinEdge += pos_f;
	box.MaxEdge += pos_f;
	for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
	{
		const aabb3f& cbox = cboxes[boxindex];

		/*
			See if the object is touching ground.

			Object touches ground if object's minimum Y is near node's
			maximum Y and object's X-Z-area overlaps with the node's
			X-Z-area.

			Use 0.15*BS so that it is easier to get on a node.
		*/
		if(
				cbox.MaxEdge.X-d > box.MinEdge.X &&
				cbox.MinEdge.X+d < box.MaxEdge.X &&
				cbox.MaxEdge.Z-d > box.MinEdge.Z &&
				cbox.MinEdge.Z+d < box.MaxEdge.Z
		){
			if(is_step_up[boxindex])
			{
				pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
				box = box_0;
				box.MinEdge += pos_f;
				box.MaxEdge += pos_f;
			}
			if(fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS)
			{
				result.touching_ground = true;
				if(is_unloaded[boxindex])
					result.standing_on_unloaded = true;
			}
		}
	}

	return result;
}
Пример #29
0
PropertyStream::Set::Set (std::string const& key, Map& map)
    : m_stream (map.stream())
{
    m_stream.array_begin (key);
}
Пример #30
0
	void clear() {

		props.clear();
		values.clear();
	}