/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 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, see .
*
*/
//Filename : OPOWER.CPP
//Description : Object Power
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//-------------- Define constant -----------------//
#define DETECT_SPREAD 3
static short nation_divide_order[MAX_NATION+1] = {1, 2, 3, 4, 5, 6, 7, 0};
//-------- Begin of static function divide_by_nation --------//
static void divide_by_nation(short *nationUnitCount, short *selectedArray, int selectedCount)
{
short *orderedArray = (short*) mem_add(sizeof(short)*selectedCount);
short *nationOrderPtr = nation_divide_order;
short unitCount = 0;
short *selectedUnitPtr;
Unit *unitPtr;
int i, j;
for(i=0; i<=MAX_NATION; ++i, nationOrderPtr++)
{
for(j=0, selectedUnitPtr=selectedArray; jnation_recno == *nationOrderPtr)
orderedArray[unitCount++] = *selectedUnitPtr;
}
err_when(unitCount>selectedCount);
nationUnitCount[i] = unitCount;
if(i= ZOOM_X1 && mouse.cur_x <= ZOOM_X2 &&
mouse.cur_y >= ZOOM_Y1 && mouse.cur_y <= ZOOM_Y2 &&
(pointingLoc = test_detect(mouse.cur_x, mouse.cur_y))!= NULL)
{
// ------- pointing something -------//
short pointingRecno;
ScreenObjectType pointingType = find_pointing_type(pointingLoc, &pointingRecno);
mouse_cursor.set_icon( choose_cursor(mouse.cur_x, mouse.cur_y,
selectedType, selectedRecno, pointingType, pointingRecno) );
}
else
mouse_cursor.set_icon( choose_cursor(mouse.cur_x, mouse.cur_y,
selectedType, selectedRecno, SCREEN_OBJECT_NONE, 0) );
//---- pressing right button in command mode -> cancel command mode ----//
if( mouse.right_press && command_id )
{
command_id = 0;
info.disp();
return;
}
/*
//------ detect selecting objects and laying tracks ------//
if( detect_frame() )
return;
//----- detect right mouse button to select defined unit groups -----//
int shiftPressed = GetKeyState(VK_SHIFT) & 0X0100; // return the current real-time key state
if( mouse.right_press && !shiftPressed ) // shift key to override the standard selection action and go for attacking own units
{
if( mouse.cur_x >= ZOOM_X1 && mouse.cur_x <= ZOOM_X2 && // if the mouse is inside the zoom area
mouse.cur_y >= ZOOM_Y1 && mouse.cur_y <= ZOOM_Y2 )
{
if( detect_select( mouse.cur_x, mouse.cur_y,
mouse.cur_x, mouse.cur_y, 1 ) ) // 1-recall group
{
return;
}
}
}
//----------- detect action ------------//
// ##### begin Gilbert 29/5 ########//
if( detect_action() && unit_array.selected_recno )
{
if( se_res.mark_command_time() )
{
Unit *unitPtr = unit_array[unit_array.selected_recno];
se_res.far_sound( unitPtr->cur_x_loc(), unitPtr->cur_y_loc(), 1, 'S',
unitPtr->sprite_id, "ACK");
}
}
// ##### end Gilbert 29/5 ########//
*/
}
//--------- End of function Power::mouse_handler ---------//
//-------- Begin of function Power::detect_frame --------//
//
// Detect selecting objects or laying tracks with the mouse
// selection frame.
//
// return: 1 - objects selected or tracks built.
// 0 - nothing selected or built.
//
int Power::detect_frame()
{
//----- detect left mouse button to activate frame selection -----//
int rc=0, selectedCount=0;
Location* locPtr;
if( mouse.is_mouse_event() )
{
if( mouse.mouse_event_type == LEFT_BUTTON )
{
int mouseX = mouse.click_x(LEFT_BUTTON);
int mouseY = mouse.click_y(LEFT_BUTTON);
if( !mouse_cursor.frame_flag )
{
if( mouseX >= ZOOM_X1 && mouseX <= ZOOM_X2 && // if the mouse is inside the zoom area
mouseY >= ZOOM_Y1 && mouseY <= ZOOM_Y2 )
{
int curXLoc = world.zoom_matrix->top_x_loc + (mouseX-ZOOM_X1)/ZOOM_LOC_WIDTH;
int curYLoc = world.zoom_matrix->top_y_loc + (mouseY-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
locPtr = world.get_loc(curXLoc, curYLoc);
//-------- set boundary of mouse -------//
mouse.set_boundary(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2);
//------- activate frame selection --------//
switch(command_id)
{
case COMMAND_BUILD_FIRM:
if(!unit_array.is_deleted(command_unit_recno) && unit_array[command_unit_recno]->is_visible())
{
Unit *cmdUnit = unit_array[command_unit_recno];
if( se_res.mark_command_time() )
{
se_res.far_sound( cmdUnit->cur_x_loc(), cmdUnit->cur_y_loc(), 1,
'S', cmdUnit->sprite_id, "ACK" );
}
cmdUnit->build_firm(curXLoc, curYLoc, command_para, COMMAND_PLAYER);
}
command_id = 0;
rc = 1;
info.disp();
break;
case COMMAND_BURN:
if(!unit_array.is_deleted(command_unit_recno) && unit_array[command_unit_recno]->is_visible())
{
Unit *cmdUnit = unit_array[command_unit_recno];
if( se_res.mark_command_time() )
{
se_res.far_sound( cmdUnit->cur_x_loc(), cmdUnit->cur_y_loc(), 1,
'S', cmdUnit->sprite_id, "ACK" );
}
cmdUnit->burn(curXLoc, curYLoc, COMMAND_PLAYER);
}
command_id = 0;
rc = 1;
break;
case COMMAND_SETTLE:
if( se_res.mark_command_time() )
{
Unit *repUnit = unit_array[unit_array.selected_recno];
se_res.far_sound( repUnit->cur_x_loc(), repUnit->cur_y_loc(), 1,
'S', repUnit->sprite_id, "ACK");
}
if( locPtr->is_town() && town_array[locPtr->town_recno()]->nation_recno == unit_array[unit_array.selected_recno]->nation_recno )
{
Town *townPtr = town_array[locPtr->town_recno()];
unit_array.assign(townPtr->loc_x1, townPtr->loc_y1, 0, COMMAND_PLAYER ); // assign to an existing town
}
else
unit_array.settle(curXLoc, curYLoc, 0, COMMAND_PLAYER); // settle as a new town
command_id = 0;
rc = 1;
info.disp();
break;
case COMMAND_SET_CARAVAN_STOP:
if(unit_array[command_unit_recno]->is_visible())
{
UnitCaravan* unitPtr = (UnitCaravan*) unit_array[command_unit_recno];
err_when( unitPtr->unit_id != UNIT_CARAVAN );
// find the firm it is pointing
Location *locPtr = world.get_loc(curXLoc, curYLoc);
Firm *firmPtr;
if( locPtr->is_firm() && (firmPtr = firm_array[locPtr->firm_recno()])
&& unitPtr->can_set_stop(firmPtr->firm_recno) )
{
if( se_res.mark_command_time() )
{
se_res.far_sound( unitPtr->cur_x_loc(), unitPtr->cur_y_loc(), 1,
'S', unitPtr->sprite_id, "ACK");
}
unitPtr->set_stop(command_para, curXLoc, curYLoc, COMMAND_PLAYER); // command_para is the id. of the stop
}
}
command_id = 0;
rc = 1;
break;
case COMMAND_SET_SHIP_STOP:
if(unit_array[command_unit_recno]->is_visible())
{
UnitMarine* unitPtr = (UnitMarine*) unit_array[command_unit_recno];
err_when( unit_res[unitPtr->unit_id]->mobile_type != UNIT_SEA );
// find the firm it is pointing
Location *locPtr = world.get_loc(curXLoc, curYLoc);
Firm *firmPtr;
if( locPtr->is_firm() && (firmPtr = firm_array[locPtr->firm_recno()])
&& unitPtr->can_set_stop(firmPtr->firm_recno) )
{
if( se_res.mark_command_time() )
{
se_res.far_sound( unitPtr->cur_x_loc(), unitPtr->cur_y_loc(), 1,
'S', unitPtr->sprite_id, "ACK");
}
unitPtr->set_stop(command_para, curXLoc, curYLoc, COMMAND_PLAYER); // command_para is the id. of the stop
}
}
command_id = 0;
rc = 1;
break;
case COMMAND_BUILD_WALL:
world.build_wall_tile(curXLoc, curYLoc, nation_array.player_recno, COMMAND_PLAYER);
rc = 1;
break;
case COMMAND_DESTRUCT_WALL:
world.destruct_wall_tile(curXLoc, curYLoc, nation_array.player_recno, COMMAND_PLAYER);
rc = 1;
break;
case COMMAND_GOD_CAST_POWER:
if(!unit_array.is_deleted(command_unit_recno) && unit_array[command_unit_recno]->is_visible())
{
Unit *cmdUnit = unit_array[command_unit_recno];
if( se_res.mark_command_time() )
{
Unit *repUnit = unit_array[unit_array.selected_recno];
se_res.far_sound( repUnit->cur_x_loc(), repUnit->cur_y_loc(), 1,
'S', repUnit->sprite_id, "ACK");
}
// ###### begin Gilbert 14/10 ########//
cmdUnit->go_cast_power(curXLoc, curYLoc, command_para, COMMAND_PLAYER);
// ###### end Gilbert 14/10 ########//
}
command_id = 0;
rc = 1;
break;
default:
if( !mouse_cursor.frame_flag )
{
mouse_cursor.set_frame(1, 0);
mouse_cursor.process(mouseX, mouseY);
}
else
mouse_cursor.set_frame(1, 0);
}
}
}
if( mouseX >= MAP_X1 && mouseX <= MAP_X2 && // if the mouse is inside the zoom area
mouseY >= MAP_Y1 && mouseY <= MAP_Y2 )
{
mouse.set_boundary(MAP_X1, MAP_Y1, MAP_X2, MAP_Y2);
}
}
//------- the selection action is complete --------//
else if( mouse.mouse_event_type == LEFT_BUTTON_RELEASE)
{
int mouseX = mouse.click_x(LEFT_BUTTON);
int mouseY = mouse.click_y(LEFT_BUTTON);
int mouseReleaseX = mouse.release_x(LEFT_BUTTON);
int mouseReleaseY = mouse.release_y(LEFT_BUTTON);
//-------- reset boundary of mouse -------//
mouse.reset_boundary();
if( mouse_cursor.frame_flag )
{
mouse_cursor.process(mouseReleaseX, mouseReleaseY);
mouse_cursor.set_frame(0);
rc = detect_select( mouse_cursor.frame_x1, mouse_cursor.frame_y1,
mouse_cursor.frame_x2, mouse_cursor.frame_y2,
0, mouse.event_skey_state & SHIFT_KEY_MASK);
}
}
}
else
{
// no mouse event but keep pressing left button
if( mouse.left_press )
{
if( mouse_cursor.frame_flag )
{
mouse_cursor.process(mouse.cur_x, mouse.cur_y);
}
}
else
{
mouse_cursor.set_frame(0);
}
}
return rc;
}
//--------- End of function Power::detect_frame ---------//
//-------- Begin of function Power::detect_action --------//
//
// return: 1 - action executed.
// 0 - no action ordered.
//
int Power::detect_action()
{
if( !mouse.has_mouse_event || mouse.mouse_event_type != RIGHT_BUTTON || !nation_array.player_recno)
return 0;
int curXLoc, curYLoc;
// int shiftPressed = GetKeyState(VK_SHIFT) & 0X0100; // return the current real-time key state
int shiftPressed = mouse.event_skey_state & SHIFT_KEY_MASK;
int mouseX = mouse.click_x(RIGHT_BUTTON);
int mouseY = mouse.click_y(RIGHT_BUTTON);
//--------- if click on the zoom window --------//
if( mouseX >= ZOOM_X1 && mouseX <= ZOOM_X2 && // if the mouse is inside the zoom area
mouseY >= ZOOM_Y1 && mouseY <= ZOOM_Y2 )
{
curXLoc = world.zoom_matrix->top_x_loc + (mouseX-ZOOM_X1)/ZOOM_LOC_WIDTH;
curYLoc = world.zoom_matrix->top_y_loc + (mouseY-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
}
//---------- if click on the map window -----------//
else if( mouseX >= MAP_X1 && mouseX <= MAP_X2 && // if the mouse is inside the zoom area
mouseY >= MAP_Y1 && mouseY <= MAP_Y2 )
{
curXLoc = world.map_matrix->top_x_loc + (mouseX-MAP_X1);
curYLoc = world.map_matrix->top_y_loc + (mouseY-MAP_Y1);
}
else
{
return 0;
}
//-------- find out how many units have been selected --------//
int selectedCount=0;
short* selectedArray;
Unit* unitPtr;
selectedArray = (short*) mem_add( sizeof(short) * unit_array.size() );
int i;
for( i=unit_array.size() ; i>0 ; i-- )
{
if( unit_array.is_deleted(i) )
continue;
unitPtr = unit_array[i];
if(unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE)
continue;
if( !unitPtr->selected_flag || !unitPtr->is_visible() )
continue;
if( !unitPtr->is_own() ) // only if the unit belongs to us (a spy is also okay if true_nation_recno is ours)
continue;
selectedArray[selectedCount++] = i;
}
//### begin alex 16/10 ###//
if((mouse.event_skey_state & ALT_KEY_MASK))
{
unit_array.add_way_point(curXLoc, curYLoc, selectedArray, selectedCount, COMMAND_PLAYER);
mem_del(selectedArray);
return 1;
}
//#### end alex 16/10 ####//
if( selectedCount==0 ) // no unit selected
{
mem_del(selectedArray);
return 0;
}
//----- get the info of the clicked location ------//
Location* locPtr=test_detect(mouse.cur_x, mouse.cur_y);
Unit *targetUnit=NULL, *targetShip=NULL, *targetAirUnit=NULL;
Firm* targetFirm=NULL;
Town* targetTown=NULL;
char targetWall=0;
Unit* activeUnit = unit_array[selectedArray[0]];
int mobileType = activeUnit->mobile_type; // mobile type of the selected units
int targetMobileType=0;
short nationRecno = activeUnit->nation_recno;
int retFlag = 0;
if( locPtr )
{
//targetMobileType = locPtr->has_any_unit(mobileType);
targetMobileType = locPtr->has_any_unit();
if(targetMobileType)
{
switch(targetMobileType)
{
case UNIT_LAND:
targetUnit = unit_array[locPtr->unit_recno(targetMobileType)];
err_when(!targetUnit->is_visible());
break;
case UNIT_SEA:
targetShip = unit_array[locPtr->unit_recno(targetMobileType)];
err_when(!targetShip->is_visible());
break;
case UNIT_AIR:
targetAirUnit = unit_array[locPtr->unit_recno(targetMobileType)];
err_when(!targetAirUnit->is_visible());
break;
default: err_here();
break;
}
}
else if( locPtr->is_firm() )
targetFirm = firm_array[locPtr->firm_recno()];
else if( locPtr->is_town() )
targetTown = town_array[locPtr->town_recno()];
else if( locPtr->is_wall() )
targetWall = 1;
}
//--------------- divide by nation ---------------//
static short nationUnitCount[MAX_NATION+1]; // plus one for independent nation
short *nationUnitCountPtr = nationUnitCount;
divide_by_nation(nationUnitCountPtr, selectedArray, selectedCount);
//------------- process action for each nation -------------//
nationUnitCountPtr = nationUnitCount;
Nation *nationPtr;
short *nationSelectedArray;
short nationSelectedCount;
int isHuman;
for(int natCount=0, preNatCount=0; natCount<=MAX_NATION; natCount++, nationUnitCountPtr++)
{
if(!(*nationUnitCountPtr) || (*nationUnitCountPtr)==preNatCount)
continue; // no unit in this nation
nationSelectedArray = selectedArray + preNatCount;
nationSelectedCount = *nationUnitCountPtr - preNatCount;
preNatCount = *nationUnitCountPtr;
nationPtr = (nation_divide_order[natCount]) ? nation_array[nation_divide_order[natCount]] : NULL;
//---------- if the target is a unit -----------//
//### begin alex 19/3 ###//
//activeUnit = unit_array[nationSelectedArray[0]]; // update activeUnit for each nation
activeUnit = unit_array[select_active_unit(nationSelectedArray, nationSelectedCount)]; // update activeUnit for each nation
//#### end alex 19/3 ####//
isHuman = unit_res[activeUnit->unit_id]->race_id > 0; // whether the unit can be assigned to firms and towns
if(targetMobileType)
{
if(targetUnit && targetUnit->hit_points>0)
{
//--- embarking horse/elephants, when targetUnit->nation_recno==0, the unit is an animal ---//
if( unit_res[activeUnit->unit_id]->vehicle_id == targetUnit->unit_id )
{
unit_array.assign(targetUnit->next_x_loc(), targetUnit->next_y_loc(), 0, COMMAND_PLAYER, nationSelectedArray, nationSelectedCount );
retFlag = 1;
}
else if( !targetUnit->is_own() )
{
if( nationPtr && nationPtr->get_relation_should_attack(targetUnit->nation_recno)
&& activeUnit->attack_count > 0 ) // Units like Phoenix that can't attack will call move_to() instead of calling attack()
{
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetUnit->next_x_loc(), targetUnit->next_y_loc(), 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, targetUnit->sprite_recno);
}
else
{
unit_array.move_to(curXLoc, curYLoc, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER);
}
retFlag = 1;
}
else if( targetUnit->is_own() && targetUnit->unit_id == UNIT_EXPLOSIVE_CART && shiftPressed)
{
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetUnit->next_x_loc(), targetUnit->next_y_loc(), 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, targetUnit->sprite_recno);
retFlag = 1;
}
// else, right click on other land unit, it is team select
}
else if(targetShip && targetShip->hit_points>0)
{
if(targetShip->is_own() )
{
if(unit_res[targetShip->unit_id]->carry_unit_capacity>0)
{
// ##### patch begin Gilbert 5/8 #######//
unit_array.assign_to_ship(targetShip->next_x_loc(), targetShip->next_y_loc(), 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, targetShip->sprite_recno );
// ##### patch end Gilbert 5/8 #######//
}
}
else
{
if( nationPtr && nationPtr->get_relation_should_attack(targetShip->nation_recno)
&& activeUnit->attack_count > 0 ) // Units like Phoenix that can't attack will call move_to() instead of calling attack()
{
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetShip->next_x_loc(), targetShip->next_y_loc(), 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, targetShip->sprite_recno);
}
else
{
unit_array.move_to(curXLoc, curYLoc, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER);
}
}
retFlag = 1;
}
else if(targetAirUnit && targetAirUnit->hit_points>0)
{
if( nationPtr && nationPtr->get_relation_should_attack(targetAirUnit->nation_recno)
&& activeUnit->attack_count > 0 ) // Units like Phoenix that can't attack will call move_to() instead of calling attack()
{
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetAirUnit->next_x_loc(), targetAirUnit->next_y_loc(), 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, targetAirUnit->sprite_recno);
}
else
{
unit_array.move_to(curXLoc, curYLoc, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER);
}
retFlag = 1;
}
}
else if(targetFirm && targetFirm->hit_points>0)
{
//-------- if this firm does not belong to the player -------//
int assignedFlag=0;
if( ( ( nationPtr && nationPtr->get_relation_should_attack(targetFirm->nation_recno) )
|| shiftPressed ) && activeUnit->attack_count > 0 ) // Units like Phoenix that can't attack will call move_to() instead of calling attack()
{
//------------ attack the firm -------------//
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetFirm->loc_x1, targetFirm->loc_y1, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, 0);
}
else
{
//------------ filtering for firm_can_assign() ---------------//
int canAssign;
if(targetFirm->firm_id==FIRM_BASE)
{
canAssign = 0;
Unit *selectedUnit;
for(int i=0; ifirm_can_assign(targetFirm->firm_recno))
if( unit_can_assign_firm(nationSelectedArray[i], targetFirm->firm_recno, nation_array.player_recno) )
// ####### end Gilbert 22/10 #########//
{
canAssign = 1;
break;
}
}
}
else
// ####### begin Gilbert 22/10 #########//
// canAssign = activeUnit->firm_can_assign(targetFirm->firm_recno);
canAssign = unit_can_assign_firm(activeUnit->sprite_recno, targetFirm->firm_recno, nation_array.player_recno);
// ####### begin Gilbert 22/10 #########//
if( canAssign && (isHuman || targetFirm->firm_id==FIRM_CAMP) )
{
//### begin alex 19/3 ###//
err_when(targetFirm->nation_recno != activeUnit->nation_recno);
//#### end alex 19/3 ####//
//----- if own firm, assign the unit to the firm ----//
if(targetFirm->firm_id==FIRM_CAMP)
unit_array.assign_to_camp(targetFirm->loc_x1, targetFirm->loc_y1, COMMAND_PLAYER, nationSelectedArray, nationSelectedCount);
else
unit_array.assign(targetFirm->loc_x1, targetFirm->loc_y1, 0, COMMAND_PLAYER, nationSelectedArray, nationSelectedCount);
}
//### begin alex 19/3 ###//
//else if( activeUnit->mobile_type == UNIT_SEA && targetFirm->firm_id == FIRM_HARBOR )
else if( canAssign && activeUnit->mobile_type == UNIT_SEA && targetFirm->firm_id == FIRM_HARBOR )
{
err_when(targetFirm->nation_recno != activeUnit->nation_recno);
//#### end alex 19/3 ####//
//----- if the selected are marine units -----//
unit_array.assign(targetFirm->loc_x1, targetFirm->loc_y1, 0, COMMAND_PLAYER, nationSelectedArray, nationSelectedCount);
}
else
{
//------- if no other action executed, move to the clicked location ------//
unit_array.move_to(curXLoc, curYLoc, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER);
}
}
retFlag = 1;
}
else if(targetTown)
{
if( activeUnit->spy_recno && activeUnit->nation_recno == targetTown->nation_recno )
{
//------ if the player is sending a spy into the town ------//
unit_array.assign(targetTown->loc_x1, targetTown->loc_y1, 0, COMMAND_PLAYER, nationSelectedArray, nationSelectedCount);
}
else if( isHuman && targetTown->nation_recno == nation_array.player_recno ) // assign to the firm
{
//----- assign units into a town in a normal operation -----//
//--- divide the array, non-skill peasant units are assigned to towns, skilled, soldiers and generals are not assigned to town, they just move close to the town ---//
short* moveArray = (short*) mem_add( sizeof(short) * nationSelectedCount );
short* assignArray = (short*) mem_add( sizeof(short) * nationSelectedCount );
int moveCount=0, assignCount=0;
for( i=0 ; imobile_type==UNIT_LAND && unitPtr->rank_id==RANK_SOLDIER && unitPtr->skill.skill_id<=0)
assignArray[assignCount++] = nationSelectedArray[i];
else
moveArray[moveCount++] = nationSelectedArray[i];
}
if( moveCount > 0 )
unit_array.move_to(targetTown->loc_x1, targetTown->loc_y1, 0, moveArray, moveCount, COMMAND_PLAYER);
if( assignCount > 0 )
{
//### begin alex 19/3 ###//
err_when(targetTown->nation_recno != activeUnit->nation_recno);
//#### end alex 19/3 ####//
unit_array.assign(targetTown->loc_x1, targetTown->loc_y1, 0, COMMAND_PLAYER, assignArray, assignCount);
}
mem_del(moveArray);
mem_del(assignArray);
}
else if( nationPtr && nationPtr->get_relation_should_attack(targetTown->nation_recno)
&& activeUnit->attack_count > 0 ) // Units like Phoenix that can't attack will call move_to() instead of calling attack()
{
//--------- attack the town ------------//
if(nation_array.player_recno==nation_divide_order[natCount])
unit_array.attack(targetTown->loc_x1, targetTown->loc_y1, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER, 0);
}
else
unit_array.move_to(curXLoc, curYLoc, 0, nationSelectedArray, nationSelectedCount, COMMAND_PLAYER);
retFlag = 1;
}
else
{
//--------- if no target selected, just move to the clicked location --------//
//---- if double-click, force move ------//
if( mouse.click_count(RIGHT_BUTTON) > 1 )
{
if( !remote.is_enable() )
{
for( int j=0 ; jforce_move_flag = 1;
}
else
{
short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_SET_FORCE_MOVE, sizeof(short)*(1+nationSelectedCount) );
// packet structure : ...
*shortPtr = nationSelectedCount;
++shortPtr;
for( int j=0 ; j selectedCount);
}
mem_del(selectedArray);
return retFlag;
}
//--------- End of function Power::detect_action ---------//
//------ Begin of function Power::test_detect -------//
//
// Test detect if there is an object at where the mouse cursor
// is currently pointing at.
//
// return: The pointer to the location with a sprite or firm
// being detected.
// NULL - no sprite detected.
// mobileType UNIT_AIR or UNIT_LAND (don't return UNIT_SEA)
//
Location* Power::test_detect(int curX, int curY, char *mobileType)
{
char dummy, tempMobileType;
if( !mobileType )
mobileType = &dummy;
//---- only proceed if the mouse cursor is inside the zoom map area ---//
if( curX < ZOOM_X1 || curX > ZOOM_X2 || // if the mouse is inside the zoom area
curY < ZOOM_Y1 || curY > ZOOM_Y2 )
{
return NULL;
}
//------ if mouse cursor is pointing at a firm, return now ------//
int curXLoc = world.zoom_matrix->top_x_loc + (curX-ZOOM_X1)/ZOOM_LOC_WIDTH;
int curYLoc = world.zoom_matrix->top_y_loc + (curY-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
Location* locPtr = world.get_loc(curXLoc,curYLoc);
//---- expand the area outwards to cover sprites that are in their way moving into the area
int detectSpread = mouse.skey_state & CONTROL_KEY_MASK ? 0 : DETECT_SPREAD;
int selXLoc1=max(0, curXLoc-detectSpread); // expand 2 tiles in case of big sprite
int selYLoc1=max(0, curYLoc-detectSpread);
int selXLoc2=min(MAX_WORLD_X_LOC-1, curXLoc+detectSpread);
int selYLoc2=min(MAX_WORLD_Y_LOC-1, curYLoc+detectSpread);
//---------- select sprite --------------//
int xLoc, yLoc;
Unit *unitPtr;
int absCurX = curX-ZOOM_X1+World::view_top_x; // the mouse cursor's absolute position on the whole world map
int absCurY = curY-ZOOM_Y1+World::view_top_y;
Location* retLoc = NULL;
// first pass : scan air unit
for( yLoc=selYLoc1 ; yLoc<=selYLoc2 ; yLoc++ )
{
locPtr = world.get_loc(selXLoc1, yLoc);
for( xLoc=selXLoc1 ; xLoc<=selXLoc2 ; xLoc++, locPtr++ )
{
if( locPtr->has_unit(UNIT_AIR) && !unit_array.is_deleted(locPtr->air_cargo_recno) ) // if the mouse does not click directly on a sprite
{
unitPtr = unit_array[locPtr->air_cargo_recno];
tempMobileType = UNIT_AIR;
err_when(!unitPtr->is_visible());
err_when( unitPtr->mobile_type != UNIT_AIR );
}
else
unitPtr = NULL;
//----- there is a sprite in the location -----//
if( unitPtr && !unitPtr->is_shealth() )
{
unitPtr->update_abs_pos();
if( absCurX >= unitPtr->abs_x1 && absCurY >= unitPtr->abs_y1 &&
absCurX <= unitPtr->abs_x2 && absCurY <= unitPtr->abs_y2 )
{
retLoc = locPtr;
*mobileType = tempMobileType;
}
}
}
}
if( retLoc )
return retLoc;
// -------- second pass : scan land firm/town/wall --------//
locPtr = world.get_loc(curXLoc, curYLoc);
if( locPtr->is_firm() || locPtr->is_town() || locPtr->is_wall() )
{
*mobileType = UNIT_LAND;
return locPtr;
}
//---------- third pass : scan land unit -------------//
for( yLoc=selYLoc1 ; yLoc<=selYLoc2 ; yLoc++ )
{
locPtr = world.get_loc(selXLoc1,yLoc);
for( xLoc=selXLoc1 ; xLoc<=selXLoc2 ; xLoc++, locPtr++ )
{
if( (locPtr->has_unit(UNIT_LAND) || locPtr->has_unit(UNIT_SEA))
&& !unit_array.is_deleted(locPtr->cargo_recno) ) // if the mouse does not click directly on a sprite
{
unitPtr = unit_array[locPtr->cargo_recno];
tempMobileType = UNIT_LAND;
err_when(!unitPtr->is_visible());
}
else
unitPtr = NULL;
//----- there is a sprite in the location -----//
if( unitPtr && !unitPtr->is_shealth() )
{
unitPtr->update_abs_pos();
if( absCurX >= unitPtr->abs_x1 && absCurY >= unitPtr->abs_y1 &&
absCurX <= unitPtr->abs_x2 && absCurY <= unitPtr->abs_y2 )
{
retLoc = locPtr;
*mobileType = tempMobileType;
}
}
}
}
return retLoc;
}
//------ End of function Power::test_detect -------//
//------ Begin of function Power::detect_select -------//
//
// This function is called when the mouse has been clicked,
// this function will select the objects inside the mouse selection area,
// and deselect previously selected objects.
//
// selX1, selY1, selX2, selY2 - the positions of the selection box
//
// recallGroup - recall selection of the defined group to which the
// selected unit belongs
//
// shiftSelect - add/remove individual selected unit
//
// return : >0 - no. of units or firms selected
// 0 - no unit or firm detected in the rectd area.
//
int Power::detect_select(int selX1, int selY1, int selX2, int selY2, int recallGroup, int shiftSelect)
{
int topXLoc = world.zoom_matrix->top_x_loc;
int topYLoc = world.zoom_matrix->top_y_loc;
int selXLoc1 = topXLoc + (selX1-ZOOM_X1)/ZOOM_LOC_WIDTH;
int selYLoc1 = topYLoc + (selY1-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
int selXLoc2 = topXLoc + (selX2-ZOOM_X1)/ZOOM_LOC_WIDTH;
int selYLoc2 = topYLoc + (selY2-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
int firstXLoc = selXLoc1, firstYLoc = selYLoc1; // first location to be tested
//-- expand the area outwards to cover sprites that are in their way moving into the area
selXLoc1=max(0, selXLoc1-DETECT_SPREAD); // expand 2 tiles in case of big sprite
selYLoc1=max(0, selYLoc1-DETECT_SPREAD);
selXLoc2=min(MAX_WORLD_X_LOC-1,selXLoc2+DETECT_SPREAD);
selYLoc2=min(MAX_WORLD_Y_LOC-1,selYLoc2+DETECT_SPREAD);
//------ calc absolute positions for fast comparsion ---//
int absSelX1 = selX1-ZOOM_X1+World::view_top_x; // the mouse cursor's absolute position on the whole world map
int absSelY1 = selY1-ZOOM_Y1+World::view_top_y;
int absSelX2 = selX2-ZOOM_X1+World::view_top_x;
int absSelY2 = selY2-ZOOM_Y1+World::view_top_y;
// int shiftSelect = GetKeyState(VK_SHIFT) & 0X0100; // return the current real-time key state
int selectOneOnly = abs(selX1-selX2)<=3 && abs(selY1-selY2)<=3;
//---------- select sprite --------------//
int selectedCount=0; // whether any sprite has been selected.
int xLoc, yLoc;
Location *locPtr;
Unit *unitPtr;
int i;
int selectedSiteRecno=0; //, selectedUnitRecno=0;
int selectedWallXLoc= -1, selectedWallYLoc= -1;
int selectedFirmRecno=0;
int selectedTownRecno=0;
int firstTest=0;
char selectSound = 0;
if( selectOneOnly )
{
char pMobileType;
locPtr = test_detect( selX2, selY2, &pMobileType );
if( locPtr )
{
if( pMobileType == UNIT_AIR && locPtr->has_unit(pMobileType) &&
!unit_array.is_deleted(locPtr->air_cargo_recno) &&
!(unitPtr = unit_array[locPtr->air_cargo_recno])->is_shealth() )
{
err_when( unitPtr->mobile_type != UNIT_AIR );
}
else if( pMobileType == UNIT_LAND &&
(locPtr->has_unit(UNIT_LAND) || locPtr->has_unit(UNIT_SEA)) &&
!unit_array.is_deleted(locPtr->cargo_recno) &&
!(unitPtr = unit_array[locPtr->cargo_recno])->is_shealth() )
{
err_when( unitPtr->mobile_type != UNIT_LAND && unitPtr->mobile_type != UNIT_SEA);
}
else if( pMobileType == UNIT_LAND && !recallGroup &&
locPtr->is_firm() && !firm_array.is_deleted(locPtr->cargo_recno) )
{
selectedFirmRecno=locPtr->firm_recno();
selectedCount++;
unitPtr = NULL;
}
else if( pMobileType == UNIT_LAND && !recallGroup &&
locPtr->is_town() && !town_array.is_deleted(locPtr->cargo_recno) )
{
selectedTownRecno=locPtr->town_recno();
selectedCount++;
unitPtr = NULL;
}
else
unitPtr = NULL;
if( unitPtr &&
(!recallGroup || unitPtr->is_own()) ) // skip recallGroup selecting enemy unit, it is attack!
{
if( !unitPtr->is_own() )
{
err_when( recallGroup ); // press right button on enemy unit is attack, not select
shiftSelect = 0;
}
if( recallGroup && unitPtr->team_id )
{
DWORD teamId = unitPtr->team_id;
char newSelectedFlag = shiftSelect ? (unitPtr->selected_flag ? 0 : 1) : 2;
for( i=unit_array.size() ; i>0 ; i-- )
{
if( unit_array.is_deleted(i) )
continue;
Unit *memberUnit = unit_array[i];
//---- set Unit::team_id to define the group ----//
if( memberUnit->team_id == teamId )
{
memberUnit->selected_flag = newSelectedFlag; // a team member is selected is depending on the clicked unit
selectedCount++;
}
}
}
else
{
char newSelectedFlag = shiftSelect ? (unitPtr->selected_flag ? 0 : 1) : 2;
unitPtr->selected_flag = newSelectedFlag;
selectedCount++;
}
if( unitPtr->selected_flag && unitPtr->is_own() && nation_array.player_recno)
{
if( se_res.mark_select_object_time() )
{
se_res.sound( unitPtr->cur_x_loc(), unitPtr->cur_y_loc(), 1,
'S', unitPtr->sprite_id, "SEL");
}
selectSound = 1;
}
// goto label_post_select;
}
}
}
else
{
const unsigned int mobileTypeCount = 3;
static char mobileTypeList[mobileTypeCount] = { UNIT_AIR, UNIT_LAND, UNIT_SEA };
// pass 1 - find if selecting own nation or spy cloaked nation
short nationSelect = nation_array.player_recno;
if( shiftSelect && unit_array.selected_recno )
{
if( !unit_array.is_deleted(unit_array.selected_recno) )
nationSelect = unit_array[unit_array.selected_recno]->nation_recno;
// so if you want to select spy of the same nation from
// from a crowd of your spy,
// select any one spy of that nation, shift select the crowd
}
else
{
unsigned short selectNationCount[MAX_NATION+1]; // count nation of selectable unit
memset( selectNationCount, 0, sizeof(selectNationCount) );
for( yLoc=selYLoc1 ; yLoc<=selYLoc2 ; yLoc++ )
{
for( xLoc=selXLoc1 ; xLoc<=selXLoc2 ; xLoc++ )
{
locPtr = world.get_loc(xLoc, yLoc);
for( int mt = 0; mt < sizeof(mobileTypeList)/sizeof(char); ++mt )
{
char mobileType = mobileTypeList[mt];
if( locPtr->has_unit(mobileType) && !unit_array.is_deleted(locPtr->unit_recno(mobileType))
&& !(unitPtr = unit_array[locPtr->unit_recno(mobileType)])->is_shealth() )
{
if(!unitPtr->is_visible() || unitPtr->hit_points<=0 || unitPtr->is_shealth() ||
!unitPtr->is_own() )
continue; // skip this unit
unitPtr->update_abs_pos();
if( m.is_touch( absSelX1, absSelY1, absSelX2, absSelY2,
unitPtr->abs_x1, unitPtr->abs_y1,
unitPtr->abs_x2, unitPtr->abs_y2 ) )
{
selectNationCount[unitPtr->nation_recno]++;
}
}
}
}
}
if( selectNationCount[nation_array.player_recno] == 0 ) // prefer own nation
{
nationSelect = -1; // all nation
}
}
// recallGroup is ignored
char newSelectedFlag = shiftSelect ? 1 : 2; // press shift to include more units
for( yLoc=selYLoc1 ; yLoc<=selYLoc2 ; yLoc++ )
{
for( xLoc=selXLoc1 ; xLoc<=selXLoc2 ; xLoc++ )
{
locPtr = world.get_loc(xLoc, yLoc);
for( int mt = 0; mt < sizeof(mobileTypeList)/sizeof(char); ++mt )
{
char mobileType = mobileTypeList[mt];
if( locPtr->has_unit(mobileType) && !unit_array.is_deleted(locPtr->unit_recno(mobileType))
&& !(unitPtr = unit_array[locPtr->unit_recno(mobileType)])->is_shealth() )
{
if(!unitPtr->is_visible() || unitPtr->hit_points<=0 || unitPtr->is_shealth() ||
!unitPtr->is_own() )
continue; // skip this unit
if( nationSelect != -1 && unitPtr->nation_recno != nationSelect )
continue; // skip this unit
unitPtr->update_abs_pos();
if( m.is_touch( absSelX1, absSelY1, absSelX2, absSelY2,
unitPtr->abs_x1, unitPtr->abs_y1,
unitPtr->abs_x2, unitPtr->abs_y2 ) )
{
selectedCount++;
//selectedUnitRecno = unitPtr->sprite_recno;
//--------- set selected_flag ----------//
unitPtr->selected_flag = newSelectedFlag; // set to 2 as all sprites will be processed below
//---- recall selection of the defined group to which the selected unit belongs ----//
}
}
}
}
}
}
//-------- detect raw material sites ---------//
if( selectedCount==0 && selectOneOnly && !recallGroup )
{
int selXLoc = topXLoc + (selX1-ZOOM_X1)/ZOOM_LOC_WIDTH;
int selYLoc = topYLoc + (selY1-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
Location* locPtr = world.get_loc(selXLoc, selYLoc);
if( locPtr->has_site() && !locPtr->is_firm() )
{
selectedCount++;
selectedSiteRecno = locPtr->site_recno();
}
}
//---------- detect city wall ----------//
if( selectedCount==0 && selectOneOnly && !recallGroup )
{
int selXLoc = topXLoc + (selX1-ZOOM_X1)/ZOOM_LOC_WIDTH;
int selYLoc = topYLoc + (selY1-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
Location* locPtr = world.get_loc(selXLoc, selYLoc);
if( locPtr->is_wall() )
{
selectedCount++;
selectedWallXLoc = selXLoc;
selectedWallYLoc = selYLoc;
}
}
//------ if any objects have been just selected ------//
// label_post_select:
if( selectedCount ) // reset previously selected flag
{
//--- if shift select, don't change the selected flag, but if town or firm is selected, reset all unit selection ---//
if( selectedFirmRecno || selectedTownRecno || selectedSiteRecno || selectedWallXLoc >= 0 || !shiftSelect )
{
for( i=unit_array.size() ; i>0 ; i-- )
{
if( unit_array.is_deleted(i) )
continue;
unitPtr = unit_array[i];
if( unitPtr->selected_flag )
{
//---- for group selection (selecting more than 1 unit), only select the player's own units ----//
if( selectedCount>1 && !unitPtr->is_own() )
unitPtr->selected_flag = 0;
else
unitPtr->selected_flag--;
// for newly selected sprite, selected_flag will be changed from 2 to 1
// for formerly selected sprite, selected_flag will be change from 1 to 0
}
}
}
//--------- count the no. of selected units --------//
//
// we need to count it instead of using selectedCount as
// selectedCount only tells the no. of units selected
// this time, not including previous selected ones for shift selection.
//
//--------------------------------------------------//
unit_array.selected_count=0; // reset it now, we will count it below
int highRankUnitRecno = 0;
//--- unit_array.selected_recno should be the unit with the highest rank ---//
for( i=unit_array.size() ; i>0 ; i-- )
{
if( !unit_array.is_deleted(i) && unit_array[i]->selected_flag )
{
unit_array.selected_count++;
if( !highRankUnitRecno ||
unit_array[i]->rank_id > unit_array[highRankUnitRecno]->rank_id )
highRankUnitRecno = i;
}
}
unit_array.selected_recno=highRankUnitRecno; // note no unit may be selected, like pressing shift to de-select unit
// so selectedCount may not be true
if( unit_array.selected_recno && !selectSound &&
unit_array[unit_array.selected_recno]->is_own() )
{
if( se_res.mark_select_object_time() )
{
Unit *headUnit = unit_array[unit_array.selected_recno];
se_res.sound( headUnit->cur_x_loc(), headUnit->cur_y_loc(), 1, 'S',
headUnit->sprite_id, "SEL");
}
selectSound = 1;
}
if( selectedFirmRecno && !selectSound &&
firm_array[selectedFirmRecno]->own_firm() )
{
if( se_res.mark_select_object_time() )
{
Firm *firmPtr = firm_array[selectedFirmRecno];
se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
'F', firmPtr->firm_id, firmPtr->under_construction ? (char*)"SELU" : (char*)"SEL" );
}
selectSound = 1;
}
if( selectedTownRecno && !selectSound &&
town_array[selectedTownRecno]->nation_recno == nation_array.player_recno )
{
if( se_res.mark_select_object_time() )
{
Town *townPtr = town_array[selectedTownRecno];
se_res.sound(townPtr->center_x, townPtr->center_y, 1,
'T', 0, "SEL" );
}
selectSound = 1;
}
//--- only set selected_recno for single unit selected, don't do so for nation selection
firm_array.selected_recno = selectedFirmRecno;
town_array.selected_recno = selectedTownRecno;
site_array.selected_recno = selectedSiteRecno;
wall_res.selected_x_loc = selectedWallXLoc;
wall_res.selected_y_loc = selectedWallYLoc;
reset_command(); // reset current command when a new unit is selected
//--- group them automatically if a group of units are selected ---//
// if( unit_array.selected_count > 1 )
// unit_array[unit_array.selected_recno]->define_team();
//----- refresh info display of the selected object -----//
info.disp();
}
//-----------------------------------------//
return selectedCount;
}
//------ End of function Power::detect_select -------//
//--------- Begin of function Power::issue_command ---------//
//
// commandId - the id. of the command
// [int] commandUnitRecno - the id. of the unit that issues the command
// [int] commandPara - an extra parameter of the command
//
void Power::issue_command(int commandId, int commandUnitRecno, int commandPara)
{
command_id = commandId;
command_unit_recno = commandUnitRecno;
command_para = commandPara;
}
//----------- End of function Power::issue_command -----------//
//--------- Begin of function Power::reset_selection ---------//
//
// Reset selection.
//
void Power::reset_selection()
{
int i;
//----- reset unit selection -------//
for(i=1; i <=unit_array.size() ; i++)
{
if( unit_array.is_deleted(i) )
continue;
unit_array[i]->selected_flag = 0;
}
unit_array.selected_recno = 0;
unit_array.selected_count = 0;
//---- reset other selection --------//
firm_array.selected_recno = 0;
town_array.selected_recno = 0;
site_array.selected_recno = 0;
wall_res.selected_x_loc = -1;
wall_res.selected_y_loc = -1;
reset_command(); // reset current command when a new unit is selected
}
//----------- End of function Power::reset_selection -----------//
//--------- Begin of function Power::get_link_icon ---------//
//
// linkStatus - link status
// sameNation - whether the two firms are of the same nation
// (default: 0)
//
// return: the bitmap pointer of the link icon
//
char* Power::get_link_icon(char linkStatus, int sameNation)
{
char goodLinkName[9] = "LINK_EE1";
goodLinkName[7] = '1'+ (char) (sys.frame_count/2%3);
switch( linkStatus )
{
case LINK_EE:
return image_icon.get_ptr(goodLinkName);
case LINK_ED:
return image_icon.get_ptr("LINK_ED");
case LINK_DE:
return image_icon.get_ptr("LINK_DE");
case LINK_DD:
if( sameNation )
return image_icon.get_ptr("LINK_DE"); // green cross for same nation firms
else
return image_icon.get_ptr("LINK_DD"); // red cross for different nation firms
}
err_here();
return NULL;
}
//----------- End of function Power::get_link_icon -----------//
// ---------- Begin of function Power::choose_cursor --------//
//
int Power::choose_cursor(int scrnX, int scrnY,
ScreenObjectType selectedObjectType, short selectedObjectRecno,
ScreenObjectType pointingObjectType, short pointingObjectRecno)
{
int selectedObjectId = 0;
int pointingObjectId = 0;
if(command_id)
{
if( scrnX >= ZOOM_X1 && scrnX <= ZOOM_X2 &&
scrnY >= ZOOM_Y1 && scrnY <= ZOOM_Y2)
{
switch(command_id)
{
case COMMAND_BUILD_FIRM:
return CURSOR_BUILD;
case COMMAND_ASSIGN:
return CURSOR_ASSIGN;
case COMMAND_BURN:
return CURSOR_BURN;
case COMMAND_SETTLE:
{
char flagColor = 0; // CURSOR_SETTLE + 0 is a valid cursor
Unit *activeUnit;
if( nation_array.player_recno
&& !nation_array.is_deleted(nation_array.player_recno) )
flagColor = (~nation_array)->color_scheme_id;
if( command_unit_recno && !unit_array.is_deleted(command_unit_recno)
&& (activeUnit = unit_array[command_unit_recno]) )
{
if( !activeUnit->nation_recno )
flagColor = 0; // independent nation
else if( !nation_array.is_deleted(activeUnit->nation_recno) )
flagColor = nation_array[activeUnit->nation_recno]->color_scheme_id;
}
return CURSOR_SETTLE + flagColor;
}
case COMMAND_SET_CARAVAN_STOP:
if(
(
pointingObjectType == SCREEN_OBJECT_FRIEND_FIRM
||
pointingObjectType == SCREEN_OBJECT_ENEMY_FIRM
)
&&
!nation_array.is_deleted(firm_array[pointingObjectRecno]->nation_recno)
&&
((UnitCaravan *)unit_array[selectedObjectRecno])->can_set_stop(pointingObjectRecno)
)
return CURSOR_SET_STOP;
return CURSOR_CANT_SET_STOP;
case COMMAND_SET_SHIP_STOP:
if(
(
pointingObjectType == SCREEN_OBJECT_FRIEND_FIRM
||
pointingObjectType == SCREEN_OBJECT_ENEMY_FIRM
)
&&
!nation_array.is_deleted(firm_array[pointingObjectRecno]->nation_recno)
&&
((UnitMarine *)unit_array[selectedObjectRecno])->can_set_stop(pointingObjectRecno)
)
return CURSOR_SHIP_STOP;
return CURSOR_CANT_SHIP_STOP;
case COMMAND_BUILD_WALL:
return CURSOR_BUILD;
case COMMAND_DESTRUCT_WALL:
return CURSOR_DESTRUCT;
case COMMAND_GOD_CAST_POWER:
return CURSOR_NORMAL;
default:
err_here();
return CURSOR_NORMAL;
}
}
else
{
return CURSOR_NORMAL;
}
}
else
{
// power.command_id == 0
// ------- check cursor inside zoom window -------//
if( scrnX >= ZOOM_X1 && scrnX <= ZOOM_X2 &&
scrnY >= ZOOM_Y1 && scrnY <= ZOOM_Y2)
{
// ------ inside zoom window, depend on selected and pointing object
switch(selectedObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
case SCREEN_OBJECT_ENEMY_UNIT:
{
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_NORMAL;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
case SCREEN_OBJECT_FRIEND_TOWN:
case SCREEN_OBJECT_FRIEND_FIRM:
return CURSOR_NORMAL_C;
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_NORMAL_O;
default:
err_here();
return CURSOR_NORMAL;
}
}
case SCREEN_OBJECT_SPY_UNIT:
{
Unit *unitPtr = unit_array[selectedObjectRecno];
short nationRecno = unitPtr->nation_recno;
selectedObjectId = unitPtr->unit_id;
switch( pointingObjectType )
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_NORMAL;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_ENEMY_UNIT:
{
Unit *pUnit = unit_array[pointingObjectRecno];
if( nationRecno == pUnit->nation_recno )
{
// same nation
return choose_cursor_units(selectedObjectRecno, pointingObjectRecno);
}
else
{
return CURSOR_UNIT_O;
}
}
case SCREEN_OBJECT_FRIEND_TOWN:
case SCREEN_OBJECT_ENEMY_TOWN:
{
Town *pTown = town_array[pointingObjectRecno];
// determine friend / enemy again
if( nationRecno == pTown->nation_recno )
{
if( unit_res[selectedObjectId]->race_id && unitPtr->rank_id == RANK_SOLDIER )
return CURSOR_ASSIGN;
else
return CURSOR_UNIT_C;
}
else
{
return CURSOR_UNIT_O;
}
}
case SCREEN_OBJECT_FRIEND_FIRM:
case SCREEN_OBJECT_ENEMY_FIRM:
{
Firm *pFirm = firm_array[pointingObjectRecno];
// ##### begin Gilbert 22/10 #########//
//if( unitPtr->firm_can_assign(pointingObjectRecno) )
if( unit_can_assign_firm(selectedObjectRecno, pointingObjectRecno, nation_array.player_recno) )
// ##### end Gilbert 22/10 #########//
return CURSOR_ASSIGN;
else
{
if( nationRecno == pFirm->nation_recno )
return CURSOR_UNIT_C;
else
return CURSOR_UNIT_O;
}
}
default:
err_here();
return CURSOR_NORMAL;
}
}
case SCREEN_OBJECT_FRIEND_UNIT:
{
Unit *unitPtr = unit_array[selectedObjectRecno];
selectedObjectId = unitPtr->unit_id;
char rankId = unitPtr->rank_id;
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_SITE:
return CURSOR_UNIT;
case SCREEN_OBJECT_FRIEND_UNIT:
return choose_cursor_units(selectedObjectRecno, pointingObjectRecno);
case SCREEN_OBJECT_UNIT_GROUP:
err_here(); // impossible to pointing at more than one unit
return CURSOR_UNIT_C;
case SCREEN_OBJECT_FRIEND_TOWN:
// ##### begin Gilbert 18/10 ######//
if( unitPtr->race_id && rankId == RANK_SOLDIER && !unitPtr->skill.skill_id)
// ##### end Gilbert 18/10 ######//
return CURSOR_ASSIGN;
else
return CURSOR_UNIT_C;
case SCREEN_OBJECT_FRIEND_FIRM:
{
Firm *firmPtr = firm_array[pointingObjectRecno];
pointingObjectId = firmPtr->firm_id;
// ###### begin Gilbert 22/10 #######//
// if( unitPtr->firm_can_assign(pointingObjectRecno) )
if( unit_can_assign_firm(selectedObjectRecno, pointingObjectRecno, nation_array.player_recno) )
// ###### end Gilbert 22/10 #######//
return CURSOR_ASSIGN;
return CURSOR_UNIT_C;
}
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_UNIT_O;
case SCREEN_OBJECT_WALL:
return CURSOR_DESTRUCT;
default:
err_here();
return CURSOR_UNIT;
}
}
case SCREEN_OBJECT_UNIT_GROUP:
{
int arraySize = unit_array.size();
int i;
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_SITE:
return CURSOR_UNIT;
case SCREEN_OBJECT_FRIEND_UNIT:
return choose_cursor_unit_group(pointingObjectRecno);
case SCREEN_OBJECT_UNIT_GROUP:
err_here(); // impossible to pointing at more than one unit
return CURSOR_UNIT_C;
case SCREEN_OBJECT_FRIEND_TOWN:
for( i = 1; i < arraySize; ++i)
{
Unit *unitPtr;
if( unit_array.is_deleted(i) || !(unitPtr = unit_array[i])->selected_flag )
continue;
// ###### begin Gilbert 18/10 ########//
if( unitPtr->race_id && unitPtr->rank_id == RANK_SOLDIER
&& !unitPtr->skill.skill_id )
// ###### end Gilbert 18/10 ########//
return CURSOR_ASSIGN;
}
return CURSOR_UNIT_C;
case SCREEN_OBJECT_FRIEND_FIRM:
{
Firm *firmPtr = firm_array[pointingObjectRecno];
pointingObjectId = firmPtr->firm_id;
for( i = 1; i < arraySize; ++i)
{
Unit *unitPtr;
if( unit_array.is_deleted(i) || !(unitPtr = unit_array[i])->selected_flag )
continue;
// ##### begin Gilbert 22/10 #######//
// if( unitPtr->firm_can_assign(pointingObjectRecno) )
if( unit_can_assign_firm(i, pointingObjectRecno, nation_array.player_recno) )
return CURSOR_ASSIGN;
// ##### end Gilbert 22/10 #######//
}
return CURSOR_UNIT_C;
}
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_UNIT_O;
case SCREEN_OBJECT_WALL:
return CURSOR_DESTRUCT;
default:
err_here();
return CURSOR_UNIT;
}
}
case SCREEN_OBJECT_FRIEND_TOWN:
{
Town *townPtr = town_array[selectedObjectRecno];
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_C_TOWN;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
return CURSOR_C_TOWN_C;
case SCREEN_OBJECT_FRIEND_FIRM:
{
Firm *pFirm = firm_array[pointingObjectRecno];
int centerX = (pFirm->loc_x1 + pFirm->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pFirm->loc_y1 + pFirm->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& townPtr->can_toggle_firm_link(pointingObjectRecno) )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_TOWN_C;
case SCREEN_OBJECT_FRIEND_TOWN:
if( selectedObjectRecno != pointingObjectRecno )
{
// check if the cursor is pointing at the middle of the town
Town *pTown = town_array[pointingObjectRecno];
int centerX = (pTown->loc_x1 + pTown->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pTown->loc_y1 + pTown->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& townPtr->can_migrate(pointingObjectRecno) )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_TOWN_C;
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
return CURSOR_C_TOWN_O;
case SCREEN_OBJECT_ENEMY_FIRM:
{
Firm *pFirm = firm_array[pointingObjectRecno];
int centerX = (pFirm->loc_x1 + pFirm->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pFirm->loc_y1 + pFirm->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& townPtr->can_toggle_firm_link(pointingObjectRecno) )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_TOWN_O;
default:
err_here();
return CURSOR_C_TOWN;
}
}
case SCREEN_OBJECT_ENEMY_TOWN:
{
Town *townPtr = town_array[selectedObjectRecno];
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_O_TOWN;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
case SCREEN_OBJECT_FRIEND_TOWN:
return CURSOR_O_TOWN_C;
case SCREEN_OBJECT_FRIEND_FIRM:
return CURSOR_O_TOWN_C;
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_O_TOWN_O;
default:
err_here();
return CURSOR_O_TOWN;
}
}
case SCREEN_OBJECT_FRIEND_FIRM:
{
Firm *firmPtr = firm_array[selectedObjectRecno];
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_C_FIRM;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
return CURSOR_C_FIRM_C;
case SCREEN_OBJECT_FRIEND_TOWN:
{
Town *pTown = town_array[pointingObjectRecno];
int centerX = (pTown->loc_x1 + pTown->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pTown->loc_y1 + pTown->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& firmPtr->can_toggle_town_link() )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_FIRM_C;
case SCREEN_OBJECT_FRIEND_FIRM:
if( selectedObjectRecno != pointingObjectRecno )
{
Firm *pFirm = firm_array[pointingObjectRecno];
int centerX = (pFirm->loc_x1 + pFirm->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pFirm->loc_y1 + pFirm->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& firmPtr->can_toggle_firm_link(pointingObjectRecno) )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_FIRM_C;
case SCREEN_OBJECT_ENEMY_UNIT:
return CURSOR_C_FIRM_O;
case SCREEN_OBJECT_ENEMY_TOWN:
{
Town *pTown = town_array[pointingObjectRecno];
int centerX = (pTown->loc_x1 + pTown->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pTown->loc_y1 + pTown->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& firmPtr->can_toggle_town_link() )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_FIRM_O;
case SCREEN_OBJECT_ENEMY_FIRM:
{
Firm *pFirm = firm_array[pointingObjectRecno];
int centerX = (pFirm->loc_x1 + pFirm->loc_x2 +1)*ZOOM_LOC_WIDTH/2 - World::view_top_x;
int centerY = (pFirm->loc_y1 + pFirm->loc_y2 +1)*ZOOM_LOC_HEIGHT/2 - World::view_top_y;
if(m.points_distance( mouse.cur_x, mouse.cur_y, centerX+ZOOM_X1, centerY+ZOOM_Y1) <= 11
&& firmPtr->can_toggle_firm_link(pointingObjectRecno) )
{
return CURSOR_ON_LINK;
}
}
return CURSOR_C_FIRM_O;
default:
err_here();
return CURSOR_C_FIRM;
}
}
case SCREEN_OBJECT_ENEMY_FIRM:
{
switch( pointingObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
return CURSOR_O_FIRM;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
case SCREEN_OBJECT_FRIEND_FIRM:
return CURSOR_O_FIRM_C;
case SCREEN_OBJECT_FRIEND_TOWN:
return CURSOR_O_FIRM_C;
case SCREEN_OBJECT_ENEMY_UNIT:
case SCREEN_OBJECT_ENEMY_TOWN:
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_O_FIRM_O;
default:
err_here();
return CURSOR_O_TOWN;
}
}
default:
err_here();
return CURSOR_NORMAL;
}
}
else
{
// ------ outside zoom area depend on selected object ------//
switch(selectedObjectType)
{
case SCREEN_OBJECT_NONE:
case SCREEN_OBJECT_WALL:
case SCREEN_OBJECT_SITE:
case SCREEN_OBJECT_ENEMY_UNIT:
return CURSOR_NORMAL;
case SCREEN_OBJECT_FRIEND_UNIT:
case SCREEN_OBJECT_UNIT_GROUP:
case SCREEN_OBJECT_SPY_UNIT:
return CURSOR_UNIT;
case SCREEN_OBJECT_FRIEND_TOWN:
return CURSOR_C_TOWN;
case SCREEN_OBJECT_ENEMY_TOWN:
return CURSOR_O_TOWN;
case SCREEN_OBJECT_FRIEND_FIRM:
return CURSOR_C_FIRM;
case SCREEN_OBJECT_ENEMY_FIRM:
return CURSOR_O_FIRM;
default:
err_here();
return CURSOR_NORMAL;
}
}
}
}
// ---------- End of function Power::choose_cursor --------//
// ---------- Begin of function Power::choose_cursor_units --------//
//
int Power::choose_cursor_units(short selectedUnitRecno, short pointingUnitRecno)
{
Unit *u1Ptr = unit_array[selectedUnitRecno];
Unit *u2Ptr = unit_array[pointingUnitRecno];
int selectedUnitId = u1Ptr->unit_id;
int pointingUnitId = u2Ptr->unit_id;
UnitInfo *u1 = unit_res[selectedUnitId];
UnitInfo *u2 = unit_res[pointingUnitId];
if(u1 && u2)
{
// ------- detect ship that can carry land unit -------//
if( u1->mobile_type == UNIT_LAND &&
u2 && u2->carry_unit_capacity > 0)
{
return CURSOR_ASSIGN;
}
else if( pointingUnitId == UNIT_EXPLOSIVE_CART && // check trigger explosive cart
u1Ptr->max_attack_range() > 1)
{
return CURSOR_TRIGGER_EXPLODE;
}
else if( u1->vehicle_id == pointingUnitId && // can ride on
u1->solider_id != 0) // make sure u1 is a rider, not a riding unit
{
return CURSOR_ASSIGN;
}
}
return CURSOR_UNIT_C;
}
// ---------- End of function Power::choose_cursor_units --------//
// ---------- Begin of function Power::choose_cursor_unit_group --------//
//
int Power::choose_cursor_unit_group(short pointingUnitRecno)
{
int pointingUnitId = unit_array[pointingUnitRecno]->unit_id;
// ----- assume all selected unit are owned by the player ----//
UnitInfo *u2 = unit_res[pointingUnitId];
if(u2)
{
// ------- detect ship that can carry land unit -------//
if( u2->carry_unit_capacity > 0)
{
// if any land unit in the selected array
int s = unit_array.size();
for(int i=1; i <= s; ++i)
{
if( !unit_array.is_deleted(i) && unit_array[i]->selected_flag)
{
UnitInfo *u1 = unit_res[unit_array[i]->unit_id];
if( u1->mobile_type == UNIT_LAND)
return CURSOR_ASSIGN;
}
}
}
else if( pointingUnitId == UNIT_EXPLOSIVE_CART )
{
// if any land unit in the selected array
int s = unit_array.size();
for(int i=1; i <= s; ++i)
{
Unit *unitPtr;
if( !unit_array.is_deleted(i) && (unitPtr = unit_array[i])->selected_flag)
{
if( unitPtr->max_attack_range() > 1)
return CURSOR_TRIGGER_EXPLODE;
}
}
}
else
{
// see if pointing unit is vehicle of any of the selected unit
int s = unit_array.size();
for(int i=1; i <= s; ++i)
{
if( !unit_array.is_deleted(i) && unit_array[i]->selected_flag)
{
UnitInfo *u1 = unit_res[unit_array[i]->unit_id];
if( u1->vehicle_id == pointingUnitId)
return CURSOR_ASSIGN;
}
}
//------- check other relationship here -------//
}
}
return CURSOR_UNIT_C;
}
// ---------- End of function Power::choose_cursor_unit_group --------//
// ---------- Begin of function Power::find_selected_type --------//
//
ScreenObjectType Power::find_selected_type( short *selectedRecno)
{
short dummyId;
if( selectedRecno == NULL)
selectedRecno = &dummyId;
if( unit_array.selected_recno )
{
// -------- check selected single unit ---------//
if( unit_array.selected_count == 1)
{
Unit *unitPtr = unit_array[*selectedRecno = unit_array.selected_recno];
return unitPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_UNIT :
(unitPtr->true_nation_recno() == nation_array.player_recno ?
SCREEN_OBJECT_SPY_UNIT : SCREEN_OBJECT_ENEMY_UNIT);
}
// -------- check selected a group of units ---------//
if( unit_array.selected_count > 1)
{
*selectedRecno = unit_array.selected_recno;
return SCREEN_OBJECT_UNIT_GROUP;
}
}
// -------- check selected a firm ---------//
if( firm_array.selected_recno )
{
Firm *firmPtr = firm_array[*selectedRecno = firm_array.selected_recno];
return firmPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_FIRM : SCREEN_OBJECT_ENEMY_FIRM;
}
// -------- check selected a town ---------//
if( town_array.selected_recno )
{
Town *townPtr = town_array[*selectedRecno = town_array.selected_recno];
return townPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_TOWN : SCREEN_OBJECT_ENEMY_TOWN;
}
// -------- check selected a site ---------//
if( site_array.selected_recno )
{
Site *sitePtr = site_array[*selectedRecno = site_array.selected_recno];
return SCREEN_OBJECT_SITE;
}
// -------- check selected a wall ---------//
if( wall_res.selected_x_loc >= 0 && wall_res.selected_y_loc >= 0)
{
*selectedRecno = world.get_loc(wall_res.selected_x_loc, wall_res.selected_y_loc)->power_nation_recno;
return SCREEN_OBJECT_WALL;
}
return SCREEN_OBJECT_NONE;
}
// ---------- End of function Power::find_selected_type --------//
// ---------- Begin of function Power::find_pointing_type --------//
//
ScreenObjectType Power::find_pointing_type( Location *locPtr, short *pointingRecno)
{
short dummyId;
if( pointingRecno == NULL)
pointingRecno = &dummyId;
// ------- check pointing at unit, always check air unit first -------//
if( locPtr->has_unit( UNIT_AIR ) )
{
Unit *unitPtr = unit_array[*pointingRecno = locPtr->unit_recno(UNIT_AIR)];
return unitPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_UNIT : SCREEN_OBJECT_ENEMY_UNIT;
}
if( locPtr->has_unit( UNIT_LAND ) )
{
Unit *unitPtr = unit_array[*pointingRecno = locPtr->unit_recno(UNIT_LAND)];
return unitPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_UNIT : SCREEN_OBJECT_ENEMY_UNIT;
}
if( locPtr->has_unit( UNIT_SEA ) )
{
Unit *unitPtr = unit_array[*pointingRecno = locPtr->unit_recno(UNIT_SEA)];
return unitPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_UNIT : SCREEN_OBJECT_ENEMY_UNIT;
}
// -------- check pointing at firm ---------//
if( locPtr->is_firm() )
{
Firm *firmPtr = firm_array[*pointingRecno = locPtr->firm_recno()];
return firmPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_FIRM : SCREEN_OBJECT_ENEMY_FIRM;
}
// ------- check pointing at town ---------//
if( locPtr->is_town() )
{
Town *townPtr = town_array[*pointingRecno = locPtr->town_recno()];
return townPtr->nation_recno == nation_array.player_recno ?
SCREEN_OBJECT_FRIEND_TOWN : SCREEN_OBJECT_ENEMY_TOWN;
}
// -------- check pointing a site ---------//
if( locPtr->has_site() )
{
Site *sitePtr = site_array[*pointingRecno = locPtr->site_recno()];
return SCREEN_OBJECT_SITE;
}
// -------- check pointing a wall ---------//
if( locPtr->is_wall() )
{
*pointingRecno = locPtr->power_nation_recno;
return SCREEN_OBJECT_WALL;
}
return SCREEN_OBJECT_NONE;
}
// ---------- End of function Power::find_pointing_type --------//
// ###### begin Gilbert 22/10 #######//
// ---------- Begin of function Power::unit_can_assign_firm --------//
int Power::unit_can_assign_firm(int unitRecno, int firmRecno, int ownNationRecno)
{
if(!ownNationRecno || !unitRecno || !firmRecno )
return 0;
if( unit_array.is_deleted(unitRecno) )
return 0;
Unit *unitPtr = unit_array[unitRecno];
if( firm_array.is_deleted(firmRecno) )
return 0;
Firm *firmPtr = firm_array[firmRecno];
int rc = unitPtr->firm_can_assign(firmRecno);
if( !rc )
return 0;
//----------------------------------------//
// If this is a spy, then he can only be
// assigned to an enemy firm when there is
// space for the unit.
//----------------------------------------//
if( ownNationRecno != firmPtr->nation_recno )
{
switch(rc)
{
case 1: // assign as worker
if( firmPtr->worker_count == MAX_WORKER )
return 0;
break;
case 2: // assign as overseer
if( firmPtr->overseer_recno )
return 0;
break;
case 3: // assign as construction unit
if( firmPtr->builder_recno )
return 0;
break;
}
}
return rc;
}
// ---------- End of function Power::unit_can_assign_firm --------//
// ###### end Gilbert 22/10 #######//
//### begin alex 19/3 ###//
//---------- Begin of function Power::select_active_unit --------//
// choose the most suitable unit to be the active unit
//
// For this version and the situation, unit with ability to attack is
// used instead of selecting the first unit in the array
//
// The full version should consider: 1) whether the unit is human,
// 2) can attack, 3) mobile type, etc. Or divide the unit once more
// before calling functions in unit_array
//
short Power::select_active_unit(short *selectedArray, short selectedCount)
{
Unit *unitPtr;
for(short i=0; ican_attack())
return selectedArray[i];
}
//------ return the first one if none of them can attack --------//
return selectedArray[0];
}
//---------- End of function Power::select_active_unit --------//
//#### end alex 19/3 ####//