void Inventory::load(JsonBox::Value& v, EntityManager* mgr)
{
	for(auto item : v.getArray())
	{
		std::string itemId = item.getArray()[0].getString();
		int quantity = item.getArray()[1].getInteger();
		this->items.push_back(std::make_pair(mgr->getEntity<T>(itemId), quantity));
	}
}
void unserialize(const JsonBox::Value & o, std::unordered_set<T> & v)
{
	const JsonBox::Array & a = o.getArray();
	for(u32 i = 0; i < a.size(); ++i)
	{
		T elem;
		unserialize(a[i], elem);
		v.insert(elem);
	}
}
void unserialize(const JsonBox::Value & o, std::vector<T> & v)
{
	const JsonBox::Array & a = o.getArray();
	v.resize(a.size());
	for(u32 i = 0; i < a.size(); ++i)
	{
		const JsonBox::Value & jv = a[i];
		unserialize(jv, v[i]);
	}
}
inline void unserialize(const JsonBox::Value & o, sf::Transform & t)
{
	assert(o.isArray());

	const JsonBox::Array & a = o.getArray();

	t = sf::Transform(
		a[0].getDouble(), a[4].getDouble(), a[12].getDouble(),
		a[1].getDouble(), a[5].getDouble(), a[13].getDouble(),
		a[3].getDouble(), a[7].getDouble(), a[15].getDouble()
	);
}
		JsonBox::Array SpellChecker::Check(const std::string &text)
		{
			JsonBox::Value result;

			std::wstring wide_text = Helpers::String::strtowstr(text);
			std::string utf8_text = Helpers::String::ToUtf8(wide_text);

			std::string encoded_text = Helpers::String::UriEncode(utf8_text);

			std::stringstream url;
			url << m_spell_check_url << encoded_text;

			std::stringstream data;
			Helpers::Files::DownloadFile(url.str(), data);

			std::string answer = data.str();

			result.loadFromString(answer);

			return result.getArray();
		}
