@@ -2719,17 +2719,213 @@ Bool ScriptConditions::evaluatePlayerLostObjectType(Parameter *pPlayerParm, Para
27192719}
27202720
27212721
2722+
2723+
2724+
2725+ // -------------------------------------------------------------------------------------------------
2726+ // ------------------------------- OUR SCRIPT CONDITION ADDITIONS --------------------------------
2727+ // -------------------------------------------------------------------------------------------------
2728+
2729+
27222730Bool ScriptConditions::evaluatePlayerRelation (const AsciiString& playerSrcName, Int relationType, const AsciiString& playerDstName)
27232731{
27242732 Player* pPlayerSrcName = TheScriptEngine->getPlayerFromAsciiString (playerSrcName);
27252733 Player* pPlayerDstName = TheScriptEngine->getPlayerFromAsciiString (playerDstName);
27262734
2735+ if (!pPlayerSrcName || !pPlayerDstName) {
2736+ return false ;
2737+ }
2738+ // use the default team to get an indirect relationship between players
27272739 Team* pTeamDst = pPlayerDstName->getDefaultTeam ();
27282740
2729- if (pPlayerSrcName->getRelationship (pTeamDst) == relationType) { return true ; }
2741+ return pPlayerSrcName->getRelationship (pTeamDst) == relationType;
2742+ }
2743+
2744+ // -------------------------------------------------------------------------------------------------
2745+ Bool ScriptConditions::evaluateEmptySpot (Parameter* pStartNdx)
2746+ {
2747+ Int ndx = pStartNdx->getInt () - 1 ;
2748+ if (ndx >= 0 )
2749+ {
2750+ Int pPlayerCount = ThePlayerList->getPlayerCount ();
2751+ // iterate through all players
2752+ // i=2 because player 0 is "neutral" & player 1 is "PlyrCivilian".
2753+ // playerCount-1 to skip any possible "observer" player at the end.
2754+ for (int i = 2 ; i < pPlayerCount - 1 ; i++)
2755+ {
2756+ Player* pPlayers = ThePlayerList->getNthPlayer (i);
2757+ if (pPlayers->getMpStartIndex () == ndx)
2758+ {
2759+ return false ;
2760+ }
2761+ }
2762+ return true ;
2763+ }
27302764 return false ;
27312765}
27322766
2767+ // -------------------------------------------------------------------------------------------------
2768+ Bool ScriptConditions::evaluateNeighbouringSpot (Parameter* pPlayerParm, Parameter* pStartNdx)
2769+ {
2770+ Player* player = playerFromParam (pPlayerParm);
2771+ if (!player || pStartNdx->getInt () < 1 || pStartNdx->getInt () == player->getMpStartIndex () + 1 ) { return false ; }
2772+
2773+ // format the waypoint name for this player's start position
2774+ AsciiString pSpot;
2775+ pSpot.format (" Player_%d_Start" , player->getMpStartIndex () + 1 );
2776+
2777+ Waypoint* pWay = TheTerrainLogic->getWaypointByName (pSpot);
2778+ if (!pWay) { return false ; }
2779+
2780+ // iterate through all player start waypoints to find the closest one
2781+ Coord3D pCoords = *pWay->getLocation ();
2782+ Real minDist = FLT_MAX ;
2783+
2784+ for (Waypoint* iWay = TheTerrainLogic->getFirstWaypoint (); iWay; iWay = iWay->getNext ())
2785+ {
2786+ const AsciiString& name = iWay->getName ();
2787+ if (name.startsWith (" Player_" ) && name.endsWith (" _Start" ))
2788+ {
2789+ if (iWay != pWay)
2790+ {
2791+ Coord3D cCoords = *iWay->getLocation ();
2792+ Real dx = pCoords.x - cCoords.x ;
2793+ Real dy = pCoords.y - cCoords.y ;
2794+ Real dist = sqrtf (dx * dx + dy * dy);
2795+
2796+ if (dist < minDist) { minDist = dist; }
2797+ }
2798+ }
2799+ }
2800+ // if the closest distance still is FLT_MAX, then this is no skirmish map.
2801+ if (minDist == FLT_MAX ) { return false ; }
2802+
2803+ // consider neighbouring if within 1.5 times the closest distance.
2804+ minDist *= 1 .5f ;
2805+
2806+ // create a Waypoint for the start position to check against
2807+ AsciiString targetName;
2808+ targetName.format (" Player_%d_Start" , pStartNdx->getInt ());
2809+ Waypoint* target = TheTerrainLogic->getWaypointByName (targetName);
2810+ if (!target) { return false ; }
2811+
2812+ Coord3D tCoords = *target->getLocation ();
2813+ Real cX = pCoords.x - tCoords.x ;
2814+ Real cY = pCoords.y - tCoords.y ;
2815+ Real targetDist = sqrtf (cX * cX + cY * cY);
2816+
2817+ return targetDist <= minDist;
2818+ }
2819+
2820+ // -------------------------------------------------------------------------------------------------
2821+ Bool ScriptConditions::evaluateNeighbouringSpotsEmpty (Parameter* pPlayerParm, Parameter* pComparisonParm, Int pCountParm)
2822+ {
2823+ Player* player = playerFromParam (pPlayerParm);
2824+ Int playerCount = ThePlayerList->getPlayerCount ();
2825+ if (!player || !playerCount) { return false ; }
2826+
2827+ AsciiString pSpot;
2828+ pSpot.format (" Player_%d_Start" , player->getMpStartIndex () + 1 );
2829+ Waypoint* pWay = TheTerrainLogic->getWaypointByName (pSpot);
2830+ if (!pWay) { return false ; }
2831+
2832+
2833+ Coord3D pCoords = *pWay->getLocation ();
2834+ Real minDist = FLT_MAX ;
2835+ // iterate through all player start waypoints to find the closest one
2836+ for (Waypoint* iWay = TheTerrainLogic->getFirstWaypoint (); iWay; iWay = iWay->getNext ())
2837+ {
2838+ const AsciiString& name = iWay->getName ();
2839+ if (name.startsWith (" Player_" ) && name.endsWith (" _Start" ))
2840+ {
2841+ if (iWay != pWay)
2842+ {
2843+ Coord3D cCoords = *iWay->getLocation ();
2844+ Real dx = pCoords.x - cCoords.x ;
2845+ Real dy = pCoords.y - cCoords.y ;
2846+ Real dist = sqrtf (dx * dx + dy * dy);
2847+ if (dist < minDist)
2848+ {
2849+ minDist = dist;
2850+ }
2851+ }
2852+ }
2853+ }
2854+
2855+ std::vector<Waypoint*> neighbouringWaypoints;
2856+
2857+ // if the closest distance still is FLT_MAX, then this is no skirmish map.
2858+ if (minDist == FLT_MAX ) { return false ; }
2859+
2860+ // consider neighbouring if within 1.5 times the closest distance.
2861+ minDist *= 1 .5f ;
2862+
2863+ // find all neighbouring waypoints
2864+ for (Waypoint* iWay = TheTerrainLogic->getFirstWaypoint (); iWay; iWay = iWay->getNext ())
2865+ {
2866+ const AsciiString& name = iWay->getName ();
2867+ if (name.startsWith (" Player_" ) && name.endsWith (" _Start" ))
2868+ {
2869+ if (iWay != pWay)
2870+ {
2871+ Coord3D cCoords = *iWay->getLocation ();
2872+ Real dx = pCoords.x - cCoords.x ;
2873+ Real dy = pCoords.y - cCoords.y ;
2874+ Real dist = sqrtf (dx * dx + dy * dy);
2875+ if (dist <= minDist)
2876+ {
2877+ neighbouringWaypoints.push_back (iWay);
2878+ }
2879+ }
2880+ }
2881+ }
2882+
2883+ // Make sure that the newly found neighbouring starting points are *indeed* empty.
2884+ // i=2 because player 0 is "neutral" & player 1 is "PlyrCivilian".
2885+ // playerCount-1 to skip any possible "observer" player at the end.
2886+ for (int i = 2 ; i < playerCount - 1 ; i++) {
2887+ Int pIndex = ThePlayerList->getNthPlayer (i)->getMpStartIndex () + 1 ;
2888+ AsciiString tName;
2889+ tName.format (" Player_%d_Start" , pIndex);
2890+
2891+ for (int j = neighbouringWaypoints.size () - 1 ; j >= 0 ; j--) {
2892+ AsciiString sName = neighbouringWaypoints[j]->getName ();
2893+ if (sName == tName) {
2894+ neighbouringWaypoints.erase (neighbouringWaypoints.begin () + j);
2895+ }
2896+ }
2897+ }
2898+
2899+ // compare the new size of the neighbouring EMPTY waypoints with the given count
2900+ switch (pComparisonParm->getInt ())
2901+ {
2902+ case Parameter::LESS_THAN : return neighbouringWaypoints.size () < pCountParm;
2903+ case Parameter::LESS_EQUAL : return neighbouringWaypoints.size () <= pCountParm;
2904+ case Parameter::EQUAL : return neighbouringWaypoints.size () == pCountParm;
2905+ case Parameter::GREATER_EQUAL : return neighbouringWaypoints.size () >= pCountParm;
2906+ case Parameter::GREATER : return neighbouringWaypoints.size () > pCountParm;
2907+ case Parameter::NOT_EQUAL : return neighbouringWaypoints.size () != pCountParm;
2908+ }
2909+ return false ;
2910+ }
2911+
2912+ // -------------------------------------------------------------------------------------------------
2913+ Bool ScriptConditions::evaluateClosestEnemyUnit (Parameter* pPlayerParm, Parameter* pComparisonParm, Int pDistanceParm)
2914+ {
2915+ Player* player = playerFromParam (pPlayerParm);
2916+ if (!player) { return false ; }
2917+ return false ;
2918+ }
2919+
2920+
2921+ // -------------------------------------------------------------------------------------------------
2922+ // ------------------------------ OUR SCRIPT CONDITION ADDITIONS END -------------------------------
2923+ // -------------------------------------------------------------------------------------------------
2924+
2925+
2926+
2927+
2928+
27332929// -------------------------------------------------------------------------------------------------
27342930/* * Evaluate a condition */
27352931// -------------------------------------------------------------------------------------------------
@@ -2997,7 +3193,13 @@ Bool ScriptConditions::evaluateCondition( Condition *pCondition )
29973193
29983194 case Condition::RELATION_IS :
29993195 return evaluatePlayerRelation (pCondition->getParameter (0 )->getString (), pCondition->getParameter (1 )->getInt (), pCondition->getParameter (2 )->getString ());
3000-
3196+ case Condition::SPOT_EMPTY :
3197+ return evaluateEmptySpot (pCondition->getParameter (0 ));
3198+ case Condition::SPOT_NEIGHBOURING :
3199+ return evaluateNeighbouringSpot (pCondition->getParameter (0 ), pCondition->getParameter (1 ));
3200+ case Condition::NEIGHBOURING_SPOTS_EMPTY :
3201+ return evaluateNeighbouringSpotsEmpty (pCondition->getParameter (0 ), pCondition->getParameter (1 ), pCondition->getParameter (2 )->getInt ());
3202+
30013203 }
30023204}
30033205
0 commit comments