PowerupType CPowerupManager::GetPowerup( const Core::CCoordinates& coordinates ) const { return GetPowerup( coordinates.x, coordinates.y ); }
void CPowerupManager::HandleStepForPlayer( CPlayer& activePlayer, std::vector<CPlayer>& players, std::set<CPlayer*>& crashedPlayers ) { if( activePlayer.GetPosition() == activePlayer.GetPreviousPosition() ) { return; } if( GetPowerup( activePlayer.GetPosition().x, activePlayer.GetPosition().y ) != NONE ) { switch( powerups[activePlayer.GetPosition()] ) { case WALL: powerups.erase( activePlayer.GetPosition() ); crashedPlayers.insert( &activePlayer ); break; case SAND: powerups.erase( activePlayer.GetPosition() ); activePlayer.SetInertia( { 0, 0 } ); break; case OIL: powerups.erase( activePlayer.GetPosition() ); activePlayer.SetInertia( { 0, 0 } ); while( true ) { int direction = std::rand() % 9 + 1; if( direction != 5 ) { activePlayer.Move( Direction( direction ) ); break; } } activePlayer.SetInertia( { 0, 0 } ); break; case MINE: powerups[activePlayer.GetPosition()] = MINE_ACTIVE; break; case MINE_ACTIVE: powerups.erase( activePlayer.GetPosition() ); crashedPlayers.insert( &activePlayer ); break; case LAZER: { CCoordinates u = activePlayer.GetPosition() - activePlayer.GetPreviousPosition(); double a = std::hypot( u.x, u.y ); // a > 0 всегда, т.к. соответствующая проверка выполнялась в начале функции for( auto& player : players ) { // геометрия. u - вектор движения, v - вектор от стреляющего до другого игрока // a и b - длины этих векторов соответственно, dot - скалярное произведение CCoordinates v = player.GetPosition() - activePlayer.GetPosition(); double dot = u.x * v.x + u.y * v.y; double b = std::hypot( v.x, v.y ); if( dot > 0 && b > 0 && std::sqrt( 1 - std::pow( dot / (a * b), 2 ) ) * b < 0.3 ) { crashedPlayers.insert( &player ); } } powerups.erase( activePlayer.GetPosition() ); shots.push_back( std::make_pair( std::make_pair( activePlayer.GetPosition().x, activePlayer.GetPosition().y ), std::make_pair( float(u.x) / a, float(u.y) / a ) ) ); break; } case SHIELD: powerups.erase( activePlayer.GetPosition() ); activePlayer.ActivateShield(); break; default: break; } } for( auto& player : players ) { handleWalls( player, crashedPlayers ); } }
//performs clipping each frame void Clipping(void) { LIST * cur1; LIST * cur2; LIST * next; for(cur1 = g_asteroid_list; cur1; cur1 = next) { next = cur1->next; if(g_ships && !g_player.wait_time && (((ASTEROID *)cur1->d)->region & g_player.region) && PolyInCircle(&g_player.clip_poly, &(((ASTEROID *)cur1->d)->clip_circle))) //if the player hits the asteroid { PlayerHit(); AsteroidHit(cur1, 0); continue; } for(cur2 = g_alien_list; cur2; cur2 = cur2->next) { if((((ASTEROID *)cur1->d)->region & ((ALIEN *)cur2->d)->region) && (PolyInCircle(&(((ALIEN *)cur2->d)->clip_poly/*s[0]*/), &(((ASTEROID *)cur1->d)->clip_circle)) /*|| PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[1]), &(((ASTEROID *)cur1->d)->clip_circle)) || PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[2]), &(((ASTEROID *)cur1->d)->clip_circle))*/)) { AlienHit(cur2, 0); AsteroidHit(cur1, 0); break; } } if(cur2) //if we broke early from the loop continue; for(cur2 = g_shot_list; cur2; cur2 = cur2->next) { if((((ASTEROID *)cur1->d)->region & ((SHOT *)cur2->d)->region) && PointInCircle(&(((SHOT *)cur2->d)->pos), &(((ASTEROID *)cur1->d)->clip_circle))) //if any shot hits the asteroid { AsteroidHit(cur1, ((SHOT *)cur2->d)->player_owned); RemoveNode(cur2, &g_shot_list); break; } } if(cur2) //if we broke early from the loop continue; } for(cur1 = g_shot_list; cur1; cur1 = next) { next = cur1->next; if(!((SHOT *)cur1->d)->player_owned && g_ships && !g_player.wait_time && (g_player.region & ((SHOT *)cur1->d)->region) && PointInPoly(&(((SHOT *)cur1->d)->pos), &g_player.clip_poly)) //if the alien shot is inside player { RemoveNode(cur1, &g_shot_list); PlayerHit(); continue; } if(((SHOT *)cur1->d)->player_owned) { for(cur2 = g_alien_list; cur2; cur2 = cur2->next) { if((((SHOT *)cur1->d)->region & ((ALIEN *)cur2->d)->region) && (PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_poly/*s[0]*/)) /*|| PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[1])) || PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[2]))*/)) { RemoveNode(cur1, &g_shot_list); AlienHit(cur2, 1); break; } } if(cur2) continue; } for(cur2 = g_powerup_list; cur2; cur2 = cur2->next) { if((((SHOT *)cur1->d)->region & ((POWERUP *)cur2->d)->region) && PointInCircle(&(((SHOT *)cur1->d)->pos), &(((POWERUP *)cur2->d)->clip_circle))) { PowerupHit(cur2, ((SHOT *)cur1->d)->player_owned); RemoveNode(cur1, &g_shot_list); break; } } if(cur2) continue; } if(g_ships && !g_player.wait_time) { for(cur1 = g_alien_list; cur1; cur1 = cur1->next) { if((g_player.region & ((ALIEN *)cur1->d)->region) && (PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_poly/*s[0]*/)) /*|| PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[1])) || PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[2]))*/)) { PlayerHit(); AlienHit(cur1, 0); break; } } } if(g_ships) { for(cur1 = g_powerup_list; cur1; cur1 = next) { next = cur1->next; if((g_player.region & ((POWERUP *)cur1->d)->region) && PolyInCircle(&g_player.clip_poly, &(((POWERUP *)cur1->d)->clip_circle))) { GetPowerup(cur1); continue; } } } }