/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // WARNING: probable sync bads, doesn't work right 349 %{ #include "EntitiesMP/StdH/StdH.h" #include "ModelsMP/Enemies/AirElemental/ShockWaveBase.h" #include "ModelsMP/Enemies/AirElemental/ShockWave.h" %} uses "EntitiesMP/BasicEffects"; // input parameter for launching the projectile event EAirShockwave { CEntityPointer penLauncher, // who launched it FLOAT fHeight, // height in the beginning FLOAT fEndWidth, // width along the X,Z axes in the end FLOAT fDuration, // how long to live }; %{ // shockwave #define ECF_SHOCKAWAVE ( \ ((ECBI_BRUSH|ECBI_MODEL|ECBI_CORPSE|ECBI_ITEM|ECBI_PROJECTILE_MAGIC|ECBI_PROJECTILE_SOLID)<GetAttachmentModel(SHOCKWAVEBASE_ATTACHMENT_SHOCKWAVE); return &(amo0.amo_moModelObject); }; // per-frame adjustments here BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient) { // growing if (m_bGrowing) { FLOAT3D vSize; FLOAT fLifeTime = _pTimer->GetLerpedCurrentTick() - m_tmBegin; vSize(1) = (fLifeTime/m_fDuration)*(m_fEndStretchXZ-m_fBeginStretchXZ)+m_fBeginStretchXZ; vSize(2) = m_fStretchY; vSize(3) = vSize(1); ShockwaveModel()->StretchModel(vSize); // start fadeout if more than 70% of lifetime passed if ((fLifeTime/m_fDuration)>m_fFadeStartPercent && !m_bFadeOut) { m_bFadeOut = TRUE; m_fFadeStartTime = _pTimer->GetLerpedCurrentTick(); } // remember last grow time m_tmLastGrow = _pTimer->GetLerpedCurrentTick(); } // fading out if (m_bFadeOut) { FLOAT fTimeRemain = m_tmEnd - _pTimer->GetLerpedCurrentTick(); FLOAT fFadeTime = (1 - m_fFadeStartPercent)*m_fDuration; if (fTimeRemain < 0.0f) { fTimeRemain = 0.0f; } COLOR colAlpha = ShockwaveModel()->mo_colBlendColor; colAlpha = (colAlpha&0xffffff00) + (COLOR(fTimeRemain/fFadeTime*0xff)&0xff); ShockwaveModel()->mo_colBlendColor = colAlpha; } return CMovableModelEntity::AdjustShadingParameters(vLightDirection, colLight, colAmbient); }; // throw away an entity when touched void LaunchEntity(CEntity *pen) { // don't launch air elemental and twisters and shockwaves and any items if (IsOfClass(pen, "AirElemental") || IsOfClass(pen, "Twister") || IsDerivedFromClass(pen, "Item") || IsOfClass(pen, "AirShockwave")) { return; } if (pen->GetPhysicsFlags()&EPF_MOVABLE) { FLOAT3D vSpeed; vSpeed = pen->GetPlacement().pl_PositionVector - GetPlacement().pl_PositionVector; if (vSpeed(2) apenNearEntities; FLOAT fLifeTime = _pTimer->CurrentTick() - m_tmBegin; FLOAT fCurrentRadius = Lerp(SHOCKWAVE_WIDTH, m_fEndWidth, fLifeTime/m_fDuration)/2.0f; FLOATaabbox3D m_boxCurrent = m_boxMaxSize; m_boxCurrent += GetPlacement().pl_PositionVector; // width of 'launch belt' FLOAT fBeltWidth = m_fEndWidth*_pTimer->TickQuantum*2.0f/m_fDuration; GetWorld()->FindEntitiesNearBox(m_boxCurrent, apenNearEntities); for (INDEX i=0; iGetBoundingBox(m_boxEntity); if (fDistance<(fCurrentRadius+fBeltWidth/2.0f) && fDistance>(fCurrentRadius-fBeltWidth/2.0f) && m_boxEntity.HasContactWith(m_boxCurrent)) { LaunchEntity(apenNearEntities[i]); } } CMovableModelEntity::PreMoving(); }; procedures: // --->>> MAIN Main(EAirShockwave eas) { // remember the initial parameters ASSERT(eas.penLauncher!=NULL); ASSERT(eas.fHeight>0.0f); ASSERT(eas.fEndWidth>0.1f); ASSERT(eas.fDuration>0.0f); m_penLauncher = eas.penLauncher; m_fHeight = eas.fHeight; m_fEndWidth = eas.fEndWidth; m_fDuration = eas.fDuration; // calculate stretches from parameters m_fStretchY = m_fHeight/SHOCKWAVE_HEIGHT; m_fBeginStretchXZ = 1.0f; m_fEndStretchXZ = m_fEndWidth/SHOCKWAVE_WIDTH; FLOAT3D v1 = FLOAT3D(-m_fEndWidth/2.0f, 0.0f, -m_fEndWidth/2.0f); FLOAT3D v2 = FLOAT3D(+m_fEndWidth/2.0f, m_fHeight, +m_fEndWidth/2.0f); m_boxMaxSize = FLOATaabbox3D(v1, v2); // initialization InitAsModel(); SetPhysicsFlags(EPF_SHOCKAWAVE); SetCollisionFlags(ECF_SHOCKAWAVE); SetFlags(GetFlags() | ENF_SEETHROUGH); // set appearance SetModel(MODEL_INVISIBLE); AddAttachmentToModel(this, *GetModelObject(), SHOCKWAVEBASE_ATTACHMENT_SHOCKWAVE, MODEL_SHOCKWAVE, TEXTURE_SHOCKWAVE, 0, 0, 0); GetModelObject()->StretchModel(FLOAT3D(1.0f, 1.0f, 1.0f)); ModelChangeNotify(); ShockwaveModel()->StretchModel(FLOAT3D(m_fBeginStretchXZ, m_fStretchY, m_fBeginStretchXZ)); autowait(_pTimer->TickQuantum); m_tmBegin = _pTimer->CurrentTick(); m_tmEnd = m_tmBegin + m_fDuration; m_tmLastGrow = _pTimer->CurrentTick(); m_bGrowing = TRUE; while(_pTimer->CurrentTick()TickQuantum); TestForCollisionAndLaunchEntity(); } // cease to exist Destroy(); return; } };