Exemplo n.º 1
0
///// returns a new or existing Instance
///// in case of battlegrounds it will only return an existing map, those maps are created by bg-system
Map* MapManager::CreateInstance(uint32 id, Player * player)
{
    Map* map = NULL;
    Map * pNewMap = NULL;
    uint32 NewInstanceId = 0;                                   // instanceId of the resulting map
    const MapEntry* entry = sMapStore.LookupEntry(id);

    if(entry->IsBattleGround())
    {
        // find existing bg map for player
        NewInstanceId = player->GetBattleGroundId();
        MANGOS_ASSERT(NewInstanceId);
        map = FindMap(id, NewInstanceId);
        MANGOS_ASSERT(map);
    }
    else if (DungeonPersistentState* pSave = player->GetBoundInstanceSaveForSelfOrGroup(id))
    {
        // solo/perm/group
        NewInstanceId = pSave->GetInstanceId();
        map = FindMap(id, NewInstanceId);
        // it is possible that the save exists but the map doesn't
        if (!map)
            pNewMap = CreateDungeonMap(id, NewInstanceId, pSave);
    }
    else
    {
        // if no instanceId via group members or instance saves is found
        // the instance will be created for the first time
        NewInstanceId = GenerateInstanceId();

        pNewMap = CreateDungeonMap(id, NewInstanceId);
    }

    //add a new map object into the registry
    if(pNewMap)
    {
        i_maps[MapID(id, NewInstanceId)] = pNewMap;
        map = pNewMap;
    }

    return map;
}
Exemplo n.º 2
0
void GameObject::RemoveFromWorld()
{
    ///- Remove the gameobject from the accessor
    if(IsInWorld())
    {
        if(Map *map = FindMap())
            if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
                ((InstanceMap*)map)->GetInstanceData()->OnObjectRemove(this);
        ObjectAccessor::Instance().RemoveObject(this);
        WorldObject::RemoveFromWorld();
    }
}
Exemplo n.º 3
0
		/*!
		 * \brief
		 * Redirects a part request to the map file server if the request is valid.
		 * 
		 * \param connection
		 * The connection the redirect is to be sent to.
		 * 
		 * \param request_info
		 * Pointer to the request information sent to the server by the client.
		 * 
		 * Redirects a part request to the map file server if the request is valid.
		 * 
		 * \remarks
		 * A client error status code is sent to the client if the request is incomplete, or if the map/part was not found.
		 */
		static void ProcessMapPartDownloadReferral(mg_connection* connection,
			std::string map_name,
			std::string part_name)
		{
			const mg_request_info* request_info = mg_get_request_info(connection);

			// remove the extension from the map name
			std::string::size_type extension_offset = std::string::npos;
			if((extension_offset = map_name.find(Cache::K_MAP_FILE_EXTENSION)) != std::string::npos)
				map_name.resize(extension_offset);
			else if((extension_offset = map_name.find(Cache::K_MAP_FILE_EXTENSION_YELO)) != std::string::npos)
				map_name.resize(extension_offset);

			// look for the part in the part definition
			c_map_element* map_element = FindMap(map_name.c_str());

			if(!map_element)
			{
				// the part was not found so respond with the file not found status code
				SendResponse(connection, Enums::_http_status_code_client_error_not_found);
				return;
			}

			if(!map_element->Lock())
			{
				// the part was not found so respond with the file not found status code
				SendResponse(connection, Enums::_http_status_code_client_error_request_timeout);
				return;
			}

			const c_part_element* part_element = FindPart(map_element, part_name.c_str());

			if(part_element)
			{
				// the part element exists, so respond with a redirect to the part file
				c_http_header response_headers;
				response_headers.AddHeader("Content-Type", "text/html");
				response_headers.AddHeader("Content-Length", "0");
				response_headers.AddHeader("Location", part_element->m_redirect_address.c_str());

				SendResponse(connection, Enums::_http_status_code_redirection_found, &response_headers);
			}
			else
			{
				// the part was not found so respond with the file not found status code
				SendResponse(connection, Enums::_http_status_code_client_error_not_found);
			}

			map_element->Unlock();
		}
