示例#1
0
bool CItemMulti::Ship_SetMoveDir( DIR_TYPE dir )
{
	// Set the direction we will move next time we get a tick.
	int iSpeed = 1;
	if ( m_itShip.m_DirMove == dir && m_itShip.m_fSail )
	{
		if ( m_itShip.m_DirFace == m_itShip.m_DirMove &&
			m_itShip.m_fSail == 1 )
		{
			iSpeed = 2;
		}
		else return( false );
	}

	if ( ! IsAttr(ATTR_MAGIC ))	// make sound.
	{
		if ( ! Calc_GetRandVal(10))
		{
			Sound( Calc_GetRandVal(2)?0x12:0x13 );
		}
	}

	m_itShip.m_DirMove = dir;
	m_itShip.m_fSail = iSpeed;
	GetTopSector()->SetSectorWakeStatus();	// may get here b4 my client does.
	SetTimeout(( m_itShip.m_fSail == 1 ) ? 1*TICK_PER_SEC : (TICK_PER_SEC/5));
	return( true );
}
示例#2
0
bool CItemMulti::Ship_CanMoveTo( const CPointMap & pt ) const
{
	// Can we move to the new location ? all water type ?
	if ( IsAttr(ATTR_MAGIC ))
		return( true );

	// Run into other ships ? ignore my own region.
/*
	const CRegionBase * pRegionOther = pt.GetRegion( REGION_TYPE_MULTI );
	if ( pRegionOther == m_pRegion )
		pRegionOther = NULL;
*/
	WORD wBlockFlags = CAN_I_WATER;
	signed char z = g_World.GetHeightPoint( pt, wBlockFlags, true );
	if ( ! ( wBlockFlags & CAN_I_WATER ))
	{
		return( false );
	}

	return( true );
}
示例#3
0
CCharBase * CItem::Spawn_SetTrackID()
{
	if ( ! IsType(IT_SPAWN_CHAR))
		return NULL;
	CCharBase * pCharDef = NULL;
	RESOURCE_ID_BASE rid = m_itSpawnChar.m_CharID;

	if ( rid.GetResType() == RES_CHARDEF )
	{
		CREID_TYPE id = (CREID_TYPE) rid.GetResIndex();
		pCharDef = CCharBase::FindCharBase( id );
	}
	if ( pCharDef )
		SetAttr( ATTR_INVIS );
	if ( IsAttr(ATTR_INVIS))	// They must want it to look like this.
	{
		SetDispID( ( pCharDef == NULL ) ? ITEMID_TRACK_WISP : pCharDef->m_trackID );
		if ( GetHue() == 0 )
			SetHue( HUE_RED_DARK );	// Indicate to GM's that it is invis.
	}
	return( pCharDef );
}
示例#4
0
bool CItemVendable::IsValidSaleItem( bool fBuyFromVendor ) const
{
	ADDTOCALLSTACK("CItemVendable::IsValidSaleItem");
	// Can this individual item be sold or bought ?
	if ( ! IsMovableType())
	{
		if ( fBuyFromVendor )
		{
			DEBUG_ERR(( "Vendor uid=0%lx selling unmovable item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName()));
		}
		return( false );
	}
	if ( ! fBuyFromVendor )
	{
		// cannot sell these to a vendor.
		if ( IsAttr(ATTR_NEWBIE|ATTR_MOVE_NEVER))
			return( false );	// spellbooks !
	}
	if ( IsType(IT_COIN))
		return( false );
	return( true );
}
示例#5
0
bool CItemMulti::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script
{
	LOCKDATA;
	EXC_TRY(("r_Verb('%s %s',%x)", s.GetKey(), s.GetArgStr(), pSrc));
	// Speaking in this ships region.
	// return: true = command for the ship.

	//"One (direction*)", " (Direction*), one" Moves ship one tile in desired direction and stops.
	//"Slow (direction*)" Moves ship slowly in desired direction (see below for possible directions).

	int iCmd = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF( sm_szVerbKeys )-1 );
	if ( iCmd < 0 )
	{
		return( CItem::r_Verb( s, pSrc ));
	}

	if ( ! pSrc )
		return( false );

	switch ( iCmd )
	{
	case SHV_MULTICREATE:
		{
			CGrayUID	uid( s.GetArgVal() );
			CChar *	pSrc	= uid.CharFind();
			Multi_Create( pSrc, 0 );
		}
		return true;
	}

	if ( IsAttr(ATTR_MOVE_NEVER) || ! IsTopLevel() )
		return false;

	CChar * pChar = pSrc->GetChar();

	// Only key holders can command the ship ???
	// if ( pChar && pChar->ContentFindKeyFor( pItem ))

	// Find the tiller man object.
	CItem * pTiller = Multi_GetSign();
	ASSERT( pTiller );

	// Get current facing dir.
	DIR_TYPE DirFace = sm_Ship_FaceDir[ Ship_GetFaceOffset() ];
	int DirMoveChange;
	LPCTSTR pszSpeak = NULL;

	switch ( iCmd )
	{
	case SHV_SHIPSTOP:
		// "Furl sail"
		// "Stop" Stops current ship movement.
		if ( ! m_itShip.m_fSail )
			return( false );
		Ship_Stop();
		break;
	case SHV_SHIPFACE:
		// Face this direction. do not change the direction of movement.
		if ( ! s.HasArgs())
			return( false );
		return Ship_Face( GetDirStr( s.GetArgStr()));

	case SHV_SHIPMOVE:
		// Move one space in this direction.
		// Does NOT protect against exploits !
		if ( ! s.HasArgs())
			return( false );
		m_itShip.m_DirMove = GetDirStr( s.GetArgStr());
		return Ship_Move( (DIR_TYPE) m_itShip.m_DirMove );

	case SHV_SHIPGATE:
		// Move the whole ship and contents to another place.
		if ( ! s.HasArgs())
			return( false );
		{
			CPointMap ptdelta = g_Cfg.GetRegionPoint( s.GetArgStr());
			if ( ! ptdelta.IsValidPoint())
				return( false );
			ptdelta -= GetTopPoint();
			return Ship_MoveDelta( ptdelta );
		}
		break;
	case SHV_SHIPTURNLEFT:
		// "Port",
		// "Turn Left",
		DirMoveChange = -2;
doturn:
		if ( m_itShip.m_fAnchored )
		{
anchored:
			pszSpeak = "The anchor is down <SEX Sir/Mam>!";
			break;
		}
		m_itShip.m_DirMove = GetDirTurn( DirFace, DirMoveChange );
		Ship_Face( (DIR_TYPE) m_itShip.m_DirMove );
		break;
	case SHV_SHIPTURNRIGHT:
		// "Turn Right",
		// "Starboard",	// Turn Right
		DirMoveChange = 2;
		goto doturn;
	case SHV_SHIPDRIFTLEFT: 
		// "Left",
		// "Drift Left",
		DirMoveChange = -2;
dodirmovechange:
		if ( m_itShip.m_fAnchored )
			goto anchored;
		if ( ! Ship_SetMoveDir( GetDirTurn( DirFace, DirMoveChange )))
			return( false );
		break;
	case SHV_SHIPDRIFTRIGHT: 
		// "Right",
		// "Drift Right",
		DirMoveChange = 2;
		goto dodirmovechange;
	case SHV_SHIPBACK: 
		// "Back",			// Move ship backwards
		// "Backward",		// Move ship backwards
		// "Backwards",	// Move ship backwards
		DirMoveChange = 4;
		goto dodirmovechange;
	case SHV_SHIPFORE:
		// "Forward"
		// "Foreward",		// Moves ship forward.
		// "Unfurl sail",	// Moves ship forward.
		DirMoveChange = 0;
		goto dodirmovechange;
	case SHV_SHIPFORELEFT: // "Forward left",
		DirMoveChange = -1;
		goto dodirmovechange;
	case SHV_SHIPFORERIGHT: // "forward right",
		DirMoveChange = 1;
		goto dodirmovechange;
	case SHV_SHIPBACKLEFT:
		// "backward left",
		// "back left",
		DirMoveChange = -3;
		goto dodirmovechange;
	case SHV_SHIPBACKRIGHT:
		// "backward right",
		// "back right",
		DirMoveChange = 3;
		goto dodirmovechange;
	case SHV_SHIPANCHORRAISE: // "Raise Anchor",
		if ( ! m_itShip.m_fAnchored )
		{
			pszSpeak = "The anchor is already up <SEX Sir/Mam>";
			break;
		}
		m_itShip.m_fAnchored = false;
		break;
	case SHV_SHIPANCHORDROP: // "Drop Anchor",
		if ( m_itShip.m_fAnchored )
		{
			pszSpeak = "The anchor is already down <SEX Sir/Mam>";
			break;
		}
		m_itShip.m_fAnchored = true;
		Ship_Stop();
		break;
	case SHV_SHIPTURN:
		//	"Turn around",	// Turns ship around and proceeds.
		// "Come about",	// Turns ship around and proceeds.
		DirMoveChange = 4;
		goto doturn;
	case SHV_SHIPUP: // "Up"
		{
			if ( ! IsAttr(ATTR_MAGIC ))
				return( false );

			CPointMap pt;
			pt.m_z = PLAYER_HEIGHT;
			if ( Ship_MoveDelta( pt ))
			{
				pszSpeak = "As you command <SEX Sir/Mam>";
			}
			else
			{
				pszSpeak = "Can't do that <SEX Sir/Mam>";
			}
		}
		break;
	case SHV_SHIPDOWN: // "Down"
		{
			if ( ! IsAttr(ATTR_MAGIC ))
				return( false );
			CPointMap pt;
			pt.m_z = -PLAYER_HEIGHT;
			if ( Ship_MoveDelta( pt ))
			{
				pszSpeak = "As you command <SEX Sir/Mam>";
			}
			else
			{
				pszSpeak = "Can't do that <SEX Sir/Mam>";
			}
		}
		break;
	case SHV_SHIPLAND: // "Land"
		{
			if ( ! IsAttr(ATTR_MAGIC ))
				return( false );
			signed char zold = GetTopZ();
			CPointMap pt = GetTopPoint();
			pt.m_z = zold;
			SetTopZ( -UO_SIZE_Z );	// bottom of the world where i won't get in the way.
			WORD wBlockFlags = CAN_I_WATER;
			signed char z = g_World.GetHeightPoint( pt, wBlockFlags );
			SetTopZ( zold );	// restore z for now.
			pt.InitPoint();
			pt.m_z = z - zold;
			if ( pt.m_z )
			{
				Ship_MoveDelta( pt );
				pszSpeak = "As you command <SEX Sir/Mam>";
			}
			else
			{
				pszSpeak = "We have landed <SEX Sir/Mam>";
			}
		}
		break;
	default:
		return( false );
	}

	if ( pChar )
	{
		if ( pszSpeak == NULL )
		{
			static LPCTSTR const sm_pszAye[] =
			{
				"Aye",
				"Aye Cap'n",
				"Aye <SEX Sir/Mam>",
			};
			pszSpeak = sm_pszAye[ Calc_GetRandVal( COUNTOF( sm_pszAye )) ];
		}

		TCHAR szText[ MAX_TALK_BUFFER ];
		strcpy( szText, pszSpeak );
		pChar->ParseText( szText, &g_Serv );
		pTiller->Speak( szText, 0, TALKMODE_SAY, FONT_NORMAL );
	}
	return false;
	EXC_CATCH("CItemMulti");
	return true;
}
示例#6
0
void CItemMulti::Multi_Create( CChar * pChar, DWORD dwKeyCode )
{
	// Create house or Ship extra stuff.
	// ARGS:
	//  dwKeyCode = set the key code for the doors/sides to this in case it's a drydocked ship.
	// NOTE: 
	//  This can only be done after the house is given location.

	const CItemBaseMulti * pMultiDef = Multi_GetDef();
	// We are top level.
	if ( pMultiDef == NULL ||
		! IsTopLevel())
		return;

	if ( dwKeyCode == UID_CLEAR )
		dwKeyCode = GetUID();

	// ??? SetTimeout( GetDecayTime()); house decay ?

	bool fNeedKey = false;
	int iQty = pMultiDef->m_Components.GetCount();
	for ( int i=0; i<iQty; i++ )
	{
		fNeedKey |= Multi_CreateComponent( (ITEMID_TYPE) pMultiDef->m_Components[i].m_id,
			pMultiDef->m_Components[i].m_dx,
			pMultiDef->m_Components[i].m_dy,
			pMultiDef->m_Components[i].m_dz,
			dwKeyCode );
	}

#if 0
	const CGrayMulti * pMultiMul = g_World.GetMultiItemDefs( GetDispID());
	if ( pMultiMul )
	{
		iQty = pMultiMul->GetItemCount();
		for ( int i=0; iQty--; i++ )
		{
			const CUOMultiItemRec * pMultiItem = pMultiMul->GetItem(i);
			ASSERT(pMultiItem);
			if ( pMultiItem->m_visible )	// client side.
				continue;
			fNeedKey |= Multi_CreateComponent( pMultiItem->GetDispID(),
				pMultiItem->m_dx,
				pMultiItem->m_dy,
				pMultiItem->m_dz,
				dwKeyCode );
		}
	}
#endif

	CItem * pKey = NULL;
	if ( fNeedKey )
	{
		// Create the key to the door.
		ITEMID_TYPE id = IsAttr(ATTR_MAGIC) ? ITEMID_KEY_MAGIC : ITEMID_KEY_COPPER ;
		pKey = CreateScript( id, pChar );
		ASSERT(pKey);
		pKey->SetType(IT_KEY);
		if ( g_Cfg.m_fAutoNewbieKeys )
			pKey->SetAttr(ATTR_NEWBIE);
		pKey->SetAttr(m_Attr&ATTR_MAGIC);
		pKey->m_itKey.m_lockUID.SetPrivateUID( dwKeyCode );
		pKey->m_uidLink = GetUID();	
	}

	Multi_GetSign();	// set the m_uidLink

	if ( pChar != NULL )
	{
		m_itShip.m_UIDCreator = pChar->GetUID();
		CItemMemory * pMemory = pChar->Memory_AddObjTypes( this, MEMORY_GUARD );

		if ( pKey )
		{
			// Put in your pack
			pChar->GetPackSafe()->ContentAdd( pKey );

			// Put dupe key in the bank.
			pKey = CreateDupeItem( pKey );
			pChar->GetBank()->ContentAdd( pKey );
			pChar->SysMessage( "The duplicate key is in your bank account" );
		}
	}
	else
	{
		// Just put the key on the front step ?
		DEBUG_CHECK( 0 );
	}
}
示例#7
0
// timer expired, should I grow?
bool CItem::Plant_OnTick()
{
	ADDTOCALLSTACK("CItem::Plant_OnTick");
	ASSERT(IsType(IT_CROPS) || IsType(IT_FOLIAGE));
	// If it is in a container, kill it.
	if ( !IsTopLevel() )
		return false;

	// Make sure the darn thing isn't moveable
	SetAttr(ATTR_MOVE_NEVER);
	Plant_SetTimer();

	// No tree stuff below here
	if ( IsAttr(ATTR_INVIS) )	// if it's invis, take care of it here and return
	{
		SetHue(HUE_DEFAULT);
		ClrAttr(ATTR_INVIS);
		Update();
		return true;
	}

	const CItemBase *pItemDef = Item_GetDef();
	ITEMID_TYPE iGrowID = pItemDef->m_ttCrops.m_idGrow;

	if ( iGrowID == -1 )
	{
		// Some plants generate a fruit on the ground when ripe.
		ITEMID_TYPE iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttCrops.m_idGrow));
		if ( m_itCrop.m_ReapFruitID )
			iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itCrop.m_ReapFruitID));
		if ( !iFruitID )
			return true;

		// Put a fruit on the ground if not already here.
		CWorldSearch AreaItems(GetTopPoint());
		for (;;)
		{
			CItem *pItem = AreaItems.GetItem();
			if ( !pItem )
			{
				CItem *pItemFruit = CItem::CreateScript(iFruitID);
				ASSERT(pItemFruit);
				pItemFruit->MoveToDecay(GetTopPoint(), 10 * g_Cfg.m_iDecay_Item);
				break;
			}
			if ( pItem->IsType(IT_FRUIT) || pItem->IsType(IT_REAGENT_RAW) )
				break;
		}

		// NOTE: ??? The plant should cycle here as well !
		iGrowID = pItemDef->m_ttCrops.m_idReset;
	}

	if ( iGrowID )
	{
		SetID(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iGrowID)));
		Update();
		return true;
	}

	// some plants go dormant again ?
	// m_itCrop.m_Fruit_ID = iTemp;
	return true;
}
CStoneMember * CItemStone::AddRecruit(const CChar * pChar, STONEPRIV_TYPE iPriv, bool bFull)
{
	ADDTOCALLSTACK("CItemStone::AddRecruit");
	// CLIMODE_TARG_STONE_RECRUIT
	// Set as member or candidate.

	if ( !pChar || !pChar->m_pPlayer )
	{
		Speak( "Only players can be members!");
		return NULL;
	}

	TCHAR * z = Str_GetTemp();
	const CItemStone * pStone = pChar->Guild_Find( GetMemoryType());
	if ( pStone && pStone != this )
	{
		sprintf(z, "%s appears to belong to %s. Must resign previous %s", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pStone->GetName()), static_cast<LPCTSTR>(GetTypeName()));
		Speak(z);
		return NULL;
	}

	if ( IsType(IT_STONE_TOWN) && IsAttr(ATTR_OWNED) && iPriv == STONEPRIV_CANDIDATE )
	{
		// instant member.
		iPriv = STONEPRIV_MEMBER;
	}

	CStoneMember * pMember = GetMember(pChar);
	if ( pMember )
	{
		// I'm already a member of some sort.
		if ( pMember->GetPriv() == iPriv || iPriv == STONEPRIV_CANDIDATE )
		{
			sprintf(z, "%s is already %s %s.", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pMember->GetPrivName()), static_cast<LPCTSTR>(GetName()));
			Speak(z);
			return NULL;
		}

		pMember->SetPriv( iPriv );
	}
	else
	{
		pMember = new CStoneMember(this, pChar->GetUID(), iPriv);

		if ( bFull )	// full join means becoming a full member already
		{
			pMember->SetPriv(STONEPRIV_MEMBER);
			pMember->SetAbbrev(true);
		}
	}

	if ( pMember->IsPrivMember())
	{
		pMember->SetLoyalTo(pChar);
		ElectMaster();	// just in case this is the first.
	}

	sprintf(z, "%s is now %s %s", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pMember->GetPrivName()), static_cast<LPCTSTR>(GetName()));
	Speak(z);
	return pMember;
}