Пример #1
0
bool CClient::Cmd_Skill_Tracking( WORD track_sel, bool bExec )
{
	ADDTOCALLSTACK("CClient::Cmd_Skill_Tracking");
	// look around for stuff.

	ASSERT(m_pChar);
	if ( track_sel == USHRT_MAX )
	{
		// Unlike others skills, Tracking is used during menu setup
		m_pChar->Skill_Cleanup();	// clean up current skill

		CMenuItem item[6];
		item[0].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_TITLE);

		item[1].m_id = ITEMID_TRACK_HORSE;
		item[1].m_color = 0;
		item[1].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_ANIMALS);
		item[2].m_id = ITEMID_TRACK_OGRE;
		item[2].m_color = 0;
		item[2].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_MONSTERS);
		item[3].m_id = ITEMID_TRACK_MAN;
		item[3].m_color = 0;
		item[3].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_NPCS);
		item[4].m_id = ITEMID_TRACK_WOMAN;
		item[4].m_color = 0;
		item[4].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_PLAYERS);

		m_tmMenu.m_Item[0] = 0;
		addItemMenu(CLIMODE_MENU_SKILL_TRACK_SETUP, item, 4);
		return true;
	}

	if ( track_sel > 0 ) // Not Cancelled
	{
		ASSERT(track_sel < COUNTOF(m_tmMenu.m_Item));
		if ( bExec )
		{
			// Tracking menu got us here. Start tracking the selected creature.
			m_pChar->SetTimeout(1 * TICK_PER_SEC);
			m_pChar->m_Act_Targ = static_cast<CGrayUID>(m_tmMenu.m_Item[track_sel]);
			m_pChar->Skill_Start(SKILL_TRACKING);
			return true;
		}

		static const NPCBRAIN_TYPE sm_Track_Brain[] =
		{
			NPCBRAIN_QTY,	// not used here
			NPCBRAIN_ANIMAL,
			NPCBRAIN_MONSTER,
			NPCBRAIN_HUMAN,
			NPCBRAIN_NONE	// players
		};

		if ( track_sel >= COUNTOF(sm_Track_Brain) )
			track_sel = COUNTOF(sm_Track_Brain) - 1;

		NPCBRAIN_TYPE track_type = sm_Track_Brain[track_sel];
		CMenuItem item[minimum(MAX_MENU_ITEMS, COUNTOF(m_tmMenu.m_Item))];
		size_t count = 0;

		item[0].m_sText = g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_SKILLMENU_TITLE);
		m_tmMenu.m_Item[0] = track_sel;

		CWorldSearch AreaChars(m_pChar->GetTopPoint(), m_pChar->Skill_GetBase(SKILL_TRACKING) / 10 + 10);
		for (;;)
		{
			CChar *pChar = AreaChars.GetChar();
			if ( !pChar )
				break;
			if ( pChar == m_pChar )
				continue;

			if ( pChar->GetNPCBrain() != track_type )
				continue;
			if ( pChar->IsStatFlag(STATF_DEAD) )	// can't track ghosts
				continue;

			if ( pChar->m_pPlayer )
			{
				// Prevent track hidden GMs
				if ( pChar->IsStatFlag(STATF_Insubstantial) && (pChar->GetPrivLevel() > GetPrivLevel()) )
					continue;

				// Check action difficulty when trying to track players
				int tracking = m_pChar->Skill_GetBase(SKILL_TRACKING);
				int detectHidden = m_pChar->Skill_GetBase(SKILL_DETECTINGHIDDEN);
				if ( (g_Cfg.m_iRacialFlags & RACIALF_ELF_DIFFTRACK) && pChar->IsElf() )
					tracking /= 2;			// elves are more difficult to track (Difficult to Track racial trait)

				int hiding = pChar->Skill_GetBase(SKILL_HIDING);
				int stealth = pChar->Skill_GetBase(SKILL_STEALTH);
				int divisor = maximum(hiding + stealth, 1);

				int chance;
				if ( g_Cfg.m_iFeatureSE & FEATURE_SE_UPDATE )
					chance = 50 * (tracking * 2 + detectHidden) / divisor;
				else
					chance = 50 * (tracking + detectHidden + 10 * Calc_GetRandVal(20)) / divisor;

				if ( Calc_GetRandVal(100) > chance )
					continue;
			}

			CCharBase *pCharDef = pChar->Char_GetDef();
			if ( !pCharDef )
				continue;

			count++;
			item[count].m_id = static_cast<WORD>(pCharDef->m_trackID);
			item[count].m_color = 0;
			item[count].m_sText = pChar->GetName();
			m_tmMenu.m_Item[count] = pChar->GetUID();

			if ( count >= COUNTOF(item) - 1 )
				break;
		}

		// Some credit for trying
		if ( count > 0 )
		{
			m_pChar->Skill_UseQuick(SKILL_TRACKING, 20 + Calc_GetRandLLVal(30));
			ASSERT(count < COUNTOF(item));
			addItemMenu(CLIMODE_MENU_SKILL_TRACK, item, count);
			return true;
		}
		else
		{
			// Tracking failed or cancelled
			m_pChar->Skill_UseQuick(SKILL_TRACKING, 10 + Calc_GetRandLLVal(30));

			static LPCTSTR const sm_Track_FailMsg[] =
			{
				g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_FAIL_ANIMAL),
				g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_FAIL_MONSTER),
				g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_FAIL_PEOPLE),
				g_Cfg.GetDefaultMsg(DEFMSG_TRACKING_FAIL_PEOPLE)
			};

			if ( sm_Track_FailMsg[track_sel - 1] )
				SysMessage(sm_Track_FailMsg[track_sel - 1]);
		}
	}
	return false;
}
Пример #2
0
bool CImportFile::ImportWSC( CScript & s, word wModeFlags )
{
	ADDTOCALLSTACK("CImportFile::ImportWSC");
	// This file is a WSC or UOX world script file.

	IMPFLAGS_TYPE mode = IMPFLAGS_NOTHING;
	CSString sName;
	CItem * pItem = NULL;
	CChar * pChar = NULL;

	while ( s.ReadTextLine(true))
	{
		if ( s.IsKeyHead( "SECTION WORLDITEM", 17 ))
		{
			CheckLast();
			mode = IMPFLAGS_ITEMS;
			continue;
		}
		else if ( s.IsKeyHead( "SECTION CHARACTER", 17 ))
		{
			CheckLast();
			mode = ( wModeFlags & IMPFLAGS_CHARS ) ? IMPFLAGS_CHARS : IMPFLAGS_NOTHING;
			continue;
		}
		else if ( s.GetKey()[0] == '{' )
		{
			CheckLast();
			continue;
		}
		else if ( s.GetKey()[0] == '}' )
		{
			CheckLast();
			mode = IMPFLAGS_NOTHING;
			continue;
		}
		else if ( mode == IMPFLAGS_NOTHING )
			continue;
		else if ( s.GetKey()[0] == '\\' )
			continue;

		// Parse the line.
		tchar* pKey = const_cast<tchar*>(strchr(s.GetKey(), ' '));
		lpctstr pArg = NULL;

		if (pKey != NULL)
		{
			*pKey++ = '\0';
			GETNONWHITESPACE(pKey);
			pArg = pKey;
		}
		else
		{
			pArg = "";
		}

		if ( s.IsKey("SERIAL" ))
		{
			if ( m_pCurSer != NULL )
				return false;

			dword dwSerial = ATOI( pArg );
			if ( dwSerial == UID_UNUSED )
			{
				DEBUG_ERR(( "Import:Bad serial number\n" ));
				break;
			}
			m_pCurSer = new CImportSer( dwSerial );
			m_ListSer.InsertHead( m_pCurSer );
			continue;
		}
		if ( s.IsKey("NAME" ))
		{
			sName = ( pArg[0] == '#' ) ? "" : pArg;
			if ( mode == IMPFLAGS_ITEMS )
				continue;
		}
		if ( m_pCurSer == NULL )
		{
			DEBUG_ERR(( "Import:No serial number\n" ));
			break;
		}

		if ( mode == IMPFLAGS_ITEMS )	// CItem.
		{
			if ( s.IsKey("ID" ))
			{
				if ( m_pCurObj != NULL )
					return false;
				pItem = CItem::CreateTemplate(static_cast<ITEMID_TYPE>(ATOI(pArg)));
				pItem->SetName( sName );
				m_pCurObj = pItem;
				m_pCurSer->m_pObj = pItem;
				continue;
			}

			if ( m_pCurObj == NULL )
			{
				DEBUG_ERR(( "Import:Bad Item Key '%s'\n", s.GetKey()));
				break;
			}
			else if ( s.IsKey("CONT" ))
			{
				m_pCurSer->m_dwContSer = ATOI(pArg);
			}
			else if ( s.IsKey("LAYER" ))
			{
				m_pCurSer->m_layer = static_cast<LAYER_TYPE>(ATOI(pArg));
				continue;
			}
			else if (pItem == NULL)
			{
				DEBUG_ERR(( "Import:Found '%s' before ID.\n", s.GetKey()));
				continue;
			}

			if ( s.IsKey("X" ))
			{
				CPointMap pt = pItem->GetUnkPoint();
				pt.m_x = (short)( ATOI(pArg) );
				pItem->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("Y" ))
			{
				CPointMap pt = pItem->GetUnkPoint();
				pt.m_y = (short)( ATOI(pArg) );
				pItem->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("Z" ))
			{
				CPointMap pt = pItem->GetUnkPoint();
				pt.m_z = (char)( ATOI(pArg) );
				pItem->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("COLOR" ))
			{
				pItem->SetHue( static_cast<HUE_TYPE>( ATOI(pArg) ) );
				continue;
			}
			else if ( s.IsKey("AMOUNT" ))
			{
				pItem->SetAmount( (word)ATOI(pArg) );
				continue;
			}
			else if ( s.IsKey("MOREX" ))
			{
				pItem->m_itNormal.m_morep.m_x = (short)(ATOI(pArg));
				continue;
			}
			else if ( s.IsKey("MOREY" ))
			{
				pItem->m_itNormal.m_morep.m_y = (short)(ATOI(pArg));
				continue;
			}
			else if ( s.IsKey("MOREZ" ))
			{
				pItem->m_itNormal.m_morep.m_z = (char)( ATOI(pArg) );
				continue;
			}
			else if ( s.IsKey("MORE" ))
			{
				pItem->m_itNormal.m_more1 = ATOI(pArg);
				continue;
			}
			else if ( s.IsKey("MORE2" ))
			{
				pItem->m_itNormal.m_more2 = ATOI(pArg);
				continue;
			}
			else if ( s.IsKey("DYEABLE" ))
			{
				//if ( ATOI(pArg))
				//	pItem->m_pDef->m_Can |= CAN_I_DYE;
				continue;
			}
			else if ( s.IsKey("ATT" ))
			{
				// pItem->m_pDef->m_attackBase = ATOI(pArg);
			}
			else if ( s.IsKey("TYPE" ))
			{
				// ??? translate the type field.
				//int i = ATOI(pArg);
			}
		}

		if ( mode == IMPFLAGS_CHARS )
		{
			if ( s.IsKey("NAME" ))
			{
				if ( m_pCurObj != NULL )
					return false;
				pChar = CChar::CreateBasic( CREID_MAN );
				pChar->SetName( sName );
				m_pCurObj = pChar;
				m_pCurSer->m_pObj = pChar;
				continue;
			}
			if ( m_pCurObj == NULL )
			{
				DEBUG_ERR(( "Import:Bad Item Key '%s'\n", s.GetKey()));
				break;
			}
			else if (pChar == NULL)
			{
				DEBUG_ERR(( "Import:Found '%s' before NAME.\n", s.GetKey()));
				continue;
			}

			if ( s.IsKey("X" ))
			{
				CPointMap pt = pChar->GetUnkPoint();
				pt.m_x = (short)(ATOI(pArg));
				pChar->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("Y" ))
			{
				CPointMap pt = pChar->GetUnkPoint();
				pt.m_y = (short)(ATOI(pArg));
				pChar->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("Z" ))
			{
				CPointMap pt = pChar->GetUnkPoint();
				pt.m_z = (char)(ATOI(pArg));
				pChar->SetUnkPoint(pt);
				continue;
			}
			else if ( s.IsKey("BODY" ))
			{
				pChar->SetID(static_cast<CREID_TYPE>(ATOI(pArg)));
				continue;
			}
			else if ( s.IsKey("SKIN" ))
			{
				pChar->SetHue( static_cast<HUE_TYPE>( ATOI(pArg) ));
				continue;
			}
			else if ( s.IsKey("DIR" ))
			{
				pChar->m_dirFace = static_cast<DIR_TYPE>(ATOI(pArg));
				if ( pChar->m_dirFace < 0 || pChar->m_dirFace >= DIR_QTY )
					pChar->m_dirFace = DIR_SE;
				continue;
			}
			else if ( s.IsKey("XBODY" ))
			{
				pChar->m_prev_id = static_cast<CREID_TYPE>(ATOI(pArg));
				continue;
			}
			else if ( s.IsKey("XSKIN" ))
			{
				pChar->m_prev_Hue = static_cast<HUE_TYPE>( ATOI(pArg) );
				continue;
			}
			else if ( s.IsKey("FONT" ))
			{
				pChar->m_fonttype = static_cast<FONT_TYPE>(ATOI(pArg));
				continue;
			}
			else if ( s.IsKey("KARMA" ))
			{
				pChar->Stat_SetBase(STAT_KARMA, (short)(ATOI(pArg)));
				continue;
			}
			else if ( s.IsKey("FAME" ))
			{
				pChar->Stat_SetBase(STAT_FAME, (short)(ATOI(pArg)));
				continue;
			}
			else if ( s.IsKey("TITLE" ))
			{
				pChar->m_sTitle = pArg;
				continue;
			}
			else if ( s.IsKey("STRENGTH" ))
			{
				pChar->Stat_SetBase(STAT_STR, (short)(ATOI(pArg)));
			}
			else if ( s.IsKey("DEXTERITY" ))
			{
				pChar->Stat_SetBase(STAT_DEX, (short)(ATOI(pArg)));
			}
			else if ( s.IsKey("INTELLIGENCE" ))
			{
				pChar->Stat_SetBase(STAT_INT, (short)(ATOI(pArg)));
			}
			else if ( s.IsKey("HITPOINTS" ))
			{
				pChar->Stat_SetVal(STAT_STR,(short)(ATOI(pArg)));
			}
			else if ( s.IsKey("STAMINA" ))
			{
				pChar->Stat_SetVal(STAT_DEX,(short)(ATOI(pArg)));
			}
			else if ( s.IsKey( "MANA" ))
			{
				pChar->Stat_SetVal(STAT_INT,(short)(ATOI(pArg)));
			}
			else if ( s.IsKeyHead( "SKILL", 5 ))
			{
				SKILL_TYPE skill = static_cast<SKILL_TYPE>(ATOI( &(s.GetKey()[5])));
				if ( pChar->IsSkillBase(skill) && g_Cfg.m_SkillIndexDefs.IsValidIndex(skill) )
				{
					pChar->Skill_SetBase( skill, ATOI(pArg));
				}
			}
			else if ( s.IsKey("ACCOUNT" ))
			{
				// What if the account does not exist ?
				pChar->SetPlayerAccount( pArg );
			}
			else if ( s.IsKey("KILLS" ) && pChar->m_pPlayer )
			{
				pChar->m_pPlayer->m_wMurders = (word)(ATOI(pArg));
			}
			else if ( s.IsKey("NPCAITYPE" ))
			{
				// Convert to proper NPC type.
				int i = ATOI( pArg );
				switch ( i )
				{
				case 0x01:	pChar->SetNPCBrain( NPCBRAIN_HEALER ); break;
				case 0x02:	pChar->SetNPCBrain( NPCBRAIN_MONSTER ); break;
				case 0x04:
				case 0x40:	pChar->SetNPCBrain( NPCBRAIN_GUARD ); break;
				case 0x08:	pChar->SetNPCBrain( NPCBRAIN_BANKER ); break;
				default:	pChar->SetNPCBrain( pChar->GetNPCBrain( false )); break;
				}
			}
			continue;
		}
	}
	return true;
}