2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
# include <StdAfx.h>
2018-03-29 17:01:57 -04:00
# include "Portal.h"
# include "World.h"
# include "ChatMsgs.h"
# include "Player.h"
# define PORTAL_TRIGGER_DISTANCE 2.0f
# define PORTAL_TRIGGER_FREQUENCY 1.0f
CPortal : : CPortal ( )
{
m_Qualities . id = 0x82D ;
m_Qualities . m_WeenieType = Portal_WeenieType ;
SetName ( " Portal " ) ;
SetIcon ( 0x0600106B ) ;
SetSetupID ( 0x20001B3 ) ;
SetInitialPhysicsState ( ETHEREAL_PS | REPORT_COLLISIONS_PS | LIGHTING_ON_PS | GRAVITY_PS ) ;
SetItemType ( TYPE_PORTAL ) ;
m_Qualities . SetBool ( STUCK_BOOL , TRUE ) ;
m_Qualities . SetBool ( ATTACKABLE_BOOL , TRUE ) ;
m_Qualities . SetInt ( ITEM_USEABLE_INT , USEABLE_REMOTE ) ;
m_Qualities . SetFloat ( USE_RADIUS_FLOAT , - 0.1f ) ;
// Arwic, for testing if we want to
// m_Destination = Position(0xC6A90023, Vector(102.4f, 70.1f, 44.0f), Quaternion(0.70710677f, 0, 0, 0.70710677f));
#if 0 // deprecated
m_fTickFrequency = 0.5f ;
# endif
m_Qualities . m_WeenieType = Portal_WeenieType ;
}
CPortal : : ~ CPortal ( )
{
}
2020-02-08 12:15:07 -05:00
void CPortal : : PostSpawn ( )
2018-03-29 17:01:57 -04:00
{
2020-02-08 12:15:07 -05:00
Position dest ;
// DESTINATION_POSITION
if ( m_Qualities . InqPosition ( RELATIVE_DESTINATION_POSITION , dest ) )
{
// convert relative position to absolute
Position pos ;
pos . objcell_id = m_Position . objcell_id ;
pos . frame . combine ( & m_Position . frame , & dest . frame ) ;
m_Qualities . SetPosition ( DESTINATION_POSITION , pos ) ;
}
CWeenieObject : : PostSpawn ( ) ;
2018-03-29 17:01:57 -04:00
}
void CPortal : : Tick ( )
{
CWeenieObject : : Tick ( ) ;
}
2018-07-12 14:41:21 -07:00
void CPortal : : CheckedTeleport ( CWeenieObject * pOther )
2018-03-29 17:01:57 -04:00
{
if ( pOther & & ! ( pOther - > m_PhysicsState & PhysicsState : : HIDDEN_PS ) )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = pOther - > AsPlayer ( ) )
2018-05-19 19:21:17 +01:00
{
if ( player - > CheckPKActivity ( ) )
{
2019-01-27 09:13:17 +00:00
pOther - > NotifyWeenieError ( WERROR_PORTAL_PK_ATTACKED_TOO_RECENTLY ) ;
return ;
}
if ( player - > IsInPortalSpace ( ) | | player - > InqFloatQuality ( LAST_PORTAL_TELEPORT_TIMESTAMP_FLOAT , 0 ) > = Timer : : cur_time )
{
player - > NotifyWeenieError ( WERROR_PORTAL_TOO_RECENTLY ) ;
2018-05-19 19:21:17 +01:00
return ;
}
}
2018-03-29 17:01:57 -04:00
ChanceExecuteEmoteSet ( pOther - > GetID ( ) , Use_EmoteCategory ) ;
std : : string restriction ;
if ( m_Qualities . InqString ( QUEST_RESTRICTION_STRING , restriction ) )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = pOther - > AsPlayer ( ) )
2018-03-29 17:01:57 -04:00
{
if ( ! player - > InqQuest ( restriction . c_str ( ) ) )
{
2019-01-27 09:13:17 +00:00
pOther - > NotifyWeenieError ( WERROR_PORTAL_QUEST_RESTRICTED ) ;
2018-03-29 17:01:57 -04:00
return ;
}
}
}
2019-01-27 09:13:17 +00:00
2018-03-29 17:01:57 -04:00
int minLevel = InqIntQuality ( MIN_LEVEL_INT , 0 ) ;
int maxLevel = InqIntQuality ( MAX_LEVEL_INT , 0 ) ;
int currentLevel = pOther - > InqIntQuality ( LEVEL_INT , 1 ) ;
if ( minLevel & & currentLevel < minLevel )
{
2019-01-27 09:13:17 +00:00
pOther - > NotifyWeenieError ( WERROR_PORTAL_LEVEL_TOO_LOW ) ;
2018-03-29 17:01:57 -04:00
}
else if ( maxLevel & & currentLevel > maxLevel )
{
2019-01-27 09:13:17 +00:00
pOther - > NotifyWeenieError ( WERROR_PORTAL_LEVEL_TOO_HIGH ) ;
2018-03-29 17:01:57 -04:00
}
else
{
2019-09-20 08:18:55 +00:00
if ( ! ( InqIntQuality ( PORTAL_BITMASK_INT , 0 ) & PortalEnum : : NOT_RECALLABLE_NOR_LINKABLE ) )
{
uint32_t origPortID = InqDIDQuality ( ORIGINAL_PORTAL_DID , 0 ) ;
if ( origPortID > 0 )
// We are interacting with a summoned portal. So make sure we set our link to the original one not 1955!
pOther - > m_Qualities . SetDataID ( LAST_PORTAL_DID , origPortID ) ;
else
//We are interacting with an original portal.
pOther - > m_Qualities . SetDataID ( LAST_PORTAL_DID , m_Qualities . id ) ;
}
2018-11-09 22:55:00 -06:00
2018-03-29 17:01:57 -04:00
Teleport ( pOther ) ;
}
}
}
int CPortal : : DoCollision ( const class ObjCollisionProfile & prof )
{
if ( prof . _bitfield & Player_OCPB )
{
2019-07-07 20:57:25 +00:00
int portalBitmask ;
if ( m_Qualities . InqInt ( PORTAL_BITMASK_INT , portalBitmask ) & & portalBitmask = = 0 ) //if PORTAL_BITMASK_INT not present, portal is considered to have no bitmask restrictions.
{
g_pWorld - > FindObject ( prof . id ) - > NotifyWeenieError ( WERROR_PORTAL_PLAYERS_NOT_ALLOWED ) ;
}
else
CheckedTeleport ( g_pWorld - > FindObject ( prof . id ) ) ;
2018-03-29 17:01:57 -04:00
}
return 1 ;
}
bool CPortal : : GetDestination ( Position & dest )
{
return ! ! m_Qualities . InqPosition ( DESTINATION_POSITION , dest ) & & dest . objcell_id ;
}
2018-07-12 14:41:21 -07:00
void CPortal : : Teleport ( CWeenieObject * pTarget )
2018-03-29 17:01:57 -04:00
{
Position dest ;
if ( GetDestination ( dest ) )
{
pTarget - > StopCompletely ( 0 ) ;
pTarget - > Movement_Teleport ( dest ) ;
if ( ! ( m_Qualities . GetInt ( PORTAL_BITMASK_INT , 0 ) & 0x20 ) )
{
pTarget - > m_Qualities . SetPosition ( LAST_PORTAL_POSITION , dest ) ;
}
std : : string questName ;
if ( m_Qualities . InqString ( QUEST_STRING , questName ) )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = pTarget - > AsPlayer ( ) )
2018-03-29 17:01:57 -04:00
{
player - > StampQuest ( questName . c_str ( ) ) ;
}
}
ChanceExecuteEmoteSet ( pTarget - > GetID ( ) , Portal_EmoteCategory ) ;
}
else
{
pTarget - > SendNetMessage ( ServerText ( " This portal has no destination set. " , 7 ) , PRIVATE_MSG , FALSE , TRUE ) ;
}
}
#if 0 // deprecated
void CPortal : : ProximityThink ( )
{
// Clear old teleports cache
if ( ( m_fLastCacheClear + PORTAL_TRIGGER_FREQUENCY ) < g_pGlobals - > Time ( ) )
{
m_RecentlyTeleported . clear ( ) ;
m_fLastCacheClear = g_pGlobals - > Time ( ) ;
}
2018-07-12 14:41:21 -07:00
std : : list < CWeenieObject * > nearbyObjects ;
2018-03-29 17:01:57 -04:00
g_pWorld - > EnumNearby ( this , PORTAL_TRIGGER_DISTANCE , & nearbyObjects ) ;
2018-07-12 14:41:21 -07:00
for ( std : : list < CWeenieObject * > : : iterator i = nearbyObjects . begin ( ) ; i ! = nearbyObjects . end ( ) ; i + + )
2018-03-29 17:01:57 -04:00
{
2018-07-12 14:41:21 -07:00
CWeenieObject * pOther = * i ;
2018-03-29 17:01:57 -04:00
if ( pOther - > _IsPlayer ( ) & & ! ( pOther - > m_PhysicsState & PhysicsState : : LIGHTING_ON_PS ) )
{
if ( m_RecentlyTeleported . find ( pOther - > GetID ( ) ) = = m_RecentlyTeleported . end ( ) )
{
Teleport ( pOther ) ;
m_RecentlyTeleported . insert ( pOther - > GetID ( ) ) ;
}
}
}
}
# endif
2018-07-12 14:41:21 -07:00
int CPortal : : Use ( CPlayerWeenie * pOther )
2018-03-29 17:01:57 -04:00
{
CPortalUseEvent * useEvent = new CPortalUseEvent ;
useEvent - > _target_id = GetID ( ) ;
pOther - > ExecuteUseEvent ( useEvent ) ;
return WERROR_NONE ;
}
void CPortalUseEvent : : OnReadyToUse ( )
{
2018-07-12 14:41:21 -07:00
CWeenieObject * target = GetTarget ( ) ;
2018-03-29 17:01:57 -04:00
if ( ! target )
{
Cancel ( WERROR_OBJECT_GONE ) ;
return ;
}
2018-07-12 14:41:21 -07:00
( ( CPortal * ) target ) - > CheckedTeleport ( _weenie ) ;
2018-03-29 17:01:57 -04:00
Done ( ) ;
}