/* ============== sdDeployMenu::OnCancel ============== */ void sdDeployMenu::OnCancel( void ) { idPlayer* localPlayer = gameLocal.GetLocalPlayer(); if ( localPlayer ) { localPlayer->RaiseWeapon(); } if ( deployableRenderEntityHandle >= 0 ) { gameRenderWorld->FreeEntityDef( deployableRenderEntityHandle ); deployableRenderEntityHandle = -1; } FreeDecals(); }
/* ============== sdDeployMaskEditSession::~sdDeployMaskEditSession ============== */ sdDeployMaskEditSession::~sdDeployMaskEditSession( void ) { FreeDecals(); gameLocal.program->FreeScriptObject( scriptObject ); }
/* ============== sdDeployMenu::Update ============== */ void sdDeployMenu::Update( void ) { sdHudModule::Update(); idPlayer* localPlayer = gameLocal.GetLocalPlayer(); if ( !deployableObject || !localPlayer ) { return; } deployResult_t result = localPlayer->GetDeployResult( position, deployableObject ); if ( result != DR_OUT_OF_RANGE ) { if ( deployableRenderEntityHandle < 0 ) { deployableRenderEntityHandle = gameRenderWorld->AddEntityDef( &deployableRenderEntity ); } idVec4 color; switch ( deployableState ) { case DR_CLEAR: color = colorGreen; break; case DR_WARNING: color = colorOrange; break; case DR_CONDITION_FAILED: color = colorWhite; break; default: case DR_FAILED: color = colorDkRed; break; } if ( decalHandle == -1 ) { decalHandle = gameLocal.RegisterLoggedDecal( decalMaterial ); lastExpandedExtents.minx = -1; } if ( decalHandleOuter == -1 ) { decalHandleOuter = gameLocal.RegisterLoggedDecal( decalMaterialOuter ); lastExpandedExtents.minx = -1; } if ( decalHandleArrows == -1 ) { decalHandleArrows = gameLocal.RegisterLoggedDecal( decalMaterialArrows ); } gameLocal.ResetLoggedDecal( decalHandleArrows ); gameDecalInfo_t* decalInfo = gameLocal.GetLoggedDecal( decalHandle ); gameDecalInfo_t* decalInfoOuter = gameLocal.GetLoggedDecal( decalHandleOuter ); gameDecalInfo_t* decalInfoArrows = gameLocal.GetLoggedDecal( decalHandleArrows ); if ( !deployableObject->AllowRotation() ) { rotation = 0.0f; } idMat3 rotationStart; idAngles::YawToMat3( rotation, rotationStart ); const sdPlayZone* playZone = gameLocal.GetPlayZone( position, sdPlayZone::PZF_DEPLOYMENT ); const sdPlayZone* playZoneHeight = gameLocal.GetPlayZone( position, sdPlayZone::PZF_HEIGHTMAP ); const sdHeightMapInstance* heightMap = NULL; if ( playZoneHeight ) { heightMap = &playZoneHeight->GetHeightMap(); } const sdDeployMaskInstance* mask = NULL; if ( playZone ) { mask = playZone->GetMask( deployableObject->GetDeploymentMask() ); } if ( mask && mask->IsValid() && heightMap && heightMap->IsValid() ) { idBounds bounds( position ); bounds.ExpandSelf( deployableObject->GetObjectSize() ); sdDeployMask::extents_t extents; mask->CoordsForBounds( bounds, extents ); idBounds mainBounds; mask->GetBounds( extents, mainBounds, heightMap ); float depth = 512.0f; idVec3 top; idBounds moveArrowBounds = mainBounds; idBounds rotateArrowBounds = mainBounds; // straight arrows moveArrowBounds.GetMaxs().y = moveArrowBounds.GetCenter().y; moveArrowBounds.GetMins().y += 0.25f * ( mainBounds.GetMaxs().y - mainBounds.GetMins().y ); moveArrowBounds.GetMaxs().y += 0.25f * ( mainBounds.GetMaxs().y - mainBounds.GetMins().y ); moveArrowBounds.GetMins().x = moveArrowBounds.GetCenter().x; { idVec3 center = moveArrowBounds.GetCenter(); moveArrowBounds.TranslateSelf( -center ); for ( int index = 0; index < 3; index++ ) { moveArrowBounds.GetMins()[ index ] *= 0.25f; moveArrowBounds.GetMaxs()[ index ] *= 0.25f; } moveArrowBounds.TranslateSelf( center ); } // rotate arrows rotateArrowBounds.GetMins().x = rotateArrowBounds.GetCenter().x; { idVec3 center = rotateArrowBounds.GetCenter(); rotateArrowBounds.TranslateSelf( -center ); for ( int index = 0; index < 3; index++ ) { rotateArrowBounds.GetMins()[ index ] *= 0.2f; rotateArrowBounds.GetMaxs()[ index ] *= 0.2f; } rotateArrowBounds.TranslateSelf( center ); } top = mainBounds.GetCenter(); top[ 2 ] = mainBounds.GetMaxs()[ 2 ]; idList< const idMaterial* > megaTextureMaterials; const idStrList& megaTextureMaterialNames = gameLocal.GetMapInfo().GetMegatextureMaterials(); for ( int i = 0; i < megaTextureMaterialNames.Num(); i++ ) { megaTextureMaterials.Append( declHolder.FindMaterial( megaTextureMaterialNames[ i ] ) ); } idFixedWinding winding; int spawnID = WORLD_SPAWN_ID; if ( GetDeployMode() ) { // rotate mode idMat3 rotationOffset; idAngles::YawToMat3( 120.0f, rotationOffset ); // forward arrow winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.0f ) ); winding.Rotate( mainBounds.GetCenter(), rotationStart ); idVec3 offset = rotationStart[ 0 ] * ( 16.f * idMath::Sin( ( gameLocal.time / 500.f ) ) ); for ( int i = 0; i < winding.GetNumPoints(); i++ ) { winding[ i ].ToVec3() += offset; } gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, idVec4( 0.87f, 0.59f, 0.f, 1.f ), decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); // rotate arrows winding.Clear(); winding += idVec5( idVec3( rotateArrowBounds.GetMins().x, rotateArrowBounds.GetMins().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.0f, 0.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMins().x, rotateArrowBounds.GetMaxs().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.0f, 1.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMaxs().x, rotateArrowBounds.GetMaxs().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 1.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMaxs().x, rotateArrowBounds.GetMins().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding.Rotate( mainBounds.GetCenter(), rotationStart * rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); } else { // move mode idMat3 rotationOffset; idAngles::YawToMat3( 90.0f, rotationOffset ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.0f ) ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); } // the grid int maxX, maxY; mask->GetDimensions( maxX, maxY ); sdDeployMask::extents_t expandedExtents; expandedExtents.minx = Max( 0, extents.minx - 2 ); expandedExtents.miny = Max( 0, extents.miny - 2 ); expandedExtents.maxx = Min( maxX, extents.maxx + 2 ); expandedExtents.maxy = Min( maxY, extents.maxy + 2 ); int w = expandedExtents.maxx - expandedExtents.minx + 1; int h = expandedExtents.maxx - expandedExtents.minx + 1; int terrIdx = 0; bool regen = false; if ( ( w * h ) > sizeof( lastTerritory ) / sizeof( lastTerritory[0] ) ) { common->Warning( "test territory size too large" ); return; } for ( int i = expandedExtents.minx; i <= expandedExtents.maxx; i++ ) { for ( int j = expandedExtents.miny; j <= expandedExtents.maxy; j++ ) { gameDecalInfo_t* info = ( ( i >= extents.minx ) && ( i <= extents.maxx ) && ( j >= extents.miny ) && ( j <= extents.maxy ) ) ? decalInfo : decalInfoOuter; if ( !info ) { continue; } sdDeployMask::extents_t localExtents; localExtents.minx = i; localExtents.maxx = i; localExtents.miny = j; localExtents.maxy = j; mask->GetBounds( localExtents, bounds, heightMap ); top = bounds.GetCenter(); top[ 2 ] = bounds.GetMaxs()[ 2 ]; deployResult_t localResult = localPlayer->CheckBoundsForDeployment( localExtents, *mask, deployableObject, playZoneHeight ); bool hasTerritory; if ( localResult == DR_CLEAR ) { hasTerritory = gameLocal.TerritoryForPoint( top, localPlayer->GetGameTeam(), true ) != NULL; } else { hasTerritory = false; } if ( hasTerritory != lastTerritory[ terrIdx ] ) { regen = true; } lastTerritory[ terrIdx++ ] = hasTerritory; } } if ( expandedExtents.minx != lastExpandedExtents.minx || expandedExtents.maxx != lastExpandedExtents.maxx || expandedExtents.miny != lastExpandedExtents.miny || expandedExtents.maxy != lastExpandedExtents.maxy || regen ) { gameLocal.ResetLoggedDecal( decalHandle ); gameLocal.ResetLoggedDecal( decalHandleOuter ); lastExpandedExtents = expandedExtents; terrIdx = 0; for ( int i = expandedExtents.minx; i <= expandedExtents.maxx; i++ ) { for ( int j = expandedExtents.miny; j <= expandedExtents.maxy; j++ ) { gameDecalInfo_t* info = ( ( i >= extents.minx ) && ( i <= extents.maxx ) && ( j >= extents.miny ) && ( j <= extents.maxy ) ) ? decalInfo : decalInfoOuter; if ( !info ) { continue; } sdDeployMask::extents_t localExtents; localExtents.minx = i; localExtents.maxx = i; localExtents.miny = j; localExtents.maxy = j; mask->GetBounds( localExtents, bounds, heightMap ); top = bounds.GetCenter(); top[ 2 ] = bounds.GetMaxs()[ 2 ]; //bool hasTerritory = gameLocal.TerritoryForPoint( top, localPlayer->GetGameTeam(), true ) != NULL; deployResult_t localResult = localPlayer->CheckBoundsForDeployment( localExtents, *mask, deployableObject, playZoneHeight ); idVec4 localColor; switch ( localResult ) { case DR_CLEAR: if ( !lastTerritory[ terrIdx ] ) { localColor = colorOrange; } else { localColor = colorGreen; } break; case DR_WARNING: localColor = colorOrange; break; case DR_FAILED: localColor = colorDkRed; break; } winding.Clear(); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 0.0f ) ); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 0.0f ) ); // gameRenderWorld->DebugBounds( localColor, bounds ); // gameRenderWorld->DrawText( va( "%i %i", i, j ), top, 0.5, colorWhite, gameLocal.GetLocalPlayer()->GetRenderView()->viewaxis ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0, 0, 64.f + depth ), true, localColor, info->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); terrIdx++; } } } } else { gameLocal.ResetLoggedDecal( decalHandle ); gameLocal.ResetLoggedDecal( decalHandleOuter ); lastExpandedExtents.minx = -1; } idVec3 modelPos = position; if ( playZoneHeight ) { const sdHeightMapInstance& heightMap = playZoneHeight->GetHeightMap(); if ( heightMap.IsValid() ) { modelPos.z = heightMap.GetHeight( modelPos ); } } sdDeployRequest::UpdateRenderEntity( deployableRenderEntity, color, modelPos ); deployableRenderEntity.axis = rotationStart; gameRenderWorld->UpdateEntityDef( deployableRenderEntityHandle, &deployableRenderEntity ); } else { if ( deployableRenderEntityHandle >= 0 ) { gameRenderWorld->FreeEntityDef( deployableRenderEntityHandle ); deployableRenderEntityHandle = -1; } FreeDecals(); } }