Exemplo n.º 4
0
Bool
SDL_NAME(XF86DGAGetVideo)(
    Display *dis,
    int screen,
    char **addr,
    int *width, 
    int *bank, 
    int *ram
){
    /*unsigned long*/ int offset;
    static int beenHere = 0;
    ScrPtr sp;
    MapPtr mp;

    if (!(sp = FindScr(dis, screen))) {
	if (!(sp = AddScr())) {
	    fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
	    exit(-2);
	}
	sp->display = dis;
	sp->screen = screen;
	sp->map = NULL;
    }

    SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram);

    *addr = MapPhysAddress(offset, *bank);
    if (*addr == NULL) {
	fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
		strerror(errno));
	exit(-2);
    }

    if ((mp = FindMap(offset, *bank)))
	sp->map = mp;

    if (!beenHere) {
	beenHere = 1;
	atexit((void(*)(void))XF86cleanup);
	/* one shot XF86cleanup attempts */
	signal(SIGSEGV, XF86cleanup);
#ifdef SIGBUS
	signal(SIGBUS, XF86cleanup);
#endif
	signal(SIGHUP, XF86cleanup);
	signal(SIGFPE, XF86cleanup);  
    }

    return 1;
}
Exemplo n.º 5
0
void Garrison::CancelBuildingConstruction(uint32 garrPlotInstanceId)
{
    WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
    buildingRemoved.GarrTypeID = GARRISON_TYPE_GARRISON;
    buildingRemoved.Result = CheckBuildingRemoval(garrPlotInstanceId);
    if (buildingRemoved.Result == GARRISON_SUCCESS)
    {
        Plot* plot = GetPlot(garrPlotInstanceId);

        buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
        buildingRemoved.GarrBuildingID = plot->BuildingInfo.PacketInfo->GarrBuildingID;

        Map* map = FindMap();
        if (map)
            plot->DeleteGameObject(map);

        plot->ClearBuildingInfo(_owner);
        _owner->SendDirectMessage(buildingRemoved.Write());

        GarrBuildingEntry const* constructing = sGarrBuildingStore.AssertEntry(buildingRemoved.GarrBuildingID);
        // Refund construction/upgrade cost
        _owner->ModifyCurrency(constructing->CostCurrencyID, constructing->CostCurrencyAmount, false, true);
        _owner->ModifyMoney(constructing->CostMoney * GOLD, false);

        if (constructing->Level > 1)
        {
            // Restore previous level building
            uint32 restored = sGarrisonMgr.GetPreviousLevelBuildingId(constructing->Type, constructing->Level);
            ASSERT(restored);

            WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult;
            placeBuildingResult.GarrTypeID = GARRISON_TYPE_GARRISON;
            placeBuildingResult.Result = GARRISON_SUCCESS;
            placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId;
            placeBuildingResult.BuildingInfo.GarrBuildingID = restored;
            placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);
            placeBuildingResult.BuildingInfo.Active = true;

            plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
            _owner->SendDirectMessage(placeBuildingResult.Write());
        }

        if (map)
            if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
                map->AddToMap(go);
    }
    else
        _owner->SendDirectMessage(buildingRemoved.Write());
}
bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) {
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

  const backtrace_map_t* map = FindMap(ptr);
  if (map && map->flags & PROT_READ) {
    *out_value = *reinterpret_cast<uint32_t*>(ptr);
    return true;
  } else {
    BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
    *out_value = static_cast<uint32_t>(-1);
    return false;
  }
}
Exemplo n.º 7
0
void Garrison::PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId)
{
    WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult;
    placeBuildingResult.GarrTypeID = GARRISON_TYPE_GARRISON;
    placeBuildingResult.Result = CheckBuildingPlacement(garrPlotInstanceId, garrBuildingId);
    if (placeBuildingResult.Result == GARRISON_SUCCESS)
    {
        placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId;
        placeBuildingResult.BuildingInfo.GarrBuildingID = garrBuildingId;
        placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);

        Plot* plot = GetPlot(garrPlotInstanceId);
        uint32 oldBuildingId = 0;
        Map* map = FindMap();
        GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId);
        if (map)
            plot->DeleteGameObject(map);

        if (plot->BuildingInfo.PacketInfo)
        {
            oldBuildingId = plot->BuildingInfo.PacketInfo->GarrBuildingID;
            if (sGarrBuildingStore.AssertEntry(oldBuildingId)->Type != building->Type)
                plot->ClearBuildingInfo(_owner);
        }

        plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
        if (map)
            if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
                map->AddToMap(go);

        _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true);
        _owner->ModifyMoney(-building->CostMoney * GOLD, false);

        if (oldBuildingId)
        {
            WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
            buildingRemoved.GarrTypeID = GARRISON_TYPE_GARRISON;
            buildingRemoved.Result = GARRISON_SUCCESS;
            buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
            buildingRemoved.GarrBuildingID = oldBuildingId;
            _owner->SendDirectMessage(buildingRemoved.Write());
        }

        _owner->UpdateCriteria(CRITERIA_TYPE_PLACE_GARRISON_BUILDING, garrBuildingId);
    }

    _owner->SendDirectMessage(placeBuildingResult.Write());
}
Exemplo n.º 8
0
bool CheckForMod(char *theMap)
{
	std::vector<struct WZmaps>::iterator it;
	if (theMap == NULL)
	{
		return false;
	}
	it = std::find_if(WZ_Maps.begin(), WZ_Maps.end(), FindMap(theMap));
	if(it != WZ_Maps.end())
	{
		return it->isMapMod;
	}
	debug(LOG_ERROR, "Couldn't find map %s", theMap);

	return false;
}
Exemplo n.º 9
0
//-----------------------------------------------------------------------------
TBaseItem* TFactoryGameItem::Get(Type type, std::string& name)
{
  TMapStrPtrItem* pMap = FindMap(type);
  TBaseItem* pItem = FindItemInMapByName(name, pMap);
  if(pItem)
    return pItem;
  
  pItem = NewItem(type, name);
  if(mMngSerializer->Load(type, pItem)==false)
  {
    delete pItem;
    return NULL;
  }
  mListItems.push_back(pItem);
  AddItemInMap(pItem, pMap);
  return pItem;
}
Exemplo n.º 10
0
		/*!
		 * \brief
		 * Sends a map part definition to the client if the request is valid.
		 * 
		 * \param connection
		 * The connection the response is to be sent to.
		 * 
		 * \param request_info
		 * Pointer to the request information sent to the server by the client.
		 * 
		 * Sends a map part definition to the client if the request is valid.
		 * 
		 * \remarks
		 * A client error status code is returned to the client if the request is incomplete or if no matching map is found.
		 */
		static void ProcessMapPartDefinitionRequest(mg_connection* connection,
			std::string map_name)
		{
			const mg_request_info* request_info = mg_get_request_info(connection);

			// look for the map definition element
			c_map_element* map_element = FindMap(map_name.c_str());

			if(!map_element)
			{
				// the map wasn't found so respond with the file not found status code
				SendResponse(connection, Enums::_http_status_code_client_error_not_found);
				return;
			}

			// the map was found so respond with its map part definition
			SendMapPartDefinition(connection, map_element);
		}
