 |
|  |
 |
|
E
|
 |
July 24,2005 Ctp2 Tiles in sig!
May 1999 time: 21:22
|
|
Does it look like then there is a BUG between how CanBombard and Bombard work. I'm thinking Bombard should be coded like CanBombard instead of using the IsNextTo. As it is now ArmyData:BOmbard doesnt even check if it CanBombard, instead it checks if the unit "IsNextTo"
As far as an army with different bombard range. I think it calculates as a single army each unit that can bombard. So (hypothetically) a catapult of 1 doesnt bombard but only the cannons of 2 can. Atleast how the code looks.
should it be
code:
ORDER_RESULT ArmyData::Bombard(const MapPoint &orderPoint)
{
MapPoint point = orderPoint;
static CellUnitList defender;
defender.Clear();
g_theWorld->GetArmy(point, defender);
sint32 i;
BOOL isSpaceBombard = FALSE;
if(point == m_pos) {
return ORDER_RESULT_ILLEGAL;
} else {
if(!point.CanBombard(m_pos)) {
return ORDER_RESULT_ILLEGAL;
}
}
Last edited by E on 02-10-2004 at 03:51
|
|
|  |
 |
|
Solver
|
|
Apolyton Duke Of Something
|
 |
Latvia, Riga
Sep 2000 time: 07:22
|
|
quote: Yes, but as Solver pointed out, there is the "fire and forget" code lurking somewhere which first moves the army into range and then bombards, so - if this is not disabled altogether - should it move the army until something is in range, or until all bombarding units are in range? Personally I'd choose disabling it altogether, but I'm also going to have to go to bed now, so I'll leave you to search it out andfind out how it works |
It seems obvious that the code doesn't move armies into range to bombard - instead, the same code moves armies in range to execute any order, also bioinfections, franchises, etc. So we have two options: one is to disable it for bombard orders only (requires writing extra code), second is to disable it altogether (only need to take the code out). I'm strongly in favor of the latter. It is simpler to implement, and the "order and forget" movement feauture was annoying to me nonetheless - you better move units to the targets yourself. Also, disabling that will, I guess, prevent possible bugs with ranged bombard/other orders.
For the Bombard code, how about simply this:
code:
ORDER_RESULT ArmyData::Bombard(const MapPoint &orderPoint)
{
MapPoint point = orderPoint;
static CellUnitList defender;
defender.Clear();
g_theWorld->GetArmy(point, defender);
sint32 i;
BOOL isSpaceBombard = FALSE;
if(point == m_pos) {
return ORDER_RESULT_ILLEGAL;
} else {
if(! CanBombard(point)) {
return ORDER_RESULT_ILLEGAL;
}
}
So we immediately check if the army can bombard the target point... and then ArmyData::CanBombard should probably be where we check for the range properly. I really need to access the code and MSVC now...
So, do the squared distance functions work properly now for anything like that we may want to code? I find the whole squared distance instead of 'squares to move' type of algorithm annoying, because it involves extra geometrical calculations.
quote: MapPoint::GetSquaredDistance does exactly what it says (modulo some tweaks to account for the isometric tile set and wrapping, of course...). The reason it adds 0.5 is so that diagonally adjacent squares (which have a squaredistance of 2) fit inside distance 1 (which has rsq=(1+0.5)^2=2.25). |
But it would work the same if diagonally adjacent squared were distance=1, right?
EDIT: CanBombard gotta check for point, not m_pos. m_pos is where the unit ordered to bombard is located, point is where the target is.
|
|
|  |
 |
|
Flinx
|
 |
Toronto, ON CANADA
Nov 2001 time: 00:22
|
|
quote: Originally posted by Solver
It seems obvious that the code doesn't move armies into range to bombard - instead, the same code moves armies in range to execute any order, also bioinfections, franchises, etc. So we have two options: one is to disable it for bombard orders only (requires writing extra code), second is to disable it altogether (only need to take the code out). I'm strongly in favor of the latter. It is simpler to implement, and the "order and forget" movement feauture was annoying to me nonetheless - you better move units to the targets yourself. Also, disabling that will, I guess, prevent possible bugs with ranged bombard/other orders.
|
Would the AI be affected? Does the AI use this code?
|
|
|  |
 |
|
Solver
|
|
Apolyton Duke Of Something
|
 |
Latvia, Riga
Sep 2000 time: 07:22
|
|
The damn thing is running nice finally. Ths is what I've found. As it stands, the GetDistance in UnitData::CanBombard is reduntant. It only gets invoked when the unit is adjacent to its target.
I did a test with a Catapult(range 1) bombing an adjacent target. The bombard order was processed, CanBombard and GetDistance invoked, all fine, target bombarded. Then a Cannon (range 2) trying to bombard a target two squares away. The bombard order was received, and the Cannon moved adjacent to its target - and only THEN was the UnitData::CanBombard invoked. When a Cannon is given the bombard order, it's a SelectedItem class event, not a UnitData or ArmyData event. I suspect the following code is to blame for this movement:
code:
void SelectedItem::Bombard(const MapPoint &pnt)
{
PLAYER_INDEX player = GetVisiblePlayer();
if(m_select_state[player] == SELECT_TYPE_LOCAL_ARMY ) {
g_gevManager->AddEvent(GEV_INSERT_Tail, GEV_BombardOrder,
GEA_Army, m_selected_army[player],
GEA_MapPoint, pnt,
GEA_End);
}
}
So we have a specific bombard event added to the event manager... but I have no clue how that works yet. Am off to look at it further.
|
|
|  |
 |
|
E
|
 |
July 24,2005 Ctp2 Tiles in sig!
May 1999 time: 21:22
|
|
then there is this towards the end of the armyevent.cpp
code:
void armyevent_Initialize()
{
g_gevManager->AddCallback(GEV_MoveOrder, GEV_PRI_Primary, &s_ArmyMoveOrderEvent);
g_gevManager->AddCallback(GEV_MoveToOrder, GEV_PRI_Primary, &s_ArmyMoveToOrderEvent);
g_gevManager->AddCallback(GEV_MovePathOrder, GEV_PRI_Primary, &s_ArmyMovePathOrderEvent);
g_gevManager->AddCallback(GEV_VictoryMoveOrder, GEV_PRI_Primary, &s_ArmyVictoryMoveOrderEvent);
g_gevManager->AddCallback(GEV_UnloadOrder, GEV_PRI_Primary, &s_ArmyUnloadOrderEvent);
g_gevManager->AddCallback(GEV_SleepOrder, GEV_PRI_Primary, &s_ArmySleepOrderEvent);
g_gevManager->AddCallback(GEV_MoveUnloadOrder, GEV_PRI_Primary, &s_ArmyMoveUnloadOrderEvent);
g_gevManager->AddCallback(GEV_EntrenchOrder, GEV_PRI_Primary, &s_ArmyEntrenchOrderEvent);
g_gevManager->AddCallback(GEV_DetrenchOrder, GEV_PRI_Primary, &s_ArmyDetrenchOrderEvent);
g_gevManager->AddCallback(GEV_DisbandArmyOrder, GEV_PRI_Primary, &s_ArmyDisbandArmyOrderEvent);
g_gevManager->AddCallback(GEV_GroupOrder, GEV_PRI_Primary, &s_ArmyGroupOrderEvent);
g_gevManager->AddCallback(GEV_GroupUnitOrder, GEV_PRI_Primary, &s_ArmyGroupUnitOrderEvent);
g_gevManager->AddCallback(GEV_UngroupOrder, GEV_PRI_Primary, &s_ArmyUngroupOrderEvent);
g_gevManager->AddCallback(GEV_InvestigateCityOrder, GEV_PRI_Primary, &s_ArmyInvestigateCityOrderEvent);
g_gevManager->AddCallback(GEV_NullifyWallsOrder, GEV_PRI_Primary, &s_ArmyNullifyWallsOrderEvent);
g_gevManager->AddCallback(GEV_StealTechnologyOrder, GEV_PRI_Primary, &s_ArmyStealTechnologyOrderEvent);
g_gevManager->AddCallback(GEV_InciteRevolutionOrder, GEV_PRI_Primary, &s_ArmyInciteRevolutionOrderEvent);
g_gevManager->AddCallback(GEV_AssassinateRulerOrder, GEV_PRI_Primary, &s_ArmyAssassinateRulerOrderEvent);
g_gevManager->AddCallback(GEV_InvestigateReadinessOrder, GEV_PRI_Primary, &s_ArmyInvestigateReadinessOrderEvent);
g_gevManager->AddCallback(GEV_BombardOrder, GEV_PRI_Primary, &s_ArmyBombardOrderEvent);
|
|
|  |
 |
|
E
|
 |
July 24,2005 Ctp2 Tiles in sig!
May 1999 time: 21:22
|
|
code:
ArmyData::PerformOrderHere(const OrderRecord * order_rec, const Path * path)
{
Assert(path != NULL);
if (path == NULL)
return ;
if (m_flags & k_CULF_IN_SPACE)
return;
Path *tmp_path = new Path((Path *) path);
MapPoint target_pos;
if (tmp_path->GetMovesRemaining() > 0)
{
target_pos = tmp_path->GetEnd();
}
else
{
target_pos = m_pos;
}
if (s_orderDBToEventMap == NULL)
AssociateEventsWithOrdersDB();
Assert(s_orderDBToEventMap != NULL);
sint32 game_event = s_orderDBToEventMap[order_rec->GetIndex()];
sint32 range = 0;
sint32 moves = tmp_path->GetMovesRemaining();
if (order_rec->GetRange()) {
order_rec->GetRange(range);
Assert(range <= moves || order_rec->GetTargetPretestAdjacentPosition());
}
for (sint32 i = 0; moves > 0 && i < range; i++) {
tmp_path->SnipEnd();
moves--;
}
g_gevManager->Pause();
if (game_event > 0) {
if (range > 0 || order_rec->GetIsTeleport() || order_rec->GetIsTarget())
{
g_gevManager->AddEvent( GEV_INSERT_AfterCurrent,
static_cast(game_event),
GEA_Army, Army(m_id),
GEA_MapPoint, target_pos,
GEA_End);
}
else {
g_gevManager->AddEvent( GEV_INSERT_AfterCurrent,
static_cast(game_event),
GEA_Army, Army(m_id),
GEA_End);
}
}
if (tmp_path->GetMovesRemaining() > 0 && !order_rec->GetIsTeleport() && !order_rec->GetIsTarget()) {
g_gevManager->AddEvent(GEV_INSERT_AfterCurrent, GEV_MoveOrder,
GEA_Army, Army(m_id),
GEA_Path, tmp_path,
GEA_MapPoint, target_pos,
GEA_Int, (game_event == -1),
GEA_End);
}
else {
delete tmp_path;
}
g_gevManager->AddEvent(GEV_INSERT_AfterCurrent, GEV_ClearOrders,
GEA_Army, Army(m_id),
GEA_End);
g_gevManager->Resume();
}
|
|
|  |
 |
|  |
All times are GMT. The time now is 05:22. Apolyton Time is 00:22. |
top of page
|
|
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is ON
vB code is ON
Smilies are ON
[IMG] code is ON
|
|
|
|
|
|