void CBasePlayerAmmo::Materialize() { if( GetEffects() & EF_NODRAW ) { // changing from invisible state to visible. EMIT_SOUND_DYN( this, CHAN_WEAPON, "items/suitchargeok1.wav", 1, ATTN_NORM, 0, 150 ); GetEffects().ClearFlags( EF_NODRAW ); GetEffects() |= EF_MUZZLEFLASH; } SetTouch( &CBasePlayerAmmo::DefaultTouch ); }
void CFuncMonsterClip::Spawn( void ) { CFuncWall::Spawn(); if( CVAR_GET_FLOAT( "showtriggers" ) == 0 ) GetEffects() = EF_NODRAW; GetFlags() |= FL_MONSTERCLIP; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CAntlionGrub::Squash( CBaseEntity *pOther, bool bDealDamage, bool bSpawnBlood ) { // If we're already squashed, then don't bother doing it again! if ( GetEffects() & EF_NODRAW ) return; SpawnSquashedGrub(); AddEffects( EF_NODRAW ); AddSolidFlags( FSOLID_NOT_SOLID ); // Stop being attached to us if ( m_hGlowSprite ) { FadeGlow(); m_hGlowSprite->SetParent( NULL ); } EmitSound( "NPC_Antlion_Grub.Die" ); EmitSound( "NPC_Antlion_Grub.Squish" ); // if vort stepped on me, maybe he wants to say something if ( pOther && FClassnameIs( pOther, "npc_vortigaunt" ) ) { Assert(dynamic_cast<CNPC_Vortigaunt *>(pOther)); static_cast<CNPC_Vortigaunt *>(pOther)->OnSquishedGrub(this); } SetTouch( NULL ); //if ( bSpawnBlood ) { // Temp squash effect Vector vecForward, vecUp; AngleVectors( GetAbsAngles(), &vecForward, NULL, &vecUp ); // Start effects at either end of the grub Vector vecSplortPos = GetAbsOrigin() + vecForward * 14.0f; DispatchParticleEffect( "GrubSquashBlood", vecSplortPos, GetAbsAngles() ); vecSplortPos = GetAbsOrigin() - vecForward * 16.0f; Vector vecDir = -vecForward; QAngle vecAngles; VectorAngles( vecDir, vecAngles ); DispatchParticleEffect( "GrubSquashBlood", vecSplortPos, vecAngles ); MakeSquashDecals( GetAbsOrigin() + vecForward * 32.0f ); MakeSquashDecals( GetAbsOrigin() - vecForward * 32.0f ); } // Deal deadly damage to ourself if ( bDealDamage ) { CTakeDamageInfo info( pOther, pOther, Vector( 0, 0, -1 ), GetAbsOrigin(), GetHealth()+1, DMG_CRUSH ); TakeDamage( info ); } }
// Return all the effects that belong to this immediate category or any // of its subcategories), filtered by effect type. EffectSet EffectCategory::GetAllEffects(int type) const { EffectSet result = GetEffects(type); CategorySet::const_iterator iter; for (iter = mSubCategories.begin(); iter != mSubCategories.end(); ++iter) { EffectSet tmp = (*iter)->GetAllEffects(type); EffectSet::const_iterator itr2; for (itr2 = tmp.begin(); itr2 != tmp.end(); ++itr2) result.insert(*itr2); } return result; }
CBaseEntity* CBasePlayerAmmo::Respawn() { GetEffects() |= EF_NODRAW; SetTouch( NULL ); SetAbsOrigin( g_pGameRules->VecAmmoRespawnSpot( this ) );// move to wherever I'm supposed to repawn. SetThink( &CBasePlayerAmmo::Materialize ); SetNextThink( g_pGameRules->FlAmmoRespawnTime( this ) ); return this; }
std::string BattleSystem::DisplayDetail( const Spell& spell ) const { std::string output; output .append( "\n> DETAIL <\n- Power: " ) .append( spell.power ? GetStringPower( *spell.power ) : std::string( "-" ) ) .append( "\n- Effects: " ) .append( spell.effects ? GetStringEffects( GetEffects( spell.effects ) ) : std::string( "-" ) ) .append( "\n" ); std::cout << output; return output; }
void CFuncTankControls::Spawn( void ) { SetSolidType( SOLID_TRIGGER ); SetMoveType( MOVETYPE_NONE ); GetEffects() |= EF_NODRAW; SetModel( GetModelName() ); SetSize( GetRelMin(), GetRelMax() ); SetAbsOrigin( GetAbsOrigin() ); SetNextThink( gpGlobals->time + 0.3 ); // After all the func_tank's have spawned CBaseEntity::Spawn(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CAntlionGrub::SpawnSquashedGrub( void ) { // If we're already invisible, we're done if ( GetEffects() & EF_NODRAW ) return; Vector vecUp; GetVectors( NULL, NULL, &vecUp ); CBaseEntity *pGib = CreateRagGib( ANTLIONGRUB_SQUASHED_MODEL, GetAbsOrigin(), GetAbsAngles(), vecUp * 16.0f ); if ( pGib ) { pGib->AddEffects( EF_NOSHADOW ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - //----------------------------------------------------------------------------- int CAntlionGrub::OnTakeDamage( const CTakeDamageInfo &info ) { // Animate a flinch of pain if we're dying bool bSquashed = ( ( GetEffects() & EF_NODRAW ) != 0 ); if ( bSquashed == false ) { SetSequence( SelectWeightedSequence( ACT_SMALL_FLINCH ) ); m_flFlinchTime = gpGlobals->curtime + random->RandomFloat( 0.5f, 1.0f ); SetThink( &CAntlionGrub::FlinchThink ); SetNextThink( gpGlobals->curtime + 0.05f ); } return BaseClass::OnTakeDamage( info ); }
std::string BattleSystem::AttackSpell( Character& attacker, Character& target, const Spell& spell ) const { std::string events; events .append( "- " ) .append( attacker.name ) .append( " cast " ) .append( spell.name ) .append( " on " ) .append( target.name ); if( spell.power ) { const int result = GetPowerDiceRoll( *spell.power ); const int type = spell.power->beneficial ? -1 : 1; events .append( ", " ) .append( spell.power->beneficial ? "restoring" : "damaging" ) .append( " its health by " ) .append( std::to_string( result ) ); target.health.current -= result * type; } events.append( "\n" ); if( spell.effects != 0 ) { const std::vector<std::reference_wrapper<const Effect>> effects = GetEffects( spell.effects ); events .append( "- " ) .append( spell.name ) .append( " affects " ) .append( target.name ) .append( ", applying " ) .append( GetStringEffects( effects ) ) .append( "\n" ); for( const auto& effect : effects ) { target.effects.insert_or_assign( effect.get( ).name, effect.get( ) ); } } return events; }
void CCyclerSprite::Spawn( void ) { SetSolidType( SOLID_SLIDEBOX ); SetMoveType( MOVETYPE_NONE ); SetTakeDamageMode( DAMAGE_YES ); GetEffects().ClearAll(); SetFrame( 0 ); SetNextThink( gpGlobals->time + 0.1 ); m_animate = 1; m_lastTime = gpGlobals->time; PRECACHE_MODEL( GetModelName() ); SetModel( GetModelName() ); m_maxFrame = ( float ) MODEL_FRAMES( GetModelIndex() ) - 1; }
void CShower::Spawn( void ) { Vector vecVelocity = RANDOM_FLOAT( 200, 300 ) * GetAbsAngles(); vecVelocity.x += RANDOM_FLOAT( -100.f, 100.f ); vecVelocity.y += RANDOM_FLOAT( -100.f, 100.f ); if( vecVelocity.z >= 0 ) vecVelocity.z += 200; else vecVelocity.z -= 200; SetAbsVelocity( vecVelocity ); SetMoveType( MOVETYPE_BOUNCE ); SetGravity( 0.5 ); SetNextThink( gpGlobals->time + 0.1 ); SetSolidType( SOLID_NOT ); SetModel( "models/grenade.mdl" ); // Need a model, just use the grenade, we don't draw it anyway SetSize( g_vecZero, g_vecZero ); GetEffects() |= EF_NODRAW; SetSpeed( RANDOM_FLOAT( 0.5, 1.5 ) ); SetAbsAngles( g_vecZero ); }
// make the entity carry out the scripted sequence instructions, but without // destroying the monster's state. void CCineAI::PossessEntity( void ) { Schedule_t *pNewSchedule; CBaseEntity *pEntity = m_hTargetEnt; CBaseMonster *pTarget = NULL; if( pEntity ) pTarget = pEntity->MyMonsterPointer(); if( pTarget ) { if( !pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_AI ) ) { ALERT( at_aiconsole, "(AI)Can't possess entity %s\n", pTarget->GetClassname() ); return; } pTarget->m_hGoalEnt = this; pTarget->m_pCine = this; pTarget->m_hTargetEnt = this; m_saved_movetype = pTarget->GetMoveType(); m_saved_solid = pTarget->GetSolidType(); m_saved_effects = pTarget->GetEffects(); pTarget->GetEffects() |= GetEffects(); switch( m_fMoveTo ) { case 0: case 5: pTarget->m_scriptState = SCRIPT_WAIT; break; case 1: pTarget->m_scriptState = SCRIPT_WALK_TO_MARK; break; case 2: pTarget->m_scriptState = SCRIPT_RUN_TO_MARK; break; case 4: { // zap the monster instantly to the site of the script entity. pTarget->SetAbsOrigin( GetAbsOrigin() ); pTarget->SetIdealYaw( GetAbsAngles().y ); pTarget->SetAngularVelocity( g_vecZero ); pTarget->SetAbsVelocity( Vector( 0, 0, 0 ) ); pTarget->GetEffects() |= EF_NOINTERP; Vector vecAngles = pTarget->GetAbsAngles(); vecAngles.y = GetAbsAngles().y; pTarget->SetAbsAngles( vecAngles ); pTarget->m_scriptState = SCRIPT_WAIT; m_startTime = gpGlobals->time + 1E6; // UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters pTarget->GetFlags().ClearFlags( FL_ONGROUND ); break; } default: ALERT( at_aiconsole, "aiscript: invalid Move To Position value!" ); break; } ALERT( at_aiconsole, "\"%s\" found and used\n", pTarget->GetTargetname() ); pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; /* if (m_iszIdle) { StartSequence( pTarget, m_iszIdle, false ); if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay))) { pTarget->SetFrameRate( 0 ); } } */ // Already in a scripted state? if( pTarget->m_MonsterState == MONSTERSTATE_SCRIPT ) { pNewSchedule = pTarget->GetScheduleOfType( SCHED_AISCRIPT ); pTarget->ChangeSchedule( pNewSchedule ); } } }
void CRopeSample::Spawn() { GetEffects() |= EF_NODRAW; }
// make the entity enter a scripted sequence void CCineMonster::PossessEntity( void ) { CBaseEntity *pEntity = m_hTargetEnt; CBaseMonster *pTarget = NULL; if( pEntity ) pTarget = pEntity->MyMonsterPointer(); if( pTarget ) { // FindEntity() just checked this! #if 0 if( !pTarget->CanPlaySequence( FCanOverrideState() ) ) { ALERT( at_aiconsole, "Can't possess entity %s\n", pTarget->GetClassname() ); return; } #endif pTarget->m_hGoalEnt = this; pTarget->m_pCine = this; pTarget->m_hTargetEnt = this; m_saved_movetype = pTarget->GetMoveType(); m_saved_solid = pTarget->GetSolidType(); m_saved_effects = pTarget->GetEffects(); pTarget->GetEffects() |= GetEffects(); switch( m_fMoveTo ) { case 0: pTarget->m_scriptState = SCRIPT_WAIT; break; case 1: pTarget->m_scriptState = SCRIPT_WALK_TO_MARK; DelayStart( true ); break; case 2: pTarget->m_scriptState = SCRIPT_RUN_TO_MARK; DelayStart( true ); break; case 4: pTarget->SetAbsOrigin( GetAbsOrigin() ); pTarget->SetIdealYaw( GetAbsAngles().y ); pTarget->SetAngularVelocity( g_vecZero ); pTarget->SetAbsVelocity( Vector( 0, 0, 0 ) ); pTarget->GetEffects() |= EF_NOINTERP; Vector vecAngles = pTarget->GetAbsAngles(); vecAngles.y = GetAbsAngles().y; pTarget->SetAbsAngles( vecAngles ); pTarget->m_scriptState = SCRIPT_WAIT; m_startTime = gpGlobals->time + 1E6; // UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters // pTarget->GetFlags().ClearFlags( FL_ONGROUND ); break; } // ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", pTarget->GetTargetname(), GetSpawnFlags().Any( SF_SCRIPT_NOINTERRUPT ) ?"No":"Yes" ); pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; if( m_iszIdle ) { StartSequence( pTarget, m_iszIdle, false ); if( FStrEq( STRING( m_iszIdle ), STRING( m_iszPlay ) ) ) { pTarget->SetFrameRate( 0 ); } } } }
void CGTextArea::PaintText (CG32bitImage &Dest, const RECT &rcRect) // PaintText // // Paint plain text { // Paint the text if (m_pFont) { // If we haven't justified the text for this size, do it now if (m_cxJustifyWidth != RectWidth(rcRect)) { m_cxJustifyWidth = RectWidth(rcRect); m_Lines.DeleteAll(); m_pFont->BreakText(m_sText, m_cxJustifyWidth, &m_Lines, CG16bitFont::SmartQuotes); } // Compute the rect within which we draw the text RECT rcText = rcRect; if (m_bEditable) { int iVSpacing = (RectHeight(rcRect) - m_pFont->GetHeight()) / 2; rcText.left += iVSpacing; rcText.right -= iVSpacing; rcText.top += iVSpacing; rcText.bottom -= iVSpacing; } // Clip to text rect RECT rcOldClip = Dest.GetClipRect(); Dest.SetClipRect(rcText); // Figure out how many lines fit in the rect int iMaxLineCount = RectHeight(rcText) / m_pFont->GetHeight(); // If there are too many lines, and we're editable, start at the end int iStart = 0; if (m_bEditable && iMaxLineCount < m_Lines.GetCount()) iStart = m_Lines.GetCount() - iMaxLineCount; // Paint each line int x = rcText.left; int y = rcText.top; for (int i = iStart; i < m_Lines.GetCount(); i++) { CString sLine = m_Lines[i]; // Trim the last space in the line, if necessary char *pPos = sLine.GetASCIIZPointer(); if (sLine.GetLength() > 0 && pPos[sLine.GetLength() - 1] == ' ') sLine = strTrimWhitespace(sLine); // Alignment int xLine; if (m_dwStyles & alignCenter) { int cxWidth = m_pFont->MeasureText(sLine); xLine = x + (RectWidth(rcText) - cxWidth) / 2; } else if (m_dwStyles & alignRight) { int cxWidth = m_pFont->MeasureText(sLine); xLine = x + (RectWidth(rcRect) - cxWidth); } else xLine = x; // Paint if (HasEffects()) m_pFont->DrawTextEffect(Dest, xLine, y, m_rgbColor, sLine, GetEffectCount(), GetEffects()); else Dest.DrawText(xLine, y, *m_pFont, m_rgbColor, sLine); // Next y += m_pFont->GetHeight() + m_cyLineSpacing; if (y >= rcText.bottom) break; } // Paint the cursor if (m_bEditable && m_iCursorLine >= iStart) { int cxPos = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(CString(m_Lines[m_iCursorLine].GetASCIIZPointer(), m_iCursorPos, true)) : 0); int y = rcText.top + (m_iCursorLine - iStart) * (m_pFont->GetHeight() + m_cyLineSpacing); int x = rcText.left; if (m_dwStyles & alignCenter) { int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0); x += ((RectWidth(rcText) - cxWidth) / 2) + cxPos; } else if (m_dwStyles & alignRight) { int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0); x += (RectWidth(rcText) - cxWidth) + cxPos; } else x += cxPos; if (((m_iTick / 30) % 2) > 0) { Dest.Fill(x, y, 2, m_pFont->GetHeight(), RGB_CURSOR); } } // Restore clip Dest.SetClipRect(rcOldClip); } }
void CBasePlayer::PlayerDeathThink() { if( GetFlags().Any( FL_ONGROUND ) ) { const float flForward = GetAbsVelocity().Length() - 20; if( flForward <= 0 ) SetAbsVelocity( g_vecZero ); else SetAbsVelocity( flForward * GetAbsVelocity().Normalize() ); } if( HasWeapons() ) { // we drop the guns here because weapons that have an area effect and can kill their user // will sometimes crash coming back from CBasePlayer::Killed() if they kill their owner because the // player class sometimes is freed. It's safer to manipulate the weapons once we know // we aren't calling into any of their code anymore through the player pointer. PackDeadPlayerItems(); } if( GetModelIndex() && ( !m_fSequenceFinished ) && ( GetDeadFlag() == DEAD_DYING ) ) { StudioFrameAdvance(); m_iRespawnFrames++; // Note, these aren't necessarily real "frames", so behavior is dependent on # of client movement commands if( m_iRespawnFrames < 120 ) // Animations should be no longer than this return; } // once we're done animating our death and we're on the ground, we want to set movetype to None so our dead body won't do collisions and stuff anymore // this prevents a bug where the dead body would go to a player's head if he walked over it while the dead player was clicking their button to respawn if( GetMoveType() != MOVETYPE_NONE && GetFlags().Any( FL_ONGROUND ) ) SetMoveType( MOVETYPE_NONE ); if( GetDeadFlag() == DEAD_DYING ) SetDeadFlag( DEAD_DEAD ); StopAnimation(); GetEffects() |= EF_NOINTERP; SetFrameRate( 0.0 ); const bool fAnyButtonDown = ( GetButtons().Any( ~IN_SCORE ) ) != 0; // wait for all buttons released if( GetDeadFlag() == DEAD_DEAD ) { if( fAnyButtonDown ) return; if( g_pGameRules->FPlayerCanRespawn( this ) ) { m_fDeadTime = gpGlobals->time; SetDeadFlag( DEAD_RESPAWNABLE ); } return; } // if the player has been dead for one second longer than allowed by forcerespawn, // forcerespawn isn't on. Send the player off to an intermission camera until they // choose to respawn. if( g_pGameRules->IsMultiplayer() && ( gpGlobals->time > ( m_fDeadTime + 6 ) ) && !( m_afPhysicsFlags & PFLAG_OBSERVER ) ) { // go to dead camera. StartDeathCam(); } if( IsObserver() ) // player is in spectator mode return; // wait for any button down, or mp_forcerespawn is set and the respawn time is up if( !fAnyButtonDown && !( g_pGameRules->IsMultiplayer() && forcerespawn.value > 0 && ( gpGlobals->time > ( m_fDeadTime + 5 ) ) ) ) return; GetButtons().ClearAll(); m_iRespawnFrames = 0; //ALERT(at_console, "Respawn\n"); g_pGameRules->PlayerRespawn( this, !( m_afPhysicsFlags & PFLAG_OBSERVER ) );// don't copy a corpse if we're in deathcam. SetNextThink( -1 ); }