Exemplo n.º 11
0
void Garrison::ActivateBuilding(uint32 garrPlotInstanceId)
{
    if (Plot* plot = GetPlot(garrPlotInstanceId))
    {
        if (plot->BuildingInfo.CanActivate() && plot->BuildingInfo.PacketInfo && !plot->BuildingInfo.PacketInfo->Active)
        {
            plot->BuildingInfo.PacketInfo->Active = true;
            if (Map* map = FindMap())
            {
                plot->DeleteGameObject(map);
                if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
                    map->AddToMap(go);
            }

            WorldPackets::Garrison::GarrisonBuildingActivated buildingActivated;
            buildingActivated.GarrPlotInstanceID = garrPlotInstanceId;
            _owner->SendDirectMessage(buildingActivated.Write());
        }
    }
}
Exemplo n.º 12
0
Map* MapManager::CreateMap(uint32 id, WorldObject const* obj)
{
    MANGOS_ASSERT(obj);
    //if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
    Guard _guard(*this);

    Map* m = NULL;

    MapEntry const* entry = sMapStore.LookupEntry(id);
    if(!entry)
        return NULL;

    if (entry->Instanceable())
    {
        //create DungeonMap object
        if (obj->GetTypeId() == TYPEID_PLAYER)
            m = CreateInstance(id, (Player*)obj);
        else if (obj->IsInitialized() && obj->GetObjectGuid().IsMOTransport())
            DEBUG_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES,"MapManager::CreateMap %s try create map %u (no instance given), currently not implemented.",obj->IsInitialized() ? obj->GetObjectGuid().GetString().c_str() : "<uninitialized>", id);
        else
            DETAIL_LOG("MapManager::CreateMap %s try create map %u (no instance given), BUG, wrong usage!",obj->IsInitialized() ? obj->GetObjectGuid().GetString().c_str() : "<uninitialized>", id);
    }
    else
    {
        //create regular non-instanceable map
        m = FindMap(id);
        if( m == NULL )
        {
            m = new WorldMap(id, i_gridCleanUpDelay);
            //add map into container
            i_maps[MapID(id)] = m;

            // non-instanceable maps always expected have saved state
            m->CreateInstanceData(true);
        }
    }

    return m;
}
Exemplo n.º 13
0
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
{
    MANGOS_ASSERT(obj);
    //if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
    Guard _guard(*this);

    Map * m = NULL;

    const MapEntry* entry = sMapStore.LookupEntry(id);
    if(!entry)
        return NULL;

    if(entry->Instanceable())
    {
        MANGOS_ASSERT(obj->GetTypeId() == TYPEID_PLAYER);
        //create DungeonMap object
        if(obj->GetTypeId() == TYPEID_PLAYER)
            m = CreateInstance(id, (Player*)obj);
    }
    else
    {
        //create regular non-instanceable map
        m = FindMap(id);
        if( m == NULL )
        {
            m = new WorldMap(id, i_gridCleanUpDelay);
            //add map into container
            i_maps[MapID(id)] = m;

            // non-instanceable maps always expected have saved state
            m->CreateInstanceData(true);
        }
    }

    return m;
}
Exemplo n.º 14
0
//判断是否可以连接
bool CLogic::IsLink(BYTE  chess[CHESSCOUNT_H][CHESSCOUNT_W], CPoint first, CPoint second, CArrayTemplate<CPoint> *v,CPoint *ipoint1,CPoint *ipoint2)
{
	CArrayTemplate<CPoint> f,s;
	CPoint samepoint;
	
	//两个点是否相邻
	if(first.x == second.x && abs(first.y - second.y)==1 ||
		first.y == second.y && abs(first.x - second.x) == 1)
	{
		if(chess[first.y][first.x] == chess[second.y][second.x])
		{
			v->InsertAt(v->GetCount(),first);
			v->InsertAt(v->GetCount(),second);
            return true;
		}
		else
			return false;
	}

//一条直线可否连接
	FindMap(&f,chess,first,WAY_UP,false);
	FindMap(&f,chess,first,WAY_DOWN,false);
	FindMap(&f,chess,first,WAY_LEFT,false);
	FindMap(&f,chess,first,WAY_RIGHT,false);

	FindMap(&s,chess,second,WAY_UP,false);
	FindMap(&s,chess,second,WAY_DOWN,false);
	FindMap(&s,chess,second,WAY_LEFT,false);
	FindMap(&s,chess,second,WAY_RIGHT,false);

	//判断是否有共同的点
	if( AssertHaveSame(&f,&s,&samepoint) )
	{
		//找出路经
		ShortPath(chess,v,first,samepoint,NULL);
		ShortPath(chess,v,samepoint,second,NULL);
		v->InsertAt(v->GetCount(),second);

		//存储交点
		if(first.x == samepoint.x && samepoint.x == second.x || first.y == samepoint.y && samepoint.y == second.y)
			;
		else
		{
			ipoint1->x = samepoint.x;
			ipoint1->y = samepoint.y;
		}
            
		return true;		
	}
	f.RemoveAll();
	s.RemoveAll();

//两条或者三条直线是否可以连接
	FindMap(&f,chess,first,WAY_UP,true);
	FindMap(&f,chess,first,WAY_DOWN,true);
	FindMap(&f,chess,first,WAY_LEFT,true);
	FindMap(&f,chess,first,WAY_RIGHT,true);

	FindMap(&s,chess,second,WAY_UP,false);
	FindMap(&s,chess,second,WAY_DOWN,false);
	FindMap(&s,chess,second,WAY_LEFT,false);
	FindMap(&s,chess,second,WAY_RIGHT,false);

	//判断是否有共同的点
	if( AssertHaveSame(&f,&s,&samepoint) )
	{
		ShortPath(chess,v,first,samepoint,ipoint1);
		
		//存储交点
		ipoint2->x = samepoint.x;
		ipoint2->y = samepoint.y;

		ShortPath(chess,v,samepoint,second,NULL);
		v->InsertAt(v->GetCount(),second);

		return true;
	}
	return false;
	
}
Exemplo n.º 15
0
	// 自动搜索
