Example #1
0
// -- Creates a JB2Image with the remaining components
GP<JB2Image> 
CCImage::get_jb2image() const
{
  GP<JB2Image> jimg = JB2Image::create();
  jimg->set_dimension(width, height);
  if (runs.hbound() < 0)
    return jimg;
  if (ccs.hbound() < 0)
    G_THROW("Must first perform a cc analysis");
  // Iterate over CCs
  for (int ccid=0; ccid<=ccs.hbound(); ccid++)
    {
      JB2Shape shape;
      JB2Blit  blit;
      shape.parent = -1;
      shape.bits = get_bitmap_for_cc(ccid);
      shape.userdata = 0;
      if (ccid >= nregularccs)
        shape.userdata |= JB2SHAPE_SPECIAL;
      blit.shapeno = jimg->add_shape(shape);
      blit.left = ccs[ccid].bb.xmin;
      blit.bottom = ccs[ccid].bb.ymin;
      jimg->add_blit(blit);
      shape.bits->compress();
    }
  // Return
  return jimg;
}
//************************************
// Method:    ShowWinline
// FullName:  BSSlotsContainer::ShowWinline
// Access:    protected 
// Returns:   bool
// Qualifier: show winline
// Parameter: const int id   :  winlinID
//************************************
bool BSSlotsContainer::SetupWinline(const int winlineID, const int timeToShowPerWinline)
{
	if(m_pTicketGenerator == NULL)
		return false;
	
	//show winline slot animations;
	if(!m_winlineReelSlotsDict.KeyExists(winlineID))
	{
		GTLogManager::SLogFormatWarning("Warning! Can not find  winline%d!", winlineID);
		return false;
	}
	
	GTArray<GTVector2>*  pWinSlotsInReel = NULL;
	m_winlineReelSlotsDict.GetValueByKey(winlineID, pWinSlotsInReel);
	if(pWinSlotsInReel != NULL)
	{
		for(int i=0; i < pWinSlotsInReel->Length(); i++)
		{
			GTVector2 value = (*pWinSlotsInReel)[i];
			int reelID = value.x;
			int slotPos = value.y; 
			m_reelColumns[reelID]->ShowWinline(winlineID, slotPos, timeToShowPerWinline);

			//GTLogManager::SLogFormatComment("-----  show winline %d    ------- reel %d  : status = %d --> slot[%d] win!!!", 
			//								it->first, reelID, m_reelColumns[reelID]->GetStatus(), slotPos);
		}
		return true;
	}

	return false;
}
//check all reels status;
GTArray<BSReelColumn::ColumnStatus> BSSlotsContainer::CheckAllReelsStatus()
{
	GTArray<BSReelColumn::ColumnStatus> reelColumnsStatus;
	for(int i = 0; i < m_reelColumnCount; i++)
	{
		BSReelColumn::ColumnStatus status = m_reelColumns[i]->GetStatus();
		reelColumnsStatus.Add(status);
	}
	return reelColumnsStatus;
}
Example #4
0
// -- Adds a run to the CCImage
inline void 
CCImage::add_single_run(int y, int x1, int x2, int ccid)
{
  int index = runs.hbound();
  runs.touch(++index);
  Run& run = runs[index];
  run.y = y;
  run.x1 = x1;
  run.x2 = x2;
  run.ccid = ccid;
}
Example #5
0
void
CCImage::init(int w, int h, int dpi)
{
  runs.empty();
  ccs.empty();
  height = h;
  width = w;
  nregularccs = 0;
  dpi = MAX(200, MIN(900, dpi));
  largesize = MIN( 500, MAX(64, dpi));
  smallsize = MAX(2, dpi/150);
  tinysize = MAX(0, dpi*dpi/20000 - 1);
}
//************************************
// Method:    CreateTicket
// FullName:  BSSlotsContainer::BuildTicket
// Access:    public 
// Returns:   void
// Qualifier: based on real slot symbols to build fake tickets to all reels; Fake reels(top & bottom invisible)
// Parameter: GTArray<int> slotSymbols   :
//************************************
void BSSlotsContainer::BuildTicket(GTArray<int> slotSymbols)
{
#ifdef GT_DEBUG
	GTLogManager::SLogFormatComment("<------------- slot symbols (visible part current 3X5 reels)----------->");	
	GTLogManager::SLogFormatComment(slotSymbols.ToString());
#endif

	//based on real slot symbols to create fake tickets to all reels; 
	//make Fake reels(top & bottom invisible)

	//for exmaple:
	//	2, 3, 5, 6, 5,
	//	5, 5, 5, 8, 1,
	//	4, 3, 3, 3, 3
	//  make 5 reels
	//  reel1: 0, 2, 5, 4, 0
	//  reel2: 0, 3, 5, 3, 0
	// and so on
	GTDictionary<int, GTArray<int>* > reeltickets;

	//initialize
	for(int reelIndex = 0; reelIndex < m_reelColumns.Count(); reelIndex++)
	{
		GTArray<int>* pTickets = new GTArray<int>();
		pTickets->AddToTail(0);	//make fake symbols for top invisible symbols
		reeltickets.Add(reelIndex, pTickets);
	}

	//add reel symbols;
	for(int i = 0; i < slotSymbols.Length(); i++)
	{
		int reelID = i % m_reelColumns.Count();
		int slotSymbolValue = slotSymbols[i];

		GTArray<int>* pTickets = NULL;
		reeltickets.GetValueByKey(reelID, pTickets);		
		pTickets->AddToTail(slotSymbolValue);
	}

	//make fake symbols for top and bottom invisible symbols;
	for(int reelIndex = 0; reelIndex < m_reelColumns.Count(); reelIndex++)
	{
		GTArray<int>* pTickets;
		reeltickets.GetValueByKey(reelIndex, pTickets);
		pTickets->AddToTail(0);		//make fake symbols for bottom invisible symbols

		m_reelColumns[reelIndex]->SetTicket(*pTickets);	//send it to every reel;

		delete pTickets;
	}
	m_slotsSymbols = slotSymbols;
}
 //************************************
 // Method:    GetReelWinSlotsForWinlines
 // FullName:  BSSlotsContainer::GetReelWinSlotsForWinlines
 // Access:    protected 
 // Returns:   GTDictionary<int, GTArray<GTVector2>* >   key = winlineID,  value = (reelID, slotID)
 // Qualifier: based on finalWinlineRes and winline define, match to every win slot position in every reel; and get (reel and win slots in this reel) for all winline
 // Parameter: GTDictionary<int, WinlineValue> finalWinlineRes   :  key = winlineID,  value = winlineValue;
 //************************************
void BSSlotsContainer::GetReelWinSlotsForWinlines(GTDictionary<int, WinlineValue>* pFinalWinlineRes)
{
	
	 //get winline define;
	 GTDictionary<int, GTArray<int> >* pSourceWinlines = WinlineAlgorithm::GetWinlines();
	 // based on finalWinlineRes and winline define, match to every win slot position in every slot;
	for(GTDictionary<int,WinlineValue>::ObjectTypeIterator it= pFinalWinlineRes->Begin(); it != pFinalWinlineRes->End(); it++)
	{
		int winlineID = it->first;
		WinlineValue value = it->second;
		int winCount = value.WinCount;
		
		GTArray<int> winline;
		pSourceWinlines->GetValueByKey(winlineID, winline);	//get winline;

		for(int i = 0; i < winCount; i++)
		{
			int winSlot = winline[i];
			int reelID = winSlot % m_reelColumnCount;	//get reelID;
			int realSlotPosInReel = winSlot / m_reelColumnCount;	//realSlotPostion
			int slotPosInReel = realSlotPosInReel + 1;	// because we had one fake slot (invisible)
			GTVector2 reelWinSlotValue(reelID, slotPosInReel);	//value = (reelID, slotPosInReel) in reel;

			GTArray<GTVector2>* winReelSlots = NULL;
			//add winline slot into reelWinSlotsDict;
			if(m_winlineReelSlotsDict.KeyExists(winlineID))
			{
				m_winlineReelSlotsDict.GetValueByKey(winlineID, winReelSlots);
			}
			else
			{
				winReelSlots = new GTArray<GTVector2>();
			}
			winReelSlots->AddToTail(reelWinSlotValue);
			m_winlineReelSlotsDict.Add(winlineID, winReelSlots);	//save winlineid as key, value is reel slot value to dict
		}
	}
}
Example #8
0
// Removes ccs which are too small.
void
CCImage::erase_tiny_ccs()
{
  // ISSUE: HALFTONE DETECTION
  // We should not remove tiny ccs if they are part of a halftone pattern...
  for (int i=0; i<ccs.size(); i++)
    {
      CC& cc = ccs[i];
      if (cc.npix <= tinysize)
        {
          // Mark cc to be erased
          Run *r = &runs[cc.frun];
          int nr = cc.nrun;
          cc.nrun = 0;
          cc.npix = 0;
          while (--nr >= 0)
            (r++)->ccid = -1;
        }
    }
}
Example #9
0
int
DjVuPalette::compute_palette(int maxcolors, int minboxsize)
{
  if (!hist)
    G_THROW( ERR_MSG("DjVuPalette.no_color") );
  if (maxcolors<1 || maxcolors>MAXPALETTESIZE)
    G_THROW( ERR_MSG("DjVuPalette.many_colors") );
  
  // Paul Heckbert: "Color Image Quantization for Frame Buffer Display", 
  // SIGGRAPH '82 Proceedings, page 297.  (also in ppmquant)
  
  // Collect histogram colors
  int sum = 0;
  int ncolors = 0;
  GTArray<PData> pdata;
  { // extra nesting for windows
    for (GPosition p = *hist; p; ++p)
    {
      pdata.touch(ncolors);
      PData &data = pdata[ncolors++];
      int k = hist->key(p);
      data.p[0] = (k>>16) & 0xff;
      data.p[1] = (k>>8) & 0xff;
      data.p[2] = (k) & 0xff;
      data.w = (*hist)[p];
      sum += data.w;
    }
  }
  // Create first box
  GList<PBox> boxes;
  PBox newbox;
  newbox.data = pdata;
  newbox.colors = ncolors;
  newbox.boxsize = 256;
  newbox.sum = sum;
  boxes.append(newbox);
  // Repeat spliting boxes
  while (boxes.size() < maxcolors)
    {
      // Find suitable box
      GPosition p;
      for (p=boxes; p; ++p)
        if (boxes[p].colors>=2 && boxes[p].boxsize>minboxsize) 
          break;
      if (! p)
        break;
      // Find box boundaries
      PBox &splitbox = boxes[p];
      unsigned char pmax[3];
      unsigned char pmin[3];
      pmax[0] = pmin[0] = splitbox.data->p[0];
      pmax[1] = pmin[1] = splitbox.data->p[1];
      pmax[2] = pmin[2] = splitbox.data->p[2];
      { // extra nesting for windows
        for (int j=1; j<splitbox.colors; j++)
        {
          pmax[0] = umax(pmax[0], splitbox.data[j].p[0]);
          pmax[1] = umax(pmax[1], splitbox.data[j].p[1]);
          pmax[2] = umax(pmax[2], splitbox.data[j].p[2]);
          pmin[0] = umin(pmin[0], splitbox.data[j].p[0]);
          pmin[1] = umin(pmin[1], splitbox.data[j].p[1]);
          pmin[2] = umin(pmin[2], splitbox.data[j].p[2]);
        }
      }
      // Determine split direction and sort
      int bl = pmax[0]-pmin[0]; 
      int gl = pmax[1]-pmin[1];
      int rl = pmax[2]-pmin[2];
      splitbox.boxsize = (bl>gl ? (rl>bl ? rl : bl) : (rl>gl ? rl : gl));
      if (splitbox.boxsize <= minboxsize)
        continue;
      if (gl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), gcomp);
      else if (rl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), rcomp);
      else
        qsort(splitbox.data, splitbox.colors, sizeof(PData), bcomp);
      // Find median
      int lowercolors = 0;
      int lowersum = 0;
      while (lowercolors<splitbox.colors-1 && lowersum+lowersum<splitbox.sum)
        lowersum += splitbox.data[lowercolors++].w;
      // Compute new boxes
      newbox.data = splitbox.data + lowercolors;
      newbox.colors = splitbox.colors - lowercolors;
      newbox.sum = splitbox.sum - lowersum;
      splitbox.colors = lowercolors;
      splitbox.sum = lowersum;
      // Insert boxes at proper location
      GPosition q;
      for (q=p; q; ++q)
        if (boxes[q].sum < newbox.sum)
          break;
      boxes.insert_before(q, newbox);
      for (q=p; q; ++q)
        if (boxes[q].sum < splitbox.sum)
          break;
      boxes.insert_before(q, boxes, p);
    }
  // Fill palette array
  ncolors = 0;
  palette.empty();
  palette.resize(0,boxes.size()-1);
  { // extra nesting for windows
    for (GPosition p=boxes; p; ++p)
    {
      PBox &box = boxes[p];
      // Compute box representative color
      float bsum = 0;
      float gsum = 0;
      float rsum = 0;
      for (int j=0; j<box.colors; j++)
        {
          float w = (float)box.data[j].w;
          bsum += box.data[j].p[0] * w;
          gsum += box.data[j].p[1] * w;
          rsum += box.data[j].p[2] * w;
        }
      PColor &color = palette[ncolors++];
      color.p[0] = (unsigned char) fmin(255, bsum/box.sum);
      color.p[1] = (unsigned char) fmin(255, gsum/box.sum);
      color.p[2] = (unsigned char) fmin(255, rsum/box.sum);
      color.p[3] = ( color.p[0]*BMUL + color.p[1]*GMUL + color.p[2]*RMUL) / SMUL;
    }
  }
  // Save dominant color
  PColor dcolor = palette[0];
  // Sort palette colors in luminance order
  qsort((PColor*)palette, ncolors, sizeof(PColor), lcomp);
  // Clear invalid data
  colordata.empty();
  delete pmap;
  pmap = 0;
  // Return dominant color
  return color_to_index_slow(dcolor.p);
}
// Create the sprite from the property tree node
bool BSWinlineLoader::CreateFromPropertyTreeNode(GTTreeNode *pTreeNode)
{
	if(NULL == pTreeNode)
	{
		return false;
	}


	bool res = false;
	GTString errorCode("");

	//load all winlines;  Note: from winline 1 -> n 
	int winlineID = 1;
	do 
	{
		//set reel name
		GTString winlineTag = PROPERTY_TAG_WINLINE;
		winlineTag.Append(GTString::From(winlineID));// + GTString::FormatFrom(id);
		GTTreeNode* pWinline = pTreeNode->GetChild(winlineTag.ToCharString());

		if(pWinline == NULL)
			break;

		GTArray<int> winlineSlotArray;	//winline slot define;
		pWinline->ValueToArrayInt(winlineSlotArray);

		if(m_winlineDict.KeyExists(winlineID))
		{
			m_winlineDict.Remove(winlineID);
			GTLogManager::SLogFormatWarning("Warning! new winline[%d] will replace old one!!", winlineID);
		}
		m_winlineDict.Add(winlineID, winlineSlotArray);
		winlineID++;		
	} while (true);


	//load paytable; from 1 -> n
	int wintableID = 1;
	do 
	{
		//set reel name
		GTString PayTableTag = PROPERTY_TAG_PAYTABLE;
		PayTableTag.Append(GTString::From(wintableID));// + GTString::FormatFrom(id);
		GTTreeNode* pPaytable = pTreeNode->GetChild(PayTableTag.ToCharString());

		if(pPaytable == NULL)
			break;

		GTArray<int> payTableValue;	//winline slot define;
		pPaytable->ValueToArrayInt(payTableValue);

		if(payTableValue.Length() < 2)
		{
			GTLogManager::SLogFormatError("Error! Paytable[%d] does not have 2 values!", wintableID);
		}
		else
		{
			int paytableID = payTableValue[0];
			int ptValue = payTableValue[1];
			if(m_paytableDict.KeyExists(paytableID))
			{
				m_paytableDict.Remove(paytableID);
				GTLogManager::SLogFormatWarning("Warning! new paytable[%d] will replace old one!!", wintableID);
			}
			m_paytableDict.Add(paytableID, ptValue);
		}
		wintableID++;		
	} while (true);


	return res;
}
Example #11
0
// -- Merges small ccs of similar color and splits large ccs
void
CCImage::merge_and_split_ccs(int smallsize, int largesize)
{
  int ncc = ccs.size();
  int nruns = runs.size();
  int splitsize = largesize;
  if (ncc <= 0) return;
  // Associative map for storing merged ccids
  GMap<Grid_x_Color,int> map;
  nregularccs = ncc;
  // Set the correct ccids for the runs
  for (int ccid=0; ccid<ccs.size(); ccid++)
    {
      CC* cc = &ccs[ccid];
      if (cc->nrun <= 0) continue;
      Grid_x_Color key;
      key.color = cc->color;
      int ccheight = cc->bb.height();
      int ccwidth = cc->bb.width();
      if (ccheight<=smallsize && ccwidth<=smallsize)
        {
          key.gridi = (cc->bb.ymin+cc->bb.ymax)/splitsize/2;
          key.gridj = (cc->bb.xmin+cc->bb.xmax)/splitsize/2;
          int newccid = makeccid(key, map, ncc);
          for(int runid=cc->frun; runid<cc->frun+cc->nrun; runid++)
            runs[runid].ccid = newccid;
        }
      else if (ccheight>=largesize || ccwidth>=largesize)
        {
          for(int runid=cc->frun; runid<cc->frun+cc->nrun; runid++)
            {
              Run *r = & runs[runid];
              key.gridi = r->y/splitsize;
              key.gridj = r->x1/splitsize;
              int gridj_end = r->x2/splitsize;
              int gridj_span = gridj_end - key.gridj;
              r->ccid = makeccid(key, map, ncc);
              if (gridj_span>0)
                {
                  // truncate current run 
                  runs.touch(nruns+gridj_span-1);
                  r = &runs[runid];
                  int x = key.gridj*splitsize + splitsize;
                  int x_end = r->x2;
                  r->x2 = x-1;
                  // append additional runs to the runs array
                  while (++key.gridj < gridj_end)
                    {
                      Run& newrun = runs[nruns++];
                      newrun.y = r->y;
                      newrun.x1 = x;
                      x += splitsize;
                      newrun.x2 = x-1;
                      newrun.color = key.color;
                      newrun.ccid = makeccid(key, map, ncc);
                    }
                  // append last run to the run array
                  Run& newrun = runs[nruns++];
                  newrun.y = r->y;
                  newrun.x1 = x;
                  newrun.x2 = x_end;
                  newrun.color = key.color;
                  newrun.ccid = makeccid(key, map, ncc);
                }
            }
        }
    }
  // Recompute cc descriptors
  make_ccs_from_ccids();
}
Example #12
0
// -- Constructs the ``ccs'' array from run's ccids.
void
CCImage::make_ccs_from_ccids()
{
  int n;
  Run *pruns = runs;
  // Find maximal ccid
  int maxccid = -1;
  for (n=0; n<=runs.hbound(); n++)
    if (pruns[n].ccid > maxccid)
      maxccid = runs[n].ccid;
  GTArray<int> armap(0,maxccid);
  int *rmap = armap;
  // Renumber ccs 
  for (n=0; n<=maxccid; n++)
    armap[n] = -1;
  for (n=0; n<=runs.hbound(); n++)
    if (pruns[n].ccid >= 0)
      rmap[ pruns[n].ccid ] = 1;
  int nid = 0;
  for (n=0; n<=maxccid; n++)
    if (rmap[n] > 0)
      rmap[n] = nid++;
  // Adjust nregularccs (since ccs are renumbered)
  while (nregularccs>0 && rmap[nregularccs-1]<0)
    nregularccs -= 1;
  if (nregularccs>0)
    nregularccs = 1 + rmap[nregularccs-1];
  // Prepare cc descriptors
  ccs.resize(0,nid-1);
  for (n=0; n<nid; n++)
    ccs[n].nrun = 0;
  // Relabel runs
  for (n=0; n<=runs.hbound(); n++)
    {
      Run &run = pruns[n];
      if (run.ccid < 0) continue;  // runs with negative ccids are destroyed
      int oldccid = run.ccid;
      int newccid = rmap[oldccid];
      CC &cc = ccs[newccid];
      run.ccid = newccid;
      cc.nrun += 1;
    }
  // Compute positions for runs of cc
  int frun = 0;
  for (n=0; n<nid; n++) 
    {
      ccs[n].frun = rmap[n] = frun;
      frun += ccs[n].nrun;
    }
  // Copy runs
  GTArray<Run> rtmp;
  rtmp.steal(runs);
  Run *ptmp = rtmp;
  runs.resize(0,frun-1);
  pruns = runs;
  for (n=0; n<=rtmp.hbound(); n++)
    {
      int id = ptmp[n].ccid;
      if (id < 0) continue;
      int pos = rmap[id]++;
      pruns[pos] = ptmp[n];
    }
  // Finalize ccs
  for (n=0; n<nid; n++)
    {
      CC &cc = ccs[n];
      int npix = 0;
      runs.sort(cc.frun, cc.frun+cc.nrun-1);
      Run *run = &runs[cc.frun];
      int xmin = run->x1;
      int xmax = run->x2;
      int ymin = run->y;
      int ymax = run->y;
      cc.color = run->color;
      for (int i=0; i<cc.nrun; i++, run++)
        {
          if (run->x1 < xmin)  xmin = run->x1;
          if (run->x2 > xmax)  xmax = run->x2;
          if (run->y  < ymin)  ymin = run->y;
          if (run->y  > ymax)  ymax = run->y;
          npix += run->x2 - run->x1 + 1;
        }
      cc.npix = npix;
      cc.bb.xmin = xmin;
      cc.bb.ymin = ymin;
      cc.bb.xmax = xmax + 1;
      cc.bb.ymax = ymax + 1;
    }
}
Example #13
0
// -- Performs color connected component analysis
void
CCImage::make_ccids_by_analysis()
{
  // Sort runs
  runs.sort();
  // Single Pass Connected Component Analysis (with unodes)
  int n;
  int p=0;
  GTArray<int> umap;
  for (n=0; n<=runs.hbound(); n++)
    {
      int y = runs[n].y;
      int x1 = runs[n].x1 - 1;
      int x2 = runs[n].x2 + 1;
      int color = runs[n].color;
      int id = (umap.hbound() + 1);
      // iterate over previous line runs
      if (p>0) p--;
      for(;runs[p].y < y-1;p++);
      for(;(runs[p].y < y) && (runs[p].x1 <= x2);p++ )
        {
          if ( runs[p].x2 >= x1 )
            {
              if (runs[p].color == color)
                {
                  // previous run touches current run and has same color
                  int oid = runs[p].ccid;
                  while (umap[oid] < oid)
                    oid = umap[oid];
                  if ((int)id > umap.hbound()) {
                    id = oid;
                  } else if (id < oid) {
                    umap[oid] = id;
                  } else {
                    umap[id] = oid;
                    id = oid;
                  }
                  // freshen previous run id
                  runs[p].ccid = id;
                }
              // stop if previous run goes past current run
              if (runs[p].x2 >= x2)
                break;
            }
        }
      // create new entry in umap
      runs[n].ccid = id;
      if (id > umap.hbound())
        {
          umap.touch(id);
          umap[id] = id;
        }
    }
  // Update umap and ccid
  for (n=0; n<=runs.hbound(); n++)
    {
      Run &run = runs[n];
      int ccid = run.ccid;
      while (umap[ccid] < ccid)
        ccid = umap[ccid];
      umap[run.ccid] = ccid;
      run.ccid = ccid;
    }
}
//************************************
// Method:    CheckBonusAndLock
// FullName:  BSSlotsContainer::CheckBonusAndLock
// Access:    protected 
// Returns:   bool
// Qualifier: depends on locked(2rd round) or not lock(1st round), to check bonus symbols and play respin or freespin
// Parameter: bool haveReelsLocked   :
//************************************
bool BSSlotsContainer::CheckBonusSymbolsAndLock(bool haveReelsLocked)
{
	int bonusMiniCount = 0;

	if(haveReelsLocked)	
	{
		//means to get final locked reels, this is 2rd round, which some reels had been locked 
		//in this round, even 1 reel should be lock and play;
		bonusMiniCount = 0;	
	}
	else
	{
		//this is 1st round, only bonus count larger than bonusMiniCount, 
		//then lock and play respin;
		 bonusMiniCount = 2;
	}

	bool haveNewLockReel = false;
	GTArray<int> newLockReelIDs;	//store all new lock reels
	
	//check bonus symbol;
	int bonusSymbolID = m_pTicketGenerator->GetBonusSymbolID();
	//GTArray<int> slotSymbols = m_pTicketGenerator->GetSlotSymbols();

	for(int i = 0; i < m_slotsSymbols.Length(); i++)
	{
		int reelID = i % m_reelColumnCount;
		int slotSymbolValue = m_slotsSymbols[i];

		//find bonus symbol, then add this reelID into dictionary for later lock;
		if(slotSymbolValue == bonusSymbolID)
		{
			if(!m_lockReelsDict.KeyExists(reelID))	
			{
				newLockReelIDs.Add(reelID);
			}
		}
	}

	if(newLockReelIDs.Length() < bonusMiniCount)
		return false;

	//initialize all new lock reels
	for(int i = 0; i < newLockReelIDs.Length(); i++)
	{
		m_lockReelsDict.Add(newLockReelIDs[i], NULL);
	}

	//build new respin for every one new lock reels
	for(int i = 0; i < newLockReelIDs.Length(); i++)
	{
		int reelID = newLockReelIDs[i];
		GTGameObject* pGameObject = GTGameObjectManager::Inst()->CreateGameObject(NULL, CTEXT("respin1"), CTEXT("SlotGame/Respin.property"));
		if(pGameObject)
		{
			//add new lock reel into dictionary;
			m_lockReelsDict.Remove(reelID);
			m_lockReelsDict.Add(reelID, pGameObject);

			//get every reel position
			BSReelColumn* reelColum = m_reelColumns[reelID];
			GTPoint2 reelPos = reelColum->GetGameObjectPosition();		

			//set respin to there and play animation
			BSRespin* pRespin = (BSRespin*)(pGameObject->GetBehaviour(CTEXT("BSRespin")));
			if(pRespin)
			{			
				pRespin->SetGameObjectPosition(reelPos);

				GTLogManager::SLogFormatTrace("repsin lock: (%f, %f)  -> playing lock animtion", reelPos.x, reelPos.y);
				pRespin->PlayLockAnimation();
				haveNewLockReel = true;
			}
		}
	}
	return haveNewLockReel;
}
Example #15
0
// -- Merges small ccs and split large ccs
void
CCImage::merge_and_split_ccs()
{
  int ncc = ccs.size();
  int nruns = runs.size();
  int splitsize = largesize;
  if (ncc <= 0) return;
  // Grid of special components
  int gridwidth = (width+splitsize-1)/splitsize;
  nregularccs = ncc;
  // Set the correct ccids for the runs
  for (int ccid=0; ccid<ncc; ccid++)
    {
      CC* cc = &ccs[ccid];
      if (cc->nrun <= 0) continue;
      int ccheight = cc->bb.height();
      int ccwidth = cc->bb.width();
      if (ccheight<=smallsize && ccwidth<=smallsize)
        {
          int gridi = (cc->bb.ymin+cc->bb.ymax)/splitsize/2;
          int gridj = (cc->bb.xmin+cc->bb.xmax)/splitsize/2;
          int newccid = ncc + gridi*gridwidth + gridj;
          for(int runid=cc->frun; runid<cc->frun+cc->nrun; runid++)
            runs[runid].ccid = newccid;
        }
      else if (ccheight>=largesize || ccwidth>=largesize)
        {
          for(int runid=cc->frun; runid<cc->frun+cc->nrun; runid++)
            {
              Run& r = runs[runid];
              int y = r.y;
              int x_start = r.x1;
              int x_end = r.x2;
              int gridi = y/splitsize;
              int gridj_start = x_start/splitsize;
              int gridj_end = x_end/splitsize;
              int gridj_span = gridj_end-gridj_start;
              int newccid = ncc + gridi*gridwidth + gridj_start;
              if (! gridj_span)
                {
                  r.ccid = newccid;
                }
              else // gridj_span>0
                {
                  // truncate the current run 
                  r.ccid = newccid++;
                  int x = (gridj_start+1)*splitsize;
                  r.x2 = x-1;
                  runs.touch(nruns+gridj_span-1);
                  // append additional runs to the runs array
                  for(int gridj=gridj_start+1; gridj<gridj_end; gridj++)
                    {
                      Run& newrun = runs[nruns++];
                      newrun.y = y;
                      newrun.x1 = x;
                      x += splitsize;
                      newrun.x2 = x-1;
                      newrun.ccid = newccid++;
                    }
                  // append last run to the run array
                  Run& newrun = runs[nruns++];
                  newrun.y = y;
                  newrun.x1 = x;
                  newrun.x2 = x_end;
                  newrun.ccid = newccid++;                      
                }
            }
        }
    }
  // Recompute cc descriptors
  make_ccs_from_ccids();
}