diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html index 38e2ce670..213015621 100644 --- a/doc/ChangeLog.html +++ b/doc/ChangeLog.html @@ -739,6 +739,7 @@ <LI>Fixed bug #498350: Goblin Sappers didn't support follow. <LI>CD player support with libcda. (from Nehal) <LI>Rescued units keeps their player color. + <LI>Added trigger for bringing rescued units to a point. <LI>+++ </UL> </UL> diff --git a/src/game/trigger.cpp b/src/game/trigger.cpp index 703c791e1..47a917342 100644 --- a/src/game/trigger.cpp +++ b/src/game/trigger.cpp @@ -256,6 +256,86 @@ local SCM CclIfNearUnit(SCM player,SCM quantity,SCM unit,SCM near) return SCM_BOOL_F; } +/** +** Player has the quantity of rescued unit-type near to unit-type. +*/ +local SCM CclIfRescuedNearUnit(SCM player,SCM quantity,SCM unit,SCM near) +{ + int plynr; + int q; + int n; + int i; + const UnitType* unittype; + const UnitType* ut2; + Unit* table[UnitMax]; + + plynr=TriggerGetPlayer(player); + q=gh_scm2int(quantity); + unittype=TriggerGetUnitType(unit); + ut2=CclGetUnitType(near); + + // + // Get all unit types 'near'. + // + n=FindUnitsByType(ut2,table); + DebugLevel3Fn("%s: %d\n",ut2->Ident,n); + for( i=0; i<n; ++i ) { + Unit* unit; + Unit* around[UnitMax]; + int an; + int j; + int s; + + unit=table[i]; + +#ifdef UNIT_ON_MAP + // FIXME: could be done faster? +#endif + // FIXME: I hope SelectUnits checks bounds? + // FIXME: Yes, but caller should check. + // NOTE: +1 right,bottom isn't inclusive :( + if( unit->Type->UnitType==UnitTypeLand ) { + an=SelectUnits( + unit->X-1,unit->Y-1, + unit->X+unit->Type->TileWidth+1, + unit->Y+unit->Type->TileHeight+1,around); + } else { + an=SelectUnits( + unit->X-2,unit->Y-2, + unit->X+unit->Type->TileWidth+2, + unit->Y+unit->Type->TileHeight+2,around); + } + DebugLevel3Fn("Units around %d: %d\n",UnitNumber(unit),an); + // + // Count the requested units + // + for( j=s=0; j<an; ++j ) { + unit=around[j]; + if( unit->Rescued ) { // only rescued units + // + // Check unit type + // + if( (unittype==ANY_UNIT && unittype==ALL_UNITS) + || (unittype==ALL_FOODUNITS && !unit->Type->Building) + || (unittype==ALL_BUILDINGS && unit->Type->Building) + || (unittype==unit->Type) ) { + // + // Check the player + // + if( plynr==-1 || plynr==unit->Player->Player ) { + ++s; + } + } + } + } + if( s==q ) { + return SCM_BOOL_T; + } + } + + return SCM_BOOL_F; +} + /** ** Player has n opponents left. */ @@ -387,6 +467,7 @@ global void TriggerCclRegister(void) // Conditions gh_new_procedure3_0("if-unit",CclIfUnit); gh_new_procedure4_0("if-near-unit",CclIfNearUnit); + gh_new_procedure4_0("if-rescued-near-unit",CclIfRescuedNearUnit); gh_new_procedure2_0("if-opponents",CclIfOpponents); // Actions gh_new_procedure0_0("action-victory",CclActionVictory); diff --git a/src/include/unit.h b/src/include/unit.h index a22e83635..1feb0c3f9 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -464,9 +464,9 @@ struct _unit_ { int X; /// Map position X int Y; /// Map position Y - UnitType* Type; /// pointer to unit-type (peon,...) - Player* Player; /// owner of this unit - UnitStats* Stats; /// current unit stats + UnitType* Type; /// Pointer to unit-type (peon,...) + Player* Player; /// Owner of this unit + UnitStats* Stats; /// Current unit stats // DISPLAY: UnitColors Colors; /// Player colors @@ -484,9 +484,10 @@ struct _unit_ { unsigned Removed : 1; /// unit is removed (not on map) unsigned Selected : 1; /// unit is selected - unsigned Visible : 16; /// unit is visible (submarine) - unsigned Constructed : 1; /// unit is in construction - unsigned Active : 1; /// unit is active for AI + unsigned Visible : 16; /// Unit is visible (submarine) + unsigned Constructed : 1; /// Unit is in construction + unsigned Active : 1; /// Unit is active for AI + unsigned Rescued : 1; /// Unit is rescued #define MaxMana 255 /// maximal mana for units unsigned Mana : 8; /// mana points diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index bfa53d630..46576fa6b 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -1448,6 +1448,8 @@ local void ChangePlayerOwner(Player* oldplayer,Player* newplayer) for( i=0; i<n; i++ ) { unit=table[i]; ChangeUnitOwner(unit,oldplayer,newplayer); + unit->Blink=5; + unit->Rescued=1; } } @@ -1517,6 +1519,8 @@ global void RescueUnits(void) if( around[i]->Type->CanAttack && IsAllied(unit->Player,around[i]) ) { ChangeUnitOwner(unit,unit->Player,around[i]->Player); + unit->Blink=5; + unit->Rescued=1; // FIXME: more races? if( unit->Player->Race==PlayerRaceHuman ) { PlayGameSound(GameSounds.HumanRescue.Sound