bool CLogic::FindMap(CArrayTemplate<CPoint> *v, BYTE  chess[CHESSCOUNT_H][CHESSCOUNT_W],CPoint point, int way, bool isFirst)
{
	switch(way)
	{
	case WAY_UP:
		{
			point.y -= 1;
			while(InChess(chess,point.x,point.y))
			{
				if(chess[point.y][point.x]==ERROR_ALL )
				{
					v->InsertAt(v->GetCount(),point);
					if(isFirst)
					{
						FindMap(v,chess,point,WAY_LEFT,false);
						FindMap(v,chess,point,WAY_RIGHT,false);
					}
					point.y-=1;
				}
				else
                    return true;
			}
			break;
		}
	case WAY_DOWN:
		{
			point.y += 1;
			while(InChess(chess,point.x,point.y))
			{
				if(chess[point.y][point.x]==ERROR_ALL )
				{
					v->InsertAt(v->GetCount(),point);
					if(isFirst)
					{
						FindMap(v,chess,point,WAY_LEFT,false);
						FindMap(v,chess,point,WAY_RIGHT,false);
					}
					point.y+=1;
				}
				else
                    return true;
			}
			break;
		}
	case WAY_LEFT:
		{
			point.x -= 1;
			while(InChess(chess,point.x,point.y))
			{
				if(chess[point.y][point.x]==ERROR_ALL )
				{
					v->InsertAt(v->GetCount(),point);
					if(isFirst)
					{
						FindMap(v,chess,point,WAY_UP,false);
						FindMap(v,chess,point,WAY_DOWN,false);
					}
					point.x-=1;
				}
				else
                    return true;
			}
			break;
		}
	case WAY_RIGHT:
		{
			point.x += 1;
			while(InChess(chess,point.x,point.y))
			{
				if(chess[point.y][point.x]==ERROR_ALL )
				{
					v->InsertAt(v->GetCount(),point);
					if(isFirst)
					{
						FindMap(v,chess,point,WAY_UP,false);
						FindMap(v,chess,point,WAY_DOWN,false);
					}
					point.x+=1;
				}
				else
                    return true;
			}
			break;
		}
	}
	
	return true;
}
Exemplo n.º 16
0
bool UnwindPtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
  if (ucontext) {
    BACK_LOGW("Unwinding from a specified context not supported yet.");
    return false;
  }

  addr_space_ = unw_create_addr_space(&_UPT_accessors, 0);
  if (!addr_space_) {
    BACK_LOGW("unw_create_addr_space failed.");
    return false;
  }

  UnwindMap* map = static_cast<UnwindMap*>(GetMap());
  if (NULL == map) {
    BACK_LOGW("GetMap before unwinding failed.");
    return false;
  }
  unw_map_set(addr_space_, map->GetMapCursor());

  upt_info_ = reinterpret_cast<struct UPT_info*>(_UPT_create(Tid()));
  if (!upt_info_) {
    BACK_LOGW("Failed to create upt info.");
    return false;
  }

  unw_cursor_t cursor;
  if(num_ignore_frames==0xdeaddead)
  	{
  		cursor.opaque[0]=0xdeaddead; //add for tell libunwind to unwind for kernel unwind userspace backtrace,lhd
  		BACK_LOGW(" K2U_bt call into UnwindPtrace::Unwind.");
		num_ignore_frames=0;
  	}
  int ret = unw_init_remote(&cursor, addr_space_, upt_info_);
  if (ret < 0) {
    BACK_LOGW("unw_init_remote failed %d", ret);
    return false;
  }

  std::vector<backtrace_frame_data_t>* frames = GetFrames();
  frames->reserve(MAX_BACKTRACE_FRAMES);
  size_t num_frames = 0;
  do {
    unw_word_t pc;
    ret = unw_get_reg(&cursor, UNW_REG_IP, &pc);
    if (ret < 0) {
      BACK_LOGW("Failed to read IP %d", ret);
      break;
    }
    unw_word_t sp;
    ret = unw_get_reg(&cursor, UNW_REG_SP, &sp);
    if (ret < 0) {
      BACK_LOGW("Failed to read SP %d", ret);
      break;
    }

    if (num_ignore_frames == 0) {
      frames->resize(num_frames+1);
      backtrace_frame_data_t* frame = &frames->at(num_frames);
      frame->num = num_frames;
      frame->pc = static_cast<uintptr_t>(pc);
      frame->sp = static_cast<uintptr_t>(sp);
      frame->stack_size = 0;

      if (num_frames > 0) {
        backtrace_frame_data_t* prev = &frames->at(num_frames-1);
        prev->stack_size = frame->sp - prev->sp;
      }

      frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);

      frame->map = FindMap(frame->pc);

      num_frames++;
    } else {
      num_ignore_frames--;
    }
    ret = unw_step (&cursor);
  } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);

  return true;
}
Exemplo n.º 17
0
int Plate::BuildMaps(TimeValue t, RenderMapsContext &rmc) {
	SubRendParams srp;
	rmc.GetSubRendParams(srp);
  	PlateMap *pmap = FindMap(rmc.NodeRenderID());
	if (pmap&&!DoThisFrame(t,srp.fieldRender,pmap->mapTime))
		return 1;
	ViewParams vp;

	Box2 sbox;

	rmc.GetCurrentViewParams(vp);

	rmc.FindMtlScreenBox(sbox, &vp.affineTM, rmc.SubMtlIndex());

	int xmin,xmax,ymin,ymax;

	BOOL fieldRender = FALSE;
	if (srp.fieldRender) {
		sbox.top *= 2;
		sbox.bottom *= 2;
		fieldRender = TRUE;
		}

		// add a margin around object for refraction
	int ew = srp.devWidth/20;
	int eh = srp.devHeight/20;
	xmax = sbox.right+ew;
	xmin = sbox.left-ew;
	ymax = sbox.bottom+eh;
	ymin = sbox.top-eh;

	if (srp.rendType==RENDTYPE_REGION) {
		ymin = MAX(ymin,srp.ymin-eh);
		ymax = MIN(ymax,srp.ymax+eh);
		xmin = MAX(xmin,srp.xmin-ew);
		xmax = MIN(xmax,srp.xmax+ew);
		}

	srp.xmin = MAX(xmin,-ew);
	srp.xmax = MIN(xmax,srp.devWidth+ew);
	srp.ymin = MAX(ymin,-eh);
	srp.ymax = MIN(ymax,srp.devHeight+eh);

	int xorg = xmin;
	int yorg = ymin;
	int devw = srp.devWidth;
	int devh = srp.devHeight;

	// The renderer is set up to allocate A-buffer for the range
	// 0..devWidth-1,  0..devHeight-1.  If the region of the plate
	// bitmap goes out of this region, it must be extended.
	int d1 = 0, d2 = 0;
	if (srp.xmin<0) d1 = -srp.xmin;
	if (srp.xmax>=srp.devWidth) d2 = srp.xmax-srp.devWidth+1;
	int d = MAX(d1,d2);
	if (d) {
		srp.devWidth += 2*d;
		srp.xmax += d;
		srp.xmin += d;
		// must also correct fov (or zoom) so the renderer computes the
		// same xscale and yscale
		if (vp.projType==PROJ_PERSPECTIVE) {
			vp.fov = 2.0f*(float)atan((float(srp.devWidth)/float(devw))*tan(0.5*vp.fov));
			}
		else {
			vp.zoom *= (float(srp.devWidth)/float(devw));
			}
		srp.blowupCenter.x += d; // DS: 11/6/00
		}	

	d1 = d2 = 0;
	if (srp.ymin<0) d1 = -srp.ymin;
	if (srp.ymax>=srp.devHeight) d2 = srp.ymax-srp.devHeight+1;
	d = MAX(d1,d2);
	if (d) {
//		if (fieldRender)
//			d = ((d+1)>>1)<<1; // make d even, so line doubling (below) works right.
		srp.devHeight += 2*d;
		srp.ymax += d;
		srp.ymin += d;
		srp.blowupCenter.y += d;   // DS: 11/6/00
		}	


	srp.xorg = srp.xmin;
	srp.yorg = srp.ymin;

	srp.doEnvMap = useEnvMap;
	//srp.doingMirror = TRUE;  // DS: 11/6/00: no longer necessary

	int w = srp.xmax-srp.xmin;
	int h = srp.ymax-srp.ymin;


	if (w<=0||h<=0) 
		return 1;
#ifdef DBG
	w = ((w+3)/4)*4;   // For some reason this needs to be a multiple of 4 for bm->Display
#endif

  	if (pmap==NULL) {
	  	pmap = new PlateMap;
		pmap->nodeID = rmc.NodeRenderID();
		pmap->next = maps;
		maps = pmap;
		}
	
	pmap->AllocMap(w, h);
	pmap->org.x = xorg-devw/2;
	pmap->org.y = yorg-devh/2;
	pmap->devW = devw;  // TBD: This should be accessable from the SC
	pmap->mapTime = t;

	
	// Set up clipping planes to clip out stuff between camera and plate.
	Box3 b = rmc.ObjectSpaceBoundingBox();
	Matrix3 tmObToWorld = rmc.ObjectToWorldTM();
	Matrix3 obToCam = tmObToWorld*vp.affineTM;	
	int nplanes=0;
	Point4 pl[6],pc;
	Point4 clip[6];

	pl[0] = Point4( 1.0f, 0.0f, 0.0f, -b.pmax.x);
	pl[1] = Point4(-1.0f, 0.0f, 0.0f,  b.pmin.x);
	pl[2] = Point4( 0.0f, 1.0f, 0.0f, -b.pmax.y);
	pl[3] = Point4( 0.0f,-1.0f, 0.0f,  b.pmin.y);
	pl[4] = Point4( 0.0f, 0.0f, 1.0f, -b.pmax.z);
	pl[5] = Point4( 0.0f, 0.0f,-1.0f,  b.pmin.z);
	if (vp.projType==PROJ_PARALLEL) {
		for (int i=0; i<6; i++) {
			pc = TransformPlane(obToCam,pl[i]);	
			// see if camera = (0,0,0) is in front of plane
			if (pc.z>0.0f)  
				clip[nplanes++] = -pc;
			}
		}
	else {
		for (int i=0; i<6; i++) {
			pc = TransformPlane(obToCam,pl[i]);	
			// see if camera = (0,0,0) is in front of plane
			if (pc.w>0.0f)  
				clip[nplanes++] = -pc;
			}
		}

	srp.fieldRender = FALSE;

//	assert(nplanes<4);
	if (!rmc.Render(pmap->bm, vp, srp, clip, nplanes))
		return 0;

/*
	if (srp.fieldRender) {
		// Double the lines, otherwise the blur wont work right,
		// because the blank lines in between get averaged in and darken it.
		int	evenLines = srp.evenLines; 
		if(srp.ymin&1) 
			evenLines = !evenLines;

		PixelBuf l64(w);
		if (evenLines) {
			for (int i=0; i<h; i+=2) {
				BMM_Color_64 *p64=l64.Ptr();
				if (i+1<h) {
					pmap->bm->GetPixels(0,i,  w, p64); 
					pmap->bm->PutPixels(0,i+1,w, p64);				
					}
				}
			}
		else {
			for (int i=0; i<h; i+=2) {
				BMM_Color_64 *p64=l64.Ptr();
				if (i+1<h) {
					pmap->bm->GetPixels(0,i+1,w, p64); 
					pmap->bm->PutPixels(0,i  ,w, p64);				
					}
				}
			}
		}
*/

#ifdef DBG
	if (devw>200){
		pmap->bm->UnDisplay();
		TSTR buf;
		RenderGlobalContext *gc = rmc.GetGlobalContext();
		RenderInstance* inst = gc->GetRenderInstance(rmc.NodeRenderID());
		INode *node  = inst->GetINode();
		buf.printf(_T("Thinwall: %s"), node->GetName());
		pmap->bm->Display(buf, BMM_UR);
		MessageBox(NULL, _T("hi"), _T(" Plate Test"), MB_OK|MB_ICONEXCLAMATION);
		}
#endif

	if (applyBlur) {
		// I tried pyramids here, but SATs looked much better. 
		//  maybe we should give users a choice?
		pmap->bm->SetFilter(BMM_FILTER_SUM); 
//		pmap->bm->SetFilter(BMM_FILTER_PYRAMID); 
		BitmapFilter *filt = pmap->bm->Filter();
		if (filt)
			filt->MakeDirty();  // so filter gets recomputed for each frame
		}
	else 
		pmap->bm->SetFilter(BMM_FILTER_NONE); 
	return 1;
	}
Exemplo n.º 18
0
RGBA Plate::EvalColor(ShadeContext& sc) {
	BMM_Color_64 c;
	IPoint2 s;
	int id = sc.NodeID();
	PlateMap *pmap = FindMap(id);
	if (gbufID) sc.SetGBufferID(gbufID);
	if (pmap) {
		s = sc.ScreenCoord();
		int w = pmap->bm->Width(); 
		int h = pmap->bm->Height();

		Point3 view = sc.OrigView();
		Point3 v2 = sc.V();
		Point3 p = sc.P();
		Point3 dV,dvf;
		Point3 N0 = sc.OrigNormal();

		Point3 vf = RefractVector(sc, N0, view, sc.GetIOR()); 
		
		RenderGlobalContext *gc = sc.globContext;
		if (gc==NULL) return blackrgba;

		// total deflection due to refraction
		dV = view-v2;

		// deflection due to flat refracton (no bumps)
		dvf = view-vf;

		dV = refrAmt*(dV-dvf) + thick*dvf;

		// compute screen deflection: This is really a cheat, and the
		// scale factor is arbitrary. Infact it depends on the distance 
		// between to the point on the glass plate and  to the point being
		// seen behind it, which we don't know.
		// these should be multiplied by the factor (Zbehind-Zcur)/Zcur
		// This assumes that the factor is .1

		float dsx,dsy;
		if (gc->projType==0) {
			// perspective
			dsx = dV.x*0.1f*gc->xscale;
			dsy = dV.y*0.1f*gc->yscale;
			}
		else {
			// parallel projection
			dsx = -dV.x*gc->xscale*10.0f;
			dsy = -dV.y*gc->yscale*10.0f;
			}

		if (gc->fieldRender) dsy *= 2.0f;		
		int x = s.x - (pmap->org.x+gc->devWidth/2);
		int y = s.y - (pmap->org.y+gc->devHeight/2);

		if (applyBlur) {
			float du = 1.0f/float(w);
			float dv = 1.0f/float(h);

			float u = (float(x)+dsx)*du; 
			float v = (float(y)+dsy)*dv; 
			if (u<0.0f||u>1.0f||v<0.0f||v>1.0f) {
				if (useEnvMap) {
					return sc.EvalGlobalEnvironMap(view-dvf);
					}
				else 
					return blackrgba;
				}
			else 
				pmap->bm->GetFiltered(u,v, du*blur, dv*blur,&c);
			}
		else {
			int ix = x + int(dsx); 
			int iy = y + int(dsy); 
			if (ix<0||ix>=w||iy<0||iy>=h) {
				if (useEnvMap)
					return sc.EvalGlobalEnvironMap(view-dvf);
				else 
					return blackrgba;
				}
			else 
				pmap->bm->GetLinearPixels(ix,iy,1,&c);
			}
		return c;
		}
	else 
		return blackrgba;
	}
Exemplo n.º 19
0
/* Loads an area */
int Game::LoadMap(const char* ResRef, bool loadscreen)
{
	unsigned int i, ret;
	Map *newMap;
	PluginHolder<MapMgr> mM(IE_ARE_CLASS_ID);
	ScriptEngine *sE = core->GetGUIScriptEngine();

	//this shouldn't happen
	if (!mM) {
		return -1;
	}

	int index = FindMap(ResRef);
	if (index>=0) {
		return index;
	}

	bool hide = false;
	if (loadscreen && sE) {
		hide = core->HideGCWindow();
		sE->RunFunction("LoadScreen", "StartLoadScreen");
		sE->RunFunction("LoadScreen", "SetLoadScreen");
	}
	DataStream* ds = gamedata->GetResource( ResRef, IE_ARE_CLASS_ID );
	if (!ds) {
		goto failedload;
	}
	if(!mM->Open(ds)) {
		goto failedload;
	}
	newMap = mM->GetMap(ResRef, IsDay());
	if (!newMap) {
		goto failedload;
	}

	core->LoadProgress(100);

	ret = AddMap( newMap );

	//spawn creatures on a map already in the game
	//this feature exists in all blackisle games but not in bioware games
	if (core->HasFeature(GF_SPAWN_INI)) {
		newMap->LoadIniSpawn();
	}

	for (i = 0; i < PCs.size(); i++) {
		if (stricmp( PCs[i]->Area, ResRef ) == 0) {
			newMap->AddActor( PCs[i], false );
		}
	}

	PlacePersistents(newMap, ResRef);

	if (hide) {
		core->UnhideGCWindow();
	}
	newMap->InitActors();

	return ret;
failedload:
	if (hide) {
		core->UnhideGCWindow();
	}
	core->LoadProgress(100);
	return -1;
}
Exemplo n.º 20
0
		/*!
		 * \brief
		 * Processes an xml document to parse the map part definition it contains and add it to the list.
		 * 
		 * \param definition_path
		 * The path to the xml document on disk.
		 * 
		 * \returns
		 * Returns true if the xml was valid and processed successfully otherwise returns false.
		 * 
		 * Processes an xml document to parse the map part definition it contains and add it to the list.
		 */
		static bool AddMapDefinition(const char* definition_path)
		{
			TiXmlDocument definition;
			// load the map part definition
			definition.LoadFile(definition_path);

			// check the xml loaded correctly
			if(definition.Error())
			{
				blam::console_printf("Failed to load and parse the map part definition\nError: %s", definition.ErrorDesc());
				return false;
			}

			// get the xml root
			TiXmlElement* root_node = definition.FirstChildElement("osHTTPServer");
			if(!root_node)
			{
				blam::console_printf(false, "The map part definition has no osHTTPServer root node");
				return false;
			}

			// get the map element
			const TiXmlElement* map_node = root_node->FirstChildElement("map_download");
			if(!map_node)
			{
				blam::console_printf(false, "The map part definition has no map_download node");
				return false;
			}

			const char* name = map_node->Attribute("name");
			const char* md5 = map_node->Attribute("md5");
			const char* algorithm = map_node->Attribute("algorithm");
			const char* host_directory = map_node->Attribute("host_directory");

			// check the md5 string is the correct length
			bool md5_valid = false;
			if(md5)
				md5_valid = (strlen(md5) == 32);

			// if the map is valid, create a new map element
			if(name && md5 && md5_valid && algorithm)
			{
				// remove the extension from the map name
				std::string map_name(name);
				std::string::size_type extension_offset = std::string::npos;

				if((extension_offset = map_name.find(Cache::K_MAP_FILE_EXTENSION)) != std::string::npos)
					map_name.resize(extension_offset);
				else if((extension_offset = map_name.find(Cache::K_MAP_FILE_EXTENSION_YELO)) != std::string::npos)
					map_name.resize(extension_offset);

				if(FindMap(map_name.c_str()))
				{
					blam::console_printf(false, "Map definition for %s already exists", map_name.c_str());
					return false;
				}

				c_map_element* map_element = new c_map_element();
				map_element->Ctor();

				// assign the name of the map and remove its extension for later comparisons
				map_element->m_name = map_name;

				// create a copy of the maps part definition to send to the client
				// remove the host_directory attribute from the client copy as it is unnecessary
				map_element->m_part_definition = map_node->Clone()->ToElement();
				map_element->m_part_definition->RemoveAttribute("host_directory");

				// add the parts to the map element, host_directory can be null
				if(!AddMapParts(map_element, map_node, host_directory))
				{
					// a problem occurred when adding the maps part elements so delete the map element and return
					delete map_element;
					return false;
				}

				// add the completed map element to the definition lists
				if(!AddMapToList(map_element))
				{
					RemoveMapParts(map_element);

					delete map_element;
					return false;
				}
			}
			else
			{
				if(!name)
					blam::console_printf(false, "A map node is missing its name");
				if(!md5)
					blam::console_printf(false, "A map node is missing its md5 checksum");
				else if(!md5_valid)
					blam::console_printf(false, "A map nodes md5 checksum is too long/short");
				if(!algorithm)
					blam::console_printf(false, "A map node does not state its compression algorithm");
				if(!host_directory)
					blam::console_printf(false, "A map node is missing its host_directory");

				return false;
			}

			return true;
		}
Exemplo n.º 21
0
static void *
MapPhysAddress(unsigned long address, unsigned long size)
{
    unsigned long offset, delta;
    int pagesize = -1;
    void *vaddr;
    MapPtr mp;
#if defined(ISC) && defined(HAS_SVR3_MMAP)
    struct kd_memloc mloc;
#elif defined(__EMX__)
    APIRET rc;
    ULONG action;
    HFILE hfd;
#endif

    if ((mp = FindMap(address, size))) {
	mp->refcount++;
	return (void *)((unsigned long)mp->vaddr + mp->delta);
    }

#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
    pagesize = sysconf(_SC_PAGESIZE);
#endif
#ifdef _SC_PAGE_SIZE
    if (pagesize == -1)
	pagesize = sysconf(_SC_PAGE_SIZE);
#endif
#ifdef HAS_GETPAGESIZE
    if (pagesize == -1)
	pagesize = getpagesize();
#endif
#ifdef PAGE_SIZE
    if (pagesize == -1)
	pagesize = PAGE_SIZE;
#endif
    if (pagesize == -1)
	pagesize = 4096;

   delta = address % pagesize;
   offset = address - delta;

#if defined(ISC) && defined(HAS_SVR3_MMAP)
    if (mapFd < 0) {
	if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
	    return NULL;
    }
    mloc.vaddr = (char *)0;
    mloc.physaddr = (char *)offset;
    mloc.length = size + delta;
    mloc.ioflg=1;

    if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
	return NULL;
#elif defined (__EMX__)
    /*
     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
     * Consecutive calling of this routine will make PMAP$ driver run out
     * of memory handles. Some umap/close mechanism should be provided
     */

    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
    if (rc != 0)
	return NULL;
    {
	struct map_ioctl {
		union {
			ULONG phys;
			void* user;
		} a;
		ULONG size;
	} pmap,dmap;
	ULONG plen,dlen;
#define XFREE86_PMAP	0x76
#define PMAP_MAP	0x44

	pmap.a.phys = offset;
	pmap.size = size + delta;
	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
			 (PULONG)&pmap, sizeof(pmap), &plen,
			 (PULONG)&dmap, sizeof(dmap), &dlen);
	if (rc == 0) {
		vaddr = dmap.a.user;
	}
   }
   if (rc != 0)
	return NULL;
#elif defined (Lynx)
    vaddr = (void *)smem_create("XF86DGA", (char *)offset, 
				size + delta, SM_READ|SM_WRITE);
#else
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
    if (mapFd < 0) {
	if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
	    return NULL;
    }
    vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
                        MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
    if (vaddr == (void *)-1)
	return NULL;
#endif

    if (!vaddr) {
	if (!(mp = AddMap()))
	    return NULL;
	mp->physaddr = address;
	mp->size = size;
	mp->delta = delta;
	mp->vaddr = vaddr;
	mp->refcount = 1;
    }
    return (void *)((unsigned long)vaddr + delta);
}
Exemplo n.º 22
0
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
{
    Map* map = FindMap();
    if (!map)
        return NULL;

    uint32 mask = UNIT_MASK_SUMMON;
    if (properties)
    {
        switch (properties->Category)
        {
            case SUMMON_CATEGORY_PET:
                mask = UNIT_MASK_GUARDIAN;
                break;
            case SUMMON_CATEGORY_PUPPET:
                mask = UNIT_MASK_PUPPET;
                break;
            case SUMMON_CATEGORY_VEHICLE:
                mask = UNIT_MASK_MINION;
                break;
            case SUMMON_CATEGORY_WILD:
            case SUMMON_CATEGORY_ALLY:
            case SUMMON_CATEGORY_UNK:
            {
                switch (properties->Type)
                {
                    case SUMMON_TYPE_MINION:
                    case SUMMON_TYPE_GUARDIAN:
                    case SUMMON_TYPE_GUARDIAN2:
                        mask = UNIT_MASK_GUARDIAN;
                        break;
                    case SUMMON_TYPE_TOTEM:
                    case SUMMON_TYPE_LIGHTWELL:
                        mask = UNIT_MASK_TOTEM;
                        break;
                    case SUMMON_TYPE_VEHICLE:
                    case SUMMON_TYPE_VEHICLE2:
                        mask = UNIT_MASK_SUMMON;
                        break;
                    case SUMMON_TYPE_MINIPET:
                        mask = UNIT_MASK_MINION;
                        break;
                    default:
                        if (properties->Flags & 512) // Mirror Image, Summon Gargoyle
                            mask = UNIT_MASK_GUARDIAN;
                        break;
                }
                break;
            }
            default:
                return NULL;
        }
    }

    uint32 phase = PHASEMASK_NORMAL;
    uint32 team = 0;
    if (summoner)
    {
        phase = summoner->GetPhaseMask();
        if (summoner->GetTypeId() == TYPEID_PLAYER)
            team = summoner->ToPlayer()->GetTeam();
    }

    TempSummon* summon = NULL;
    switch (mask)
    {
        case UNIT_MASK_SUMMON:
            summon = new TempSummon(properties, summoner, false);
            break;
        case UNIT_MASK_GUARDIAN:
            summon = new Guardian(properties, summoner, false);
            break;
        case UNIT_MASK_PUPPET:
            summon = new Puppet(properties, summoner);
            break;
        case UNIT_MASK_TOTEM:
            summon = new Totem(properties, summoner);
            break;
        case UNIT_MASK_MINION:
            summon = new Minion(properties, summoner, false);
            break;
    }

    float x, y, z, o;
    pos.GetPosition(x, y, z, o);
    CalculatePassengerPosition(x, y, z, &o);

    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, vehId, team, x, y, z, o))
    {
        delete summon;
        return NULL;
    }

    summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);

    summon->SetTransport(this);
    summon->m_movementInfo.transport.guid = GetGUID();
    summon->m_movementInfo.transport.pos.Relocate(pos);
    summon->Relocate(x, y, z, o);
    summon->SetHomePosition(x, y, z, o);
    summon->SetTransportHomePosition(pos);

    /// @HACK - transport models are not added to map's dynamic LoS calculations
    ///         because the current GameObjectModel cannot be moved without recreating
    summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);

    summon->InitStats(duration);

    if (!map->AddToMap<Creature>(summon))
    {
        delete summon;
        return NULL;
    }

    _staticPassengers.insert(summon);

    summon->InitSummon();
    summon->SetTempSummonType(summonType);

    return summon;
}
Exemplo n.º 23
0
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
{
    Map* map = FindMap();
    if (!map)
        return NULL;

    uint32 mask = UNIT_MASK_SUMMON;
    if (properties)
    {
        switch (properties->Control)
        {
            case SUMMON_CATEGORY_PET:
                mask = UNIT_MASK_GUARDIAN;
                break;
            case SUMMON_CATEGORY_PUPPET:
                mask = UNIT_MASK_PUPPET;
                break;
            case SUMMON_CATEGORY_VEHICLE:
                mask = UNIT_MASK_MINION;
                break;
            case SUMMON_CATEGORY_WILD:
            case SUMMON_CATEGORY_ALLY:
            case SUMMON_CATEGORY_UNK:
            {
                switch (properties->Title)
                {
                    case SUMMON_TYPE_MINION:
                    case SUMMON_TYPE_GUARDIAN:
                    case SUMMON_TYPE_GUARDIAN2:
                        mask = UNIT_MASK_GUARDIAN;
                        break;
                    case SUMMON_TYPE_TOTEM:
                    case SUMMON_TYPE_LIGHTWELL:
                        mask = UNIT_MASK_TOTEM;
                        break;
                    case SUMMON_TYPE_VEHICLE:
                    case SUMMON_TYPE_VEHICLE2:
                        mask = UNIT_MASK_SUMMON;
                        break;
                    case SUMMON_TYPE_MINIPET:
                        mask = UNIT_MASK_MINION;
                        break;
                    default:
                        if (properties->Flags & 512) // Mirror Image, Summon Gargoyle
                            mask = UNIT_MASK_GUARDIAN;
                        break;
                }
                break;
            }
            default:
                return NULL;
        }
    }

    TempSummon* summon = nullptr;
    switch (mask)
    {
        case UNIT_MASK_SUMMON:
            summon = new TempSummon(properties, summoner, false);
            break;
        case UNIT_MASK_GUARDIAN:
            summon = new Guardian(properties, summoner, false);
            break;
        case UNIT_MASK_PUPPET:
            summon = new Puppet(properties, summoner);
            break;
        case UNIT_MASK_TOTEM:
            summon = new Totem(properties, summoner);
            break;
        case UNIT_MASK_MINION:
            summon = new Minion(properties, summoner, false);
            break;
    }

    float x, y, z, o;
    pos.GetPosition(x, y, z, o);
    CalculatePassengerPosition(x, y, z, &o);

    if (!summon->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, entry, x, y, z, o, nullptr, vehId))
    {
        delete summon;
        return nullptr;
    }

    PhasingHandler::InheritPhaseShift(summon, summoner ? static_cast<WorldObject*>(summoner) : static_cast<WorldObject*>(this));

    summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);

    summon->SetTransport(this);
    summon->m_movementInfo.transport.guid = GetGUID();
    summon->m_movementInfo.transport.pos.Relocate(pos);
    summon->Relocate(x, y, z, o);
    summon->SetHomePosition(x, y, z, o);
    summon->SetTransportHomePosition(pos);

    /// @HACK - transport models are not added to map's dynamic LoS calculations
    ///         because the current GameObjectModel cannot be moved without recreating
    summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);

    summon->InitStats(duration);

    if (!map->AddToMap<Creature>(summon))
    {
        delete summon;
        return nullptr;
    }

    _staticPassengers.insert(summon);

    summon->InitSummon();
    summon->SetTempSummonType(summonType);

    return summon;
}