示例#1
0
	void CShopManager::OnMessage( CMessage *pMsg )
	{
		if( !GetInst( CConfiger ).IsEnable() )
		{
			PutoutLog( LOG_FILE, LT_WARNING, "Disabled, but received client messages." );
			return ;
		}

		unsigned char type = pMsg->GetByte();
		CGUID npcID;
		long lShopID = 0;
		pMsg->GetGUID( npcID );
		lShopID = pMsg->GetLong();
		// make sure all the params are valid.
		int ret = IsValidOper( this, pMsg, npcID, lShopID ); 
		if( ret < 0 )
		{
			if( ret == -1 )
			{
				CancelTrading( pMsg->GetPlayer() );
				NotifyFatalError( pMsg->GetPlayer(), FEN_INVALID_OPER );
			}
			return ;
		}

		CShop *pShop = GetShop( lShopID );
		switch( type )
		{
		case C2S_PLAYER_BUY:
			pShop->OnPlayerBuyMsg( pMsg, npcID );	
			break;

		case C2S_PLAYER_SELL:
			pShop->OnPlayerSellMsg( pMsg, npcID );
			break;

		case C2S_PRICE_CHANGED_RES:
			pShop->OnPlayerConformSellMsg( pMsg, npcID );
			break;

		case C2S_PLAYER_CLOSE:
			pShop->OnPlayerCloseMsg( pMsg );
			break;

		default:
			CPlayer *pPlayer = pMsg->GetPlayer();
			PutoutLog( LOG_FILE, LT_ERROR, "Unknown oper type from client [%s].", 
				pPlayer->GetName() );
			break;
		}
	}
	bool CShopManager::OpenShopForBuy( long id, const CGUID &playerID, const CGUID &npcID )
	{
		CShop *pShop = GetShop( id );
		if( pShop == NULL )
		{
			return false;
		}
		
		CMessage msg( MSG_S2C_FBUSINESS_OPER );
		msg.Add( (BYTE) S2C_SELL_PAGE );
		msg.Add( npcID );
		msg.Add( id );
		DBWriteSet db;
		msg.GetDBWriteSet( db );
		pShop->EncodeSellGoodsList( db );
		msg.SendToPlayer( playerID, false );
		return true;
	}
	bool CShopManager::CreateShop( long id, const char *npcOrigName, const SellGoodsListT &goods_list )
	{
		CShop *pShop = GetShop( id );
		if( pShop == NULL )
		{
			CShop::tagParam param;
			param.id = id;
			param.npcOrigName = npcOrigName;
			param.goods_list = &goods_list;
			pShop = OBJ_CREATE_PVOID( CShop, (void*)(&param) );
			m_ShopTable.insert( std::make_pair( id, pShop ) );
			return true;
		}
		else
		{
			pShop->SetSellList( goods_list );
			return false;
		}
	}
void Chapter::Do(Character& character) const
{
  if (m_verbose) { std::clog << __func__ << std::endl; }
  Helper h;

  assert(m_observer);
  character.SetObserver(m_observer);

  if (m_verbose) { std::clog << "The first text comes now" << std::endl; }

  ShowText("\n");

  #ifndef NDEBUG
  ShowText("CHAPTER " + h.ToStr(GetChapterNumber()) + "\n");
  #endif

  //Display the text line by line
  ShowText(m_text + "\n");

  if (m_verbose) { std::clog << "The first text has been" << std::endl; }


  if (GetType() == ChapterType::game_lost)
  {
    m_game_lost_chapter.Do(character);
    assert(character.IsDead());
    return;
  }
  else if (GetType() == ChapterType::game_won)
  {
    ShowText("\n");
    m_game_won_chapter.Do(character);
    ShowText("\n");
    return;
  }
  else if (GetType() == ChapterType::play_dice)
  {
    m_dice_game_chapter.Do(character);
    m_consequence.Apply(character);
  }
  else if (GetType() == ChapterType::play_ball)
  {
    m_ball_game_chapter.Do(character);
    m_consequence.Apply(character);
  }
  else if (GetType() == ChapterType::play_pill)
  {
    m_pill_game_chapter.Do(character);
    if (character.IsDead()) return;
    m_consequence.Apply(character);
  }
  //Options
  else if (!GetOptions().GetOptions().empty())
  {
    if (GetOptions().GetValidOptions(character).empty())
    {
      std::cerr
        << "ERROR: no valid options in chapter " << character.GetCurrentChapter()
        << std::endl
        << "Options:\n"
      ;
      assert(GetOptions().GetOptions().size() == 2);
    }
    while (1)
    {
      if (m_verbose) { std::clog << "Let the use choose a valid option" << std::endl; }

      auto options = GetOptions().GetValidOptions(character);

      //If there are options, add (1) showing inventory (2) eating provision (3) drinking potion
      if (options.size() > 1)
      {
        //Add to show the inventory
        options.push_back(CreateShowInventoryOption());
        if (character.GetProvisions() > 0) { options.push_back(CreateEatProvisionOption()); }
        if (character.HasPotion()) { options.push_back(CreateDrinkPotionOption()); }
      }

      if (m_verbose) { std::clog << "Do the request" << std::endl; }

      assert(m_observer);
      const auto chosen = m_observer->RequestOption(options);

      if (m_verbose) { std::clog << "Done the request" << std::endl; }

      ShowText("\n");
      if (chosen.GetConsequence().GetType() == ConsequenceType::show_inventory)
      {
        //Showing the inventory is trivial
        this->ShowText(character.ShowInventory());
        continue;
      }
      if (chosen.GetConsequence().GetType() == ConsequenceType::eat_provision)
      {
        character.ChangeProvisions(-1);
        character.ChangeCondition(4);
        continue;
      }
      if (chosen.GetConsequence().GetType() == ConsequenceType::drink_potion)
      {
        character.DrinkPotion();
        continue;
      }

      chosen.DoChoose(character);
      assert(m_consequence.GetNextChapter() == -1);

      //Only apply these consequences once
      m_consequence.Apply(character);
      break;
    }
  }
  else if (GetType() == ChapterType::fight)
  {
    const int n_chapters_before{static_cast<int>(character.GetChapters().size())};
    m_fighting_chapter.Do(character);
    if (character.IsDead())
    {
      m_game_lost_chapter.Do(character);
      return;
    }

    assert(m_consequence.GetNextChapter() > 0);
    const int n_chapters_after{static_cast<int>(character.GetChapters().size())};
    if (n_chapters_after != n_chapters_before)
    {
      //Player has escaped
      //Check that there are no other consequences that need to be applied
      assert(m_consequence.GetChangeArrows() == 0);
      assert(m_consequence.GetChangeCondition() == 0);
      assert(m_consequence.GetChangeGold() == 0);
      assert(m_consequence.GetChangeLuck() == 0);
      assert(m_consequence.GetChangeProvisions() == 0);
      assert(m_consequence.GetChangeSkill() == 0);
      assert(m_consequence.GetItemsToAdd().empty());
      assert(m_consequence.GetItemsToRemove().empty());
    }
    else
    {
      m_consequence.Apply(character);
    }
  }
  else if (GetType() == ChapterType::test_your_luck)
  {
    GetLuck().Do(character);
  }
  else if (GetType() == ChapterType::test_your_skill)
  {
    GetSkill().Do(character);
  }
  else if (GetType() == ChapterType::shop)
  {
    GetShop().Do(character);
    m_consequence.Apply(character);
  }
  else if (GetType() == ChapterType::pawn_shop)
  {
    GetPawnShop().Do(character);
    m_consequence.Apply(character);
  }
  else if (GetType() == ChapterType::normal)
  {
    //Nothing
    m_consequence.Apply(character);
  }
  else
  {
    assert(!"Should not get here");
  }

  if (character.IsDead())
  {
    m_game_lost_chapter.Do(character);
    return;
  }

  ShowText(m_bye_text);
}