void
MCBackpack::loadEffectiveItems()
{
    MCItemManager *itemManager = MCItemManager::sharedItemManager();
    CCUserDefault *userDefault = CCUserDefault::sharedUserDefault();
    string data = userDefault->getStringForKey(kMCEffectiveItemsKey, "");
    
    if (MCGameState::sharedGameState()->isSaveFileExists()
        && data.size() > 0) {
#if MC_DEBUG_SAVEDATA == 1
        const char *output = data.c_str();
#else
        const char *input = data.c_str();
        char *output;
        mc_size_t len = strlen(input);
        MCBase64Decode((mc_byte_t *) input, len, (mc_byte_t **) &output);
#endif
        JsonBox::Value v;
        v.loadFromString(output);
        
        JsonBox::Array effectiveItems = v.getArray();
        
        healthPotion_->count = effectiveItems.at(0).getInt();
        physicalPotion_->count = effectiveItems.at(1).getInt();
        fireballTrapWide_->count = effectiveItems.at(2).getInt();
        fireballTrapDamage_->count = effectiveItems.at(3).getInt();
        curseTrapWide_->count = effectiveItems.at(4).getInt();
        curseTrapDamage_->count = effectiveItems.at(5).getInt();
        paralysisTrapWide_->count = effectiveItems.at(6).getInt();
        paralysisTrapDamage_->count = effectiveItems.at(7).getInt();
        fogTrapWide_->count = effectiveItems.at(8).getInt();
        fogTrapDamage_->count = effectiveItems.at(9).getInt();
        flashTrapWide_->count = effectiveItems.at(10).getInt();
        flashTrapDamage_->count = effectiveItems.at(11).getInt();
#if MC_DEBUG_SAVEDATA != 1
        delete []output;
#endif
    } else {
        healthPotion_->count = 0;
        physicalPotion_->count = 0;
        fireballTrapWide_->count = 0;
        fireballTrapDamage_->count = 0;
        curseTrapWide_->count = 0;
        curseTrapDamage_->count = 0;
        paralysisTrapWide_->count = 0;
        paralysisTrapDamage_->count = 0;
        fogTrapWide_->count = 0;
        fogTrapDamage_->count = 0;
        flashTrapWide_->count = 0;
        flashTrapDamage_->count = 0;
    }
    
    /* load items */
    healthPotion_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCHealthPotion]);
    healthPotion_->item->retain();
    physicalPotion_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCPhysicalPotion]);
    physicalPotion_->item->retain();
    fireballTrapWide_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFireballWide]);
    fireballTrapWide_->item->retain();
    fireballTrapDamage_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFireballDamage]);
    fireballTrapDamage_->item->retain();
    curseTrapWide_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCCurseWide]);
    curseTrapWide_->item->retain();
    curseTrapDamage_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCCurseDamage]);
    curseTrapDamage_->item->retain();
    paralysisTrapWide_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCParalysisWide]);
    paralysisTrapWide_->item->retain();
    paralysisTrapDamage_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCParalysisDamage]);
    paralysisTrapDamage_->item->retain();
    fogTrapWide_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFogWide]);
    fogTrapWide_->item->retain();
    fogTrapDamage_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFogDamage]);
    fogTrapDamage_->item->retain();
    flashTrapWide_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFlashWide]);
    flashTrapWide_->item->retain();
    flashTrapDamage_->item = itemManager->effectiveItemForObjectId(effectiveItemsOID[kMCFlashDamage]);
    flashTrapDamage_->item->retain();
}
void RPGBattleMenu::onMenu(cocos2d::CCObject *pObject)
{
    CCMenuItem *menuItem = (CCMenuItem*)pObject;
    SimpleAudioEngine::sharedEngine()->playEffect("audio_effect_btn.wav");

    switch (menuItem->getTag())
    {
        case kRPGBattleMenuTagSkill:
        {
            CCLog("技能");
            
            this->hideMenu();
            
            this->m_selectedMenuTag = kRPGBattleMenuTagSkill;
            
            CCMenuItemSprite *menuCancel = CCMenuItemSprite::create(CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), this, menu_selector(RPGBattleMenu::onMenu));
            menuCancel->setPosition(ccp(43, 596));
            menuCancel->setTag(kRPGBattleMenuTagCancel);
            menuCancel->setScale(0.75);
            this->addChild(menuCancel);
            
            CCTMXTiledMap *selectLayer = CCTMXTiledMap::create(CCString::createWithFormat("battle_select_%s.tmx", CCUserDefault::sharedUserDefault()->getStringForKey(GAME_STYLE).c_str())->getCString());
            selectLayer->setPosition(ccp((CCDirector::sharedDirector()->getWinSize().width - selectLayer->getContentSize().width) / 2, (CCDirector::sharedDirector()->getWinSize().height - selectLayer->getContentSize().height) / 2));
            selectLayer->setTag(kRPGBattleSceneLayerTagSkillSelectDialog);
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->addChild(selectLayer);            
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(true);
            
            //显示title和分隔线
            addLab(selectLayer, 199, (CCString*)this->m_stringList->objectForKey("skill_title"), 25, ccp(310, 285));
            CCLabelTTF *titleLab = (CCLabelTTF*)selectLayer->getChildByTag(199);
            titleLab->setFontFillColor(ccc3(144, 144, 144));
            
            CCSprite *separate = CCSprite::createWithSpriteFrameName("separate.png");
            separate->setPosition(ccp(selectLayer->getContentSize().width / 2, 260));
            separate->setScaleX(0.65);
            separate->setTag(198);
            selectLayer->addChild(separate);
            
            //加载技能数据
            CCTableView *tableView = (CCTableView*)selectLayer->getChildByTag(197);
            if(!tableView)
            {
                tableView = CCTableView::create(this, ccp(selectLayer->getContentSize().width, selectLayer->getContentSize().height - 80));
                tableView->setDirection(kCCScrollViewDirectionVertical);
                tableView->setPosition(CCSizeZero);
                tableView->setDelegate(this);
                tableView->setVerticalFillOrder(kCCTableViewFillTopDown);
                tableView->setTag(197);
                selectLayer->addChild(tableView);
                
            }
            
            this->m_tableItems->removeAllObjects();

            string wq = "";
            JsonBox::Value json;
            json.loadFromString(this->m_playerData->m_skill.c_str());
            JsonBox::Array jsonArr = json.getArray();
            for (int i = 0; i < jsonArr.size(); i++)
            {
                char* str = (char*)malloc(10 * sizeof(char));
                OzgCCUtility::itoa(jsonArr[i].getInt(), str);
                wq.append(str);
                
                if(i + 1 < jsonArr.size())
                    wq.append(", ");
                
                free(str);
            }
            if((int)wq.length() > 0)
            {
                CppSQLite3Query query = this->m_db->execQuery(CCString::createWithFormat(SKILL_QUERY, wq.c_str())->getCString());
                while(!query.eof())
                {
                    RPGSkillBtnData *skill = RPGSkillBtnData::create();
                    skill->m_dataId = query.getIntField("id");
                    skill->m_name = query.getStringField("name_cns");
                    skill->m_MP = query.getIntField("mp");
                    skill->m_skillAttack = query.getIntField("skill_attack");
                    skill->m_type = query.getIntField("type");
                    skill->m_attr = query.getIntField("attr");
                    skill->m_enabled = true;
                    
                    //不能使用技能的情况
                    if(this->m_playerData->m_MP <= 0 || this->m_playerData->m_HP <= 0)
                        skill->m_enabled = false;
                    else if(this->m_playerData->m_MP < skill->m_MP)
                        skill->m_enabled = false;
                    
                    this->m_tableItems->addObject(skill);
                    
                    query.nextRow();
                }
                query.finalize();
            }
            
            tableView->reloadData();
            //加载技能数据 end
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
        }
            break;
        case kRPGBattleMenuTagItems:
        {
            CCLog("道具");
            
            this->hideMenu();
            
            this->m_selectedMenuTag = kRPGBattleMenuTagItems;
            
            CCMenuItemSprite *menuCancel = CCMenuItemSprite::create(CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), this, menu_selector(RPGBattleMenu::onMenu));
            menuCancel->setPosition(ccp(43, 596));
            menuCancel->setTag(kRPGBattleMenuTagCancel);
            menuCancel->setScale(0.75);
            this->addChild(menuCancel);
            
            CCTMXTiledMap *selectLayer = CCTMXTiledMap::create(CCString::createWithFormat("battle_select_%s.tmx", CCUserDefault::sharedUserDefault()->getStringForKey(GAME_STYLE).c_str())->getCString());
            selectLayer->setPosition(ccp((CCDirector::sharedDirector()->getWinSize().width - selectLayer->getContentSize().width) / 2, (CCDirector::sharedDirector()->getWinSize().height - selectLayer->getContentSize().height) / 2));
            selectLayer->setTag(kRPGBattleSceneLayerTagItemsSelectDialog);
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->addChild(selectLayer);
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(true);
            
            //显示title和分隔线
            addLab(selectLayer, 199, (CCString*)this->m_stringList->objectForKey("items_title"), 25, ccp(310, 285));
            CCLabelTTF *titleLab = (CCLabelTTF*)selectLayer->getChildByTag(199);
            titleLab->setFontFillColor(ccc3(144, 144, 144));
            
            CCSprite *separate = CCSprite::createWithSpriteFrameName("separate.png");
            separate->setPosition(ccp(selectLayer->getContentSize().width / 2, 260));
            separate->setScaleX(0.65);
            separate->setTag(198);
            selectLayer->addChild(separate);
            
            //加载道具数据
            CCTableView *tableView = (CCTableView*)selectLayer->getChildByTag(197);
            if(!tableView)
            {
                tableView = CCTableView::create(this, ccp(selectLayer->getContentSize().width, selectLayer->getContentSize().height - 80));
                tableView->setDirection(kCCScrollViewDirectionVertical);
                tableView->setPosition(CCSizeZero);
                tableView->setDelegate(this);
                tableView->setVerticalFillOrder(kCCTableViewFillTopDown);
                tableView->setTag(197);
                selectLayer->addChild(tableView);
            }
            
            this->m_tableItems->removeAllObjects();
            
            CCArray *existingItems = ((RPGBattleSceneLayer*)this->m_parentNode)->m_existingItems;
            
            for (int i = 0; i < existingItems->count(); i++)
                this->m_tableItems->addObject(existingItems->objectAtIndex(i));
            
            tableView->reloadData();
            //加载道具数据 end
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
        }
            break;
        case kRPGBattleMenuTagEscape:
        {
//            CCLog("逃跑");
            
            float success = CCRANDOM_0_1();
            if(success >= 0.0 && success <= 0.5)
            {
//                CCLog("逃跑成功");
                
                this->setEnabled(false);
                this->removeFromParentAndCleanup(true);
                
                ((RPGBattleSceneLayer*)this->m_parentNode)->goToMap();
            }
            else
            {
                ((RPGBattleSceneLayer*)this->m_parentNode)->showMsg((CCString*)this->m_stringList->objectForKey("escape_fail"));
                
                //重置进度条
                this->m_playerData->m_progress = 0.0;
                CCProgressTimer *battleProgress = (CCProgressTimer*)this->m_parentNode->getChildByTag(kRPGBattleSceneLayerTagPlayerProgress + this->m_playerData->m_dataId);
                battleProgress->setPercentage(this->m_playerData->m_progress);
                
                ((RPGBattleSceneLayer*)this->m_parentNode)->scheduleUpdate();
                
                CCTMXTiledMap *bgLayer = (CCTMXTiledMap*)this->m_parentNode->getChildByTag(kRPGBattleMenuTagBg);
                bgLayer->removeFromParentAndCleanup(true);
                this->removeFromParentAndCleanup(true);
            }
            
        }
            break;
        case kRPGBattleMenuTagCancel:
        {
//            CCLog("取消");
            this->showMenu();
            
            CCMenuItem *menuCancel = (CCMenuItem*)this->getChildByTag(kRPGBattleMenuTagCancel);
            menuCancel->removeFromParentAndCleanup(true);
            
            switch (this->m_selectedMenuTag)
            {
                case kRPGBattleMenuTagAttack:
                    CCLog("取消攻击");
                    ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
                    ((RPGBattleSceneLayer*)this->m_parentNode)->cancelAllSelected();
                    
                    break;
                case kRPGBattleMenuTagSkill:
                    CCLog("取消技能列表");
                    
                    if(((RPGBattleSceneLayer*)this->m_parentNode)->getChildByTag(kRPGBattleSceneLayerTagSkillSelectDialog))
                        ((RPGBattleSceneLayer*)this->m_parentNode)->removeChildByTag(kRPGBattleSceneLayerTagSkillSelectDialog, true);
                    
                    ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
                    ((RPGBattleSceneLayer*)this->m_parentNode)->cancelAllSelected();
                    
                    break;
                case kRPGBattleMenuTagItems:
                    CCLog("取消道具列表");
                    
                    if(((RPGBattleSceneLayer*)this->m_parentNode)->getChildByTag(kRPGBattleSceneLayerTagItemsSelectDialog))
                        ((RPGBattleSceneLayer*)this->m_parentNode)->removeChildByTag(kRPGBattleSceneLayerTagItemsSelectDialog, true);
                    
                    ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
                    ((RPGBattleSceneLayer*)this->m_parentNode)->cancelAllSelected();
                    
                    break;
//                default:
//                    break;
            }
            
        }
            break;
        case kRPGBattleMenuTagCancel2:
        {
            //这个选择了一个技能或道具后,到了选择目标对象的一步,使用到的取消按钮
            
            CCMenuItemSprite *menuCancel = (CCMenuItemSprite*)this->getChildByTag(kRPGBattleMenuTagCancel);
            menuCancel->setVisible(true);
            
            CCMenuItemSprite *menuCancel2 = (CCMenuItemSprite*)this->getChildByTag(kRPGBattleMenuTagCancel2);
            menuCancel2->removeFromParentAndCleanup(true);
            
            if(this->m_parentNode->getChildByTag(kRPGBattleSceneLayerTagItemsSelectDialog))
                this->m_parentNode->getChildByTag(kRPGBattleSceneLayerTagItemsSelectDialog)->setVisible(true);
            
            if(this->m_parentNode->getChildByTag(kRPGBattleSceneLayerTagSkillSelectDialog))
                this->m_parentNode->getChildByTag(kRPGBattleSceneLayerTagSkillSelectDialog)->setVisible(true);
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(false);
            ((RPGBattleSceneLayer*)this->m_parentNode)->cancelAllSelected();
        }
            break;
        default:
        {
            CCLog("攻击");
            this->hideMenu();
            
            this->m_selectedMenuTag = kRPGBattleMenuTagAttack;
            
            CCMenuItemSprite *menuCancel = CCMenuItemSprite::create(CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), CCSprite::createWithSpriteFrameName("commons_btn_back_04.png"), this, menu_selector(RPGBattleMenu::onMenu));
            menuCancel->setPosition(ccp(43, 596));
            menuCancel->setTag(kRPGBattleMenuTagCancel);
            menuCancel->setScale(0.75);
            this->addChild(menuCancel);
            
            ((RPGBattleSceneLayer*)this->m_parentNode)->enabledTouched(true);
            
        }
            break;
    }
    
}