/************************************************************************** ... **************************************************************************/ static void sha_unit_remove(int id) { struct unit *pold_unit = unit_list_find(previous_units, id);; freelog(LOG_DEBUG, "sha got unit: %d", id); assert(pold_unit); unit_list_unlink(previous_units, pold_unit); /* list pointers were struct copied, cannot destroy_unit_virtual() */ memset(pold_unit, 0, sizeof(*pold_unit)); /* ensure no pointers remain */ free(pold_unit); }
/************************************************************************** ... **************************************************************************/ void handle_unit_info(struct packet_unit_info *packet) { struct city *pcity; struct unit *punit; int repaint_unit; int repaint_city; repaint_unit=0; repaint_city=0; punit=unit_list_find(&game.players[packet->owner].units, packet->id); if(punit) { if(punit->activity!=packet->activity) { /* change activity */ punit->activity=packet->activity; repaint_unit=1; /* refresh_tile_mapcanvas(punit->x, punit->y, 1); update_unit_pix_label(punit); refresh_unit_city_dialogs(punit); update_unit_focus(); */ } if(punit->homecity!=packet->homecity) { /* change homecity */ struct city *pcity; if((pcity=game_find_city_by_id(punit->homecity))) { unit_list_unlink(&pcity->units_supported, punit); refresh_city_dialog(pcity); } punit->homecity=packet->homecity; if((pcity=game_find_city_by_id(punit->homecity))) { unit_list_insert(&pcity->units_supported, punit); refresh_city_dialog(pcity); } } if(punit->hp!=packet->hp) { /* hp changed */ punit->hp=packet->hp; repaint_unit=1; } if(punit->attacks_left!=packet->attacksleft) { /* #attacks changed */ punit->attacks_left=packet->attacksleft; repaint_unit=1; } if(punit->x!=packet->x || punit->y!=packet->y) { /* change position */ struct city *pcity; pcity=map_get_city(punit->x, punit->y); if(tile_is_known(packet->x, packet->y)) { do_move_unit(punit, packet); update_unit_focus(); } else { unit_list_unlink(&game.players[packet->owner].units, punit); unit_list_unlink(&map_get_tile(punit->x, punit->y)->units, punit); refresh_tile_mapcanvas(punit->x, punit->y, 1); free(punit); } if(pcity) refresh_city_dialog(pcity); if((pcity=map_get_city(punit->x, punit->y))) refresh_city_dialog(pcity); repaint_unit=0; } if (punit->unhappiness!=packet->unhappiness) { punit->unhappiness=packet->unhappiness; repaint_city=1; } if (punit->upkeep!=packet->upkeep) { punit->upkeep=packet->upkeep; repaint_city=1; } if (repaint_city) { if((pcity=game_find_city_by_id(punit->homecity))) { refresh_city_dialog(pcity); } } punit->moves_left=packet->movesleft; punit->bribe_cost=packet->bribe_cost; } else { /* create new unit */ punit=(struct unit *)malloc(sizeof(struct unit)); punit->id=packet->id; punit->owner=packet->owner; punit->x=packet->x; punit->y=packet->y; punit->veteran=packet->veteran; punit->homecity=packet->homecity; punit->type=packet->type; punit->attacks_left=packet->attacksleft; punit->moves_left=packet->movesleft; punit->hp=packet->hp; punit->unhappiness=0; punit->activity=packet->activity; punit->upkeep=0; punit->hp=packet->hp; punit->bribe_cost=packet->bribe_cost; unit_list_insert(&game.players[packet->owner].units, punit); unit_list_insert(&map_get_tile(punit->x, punit->y)->units, punit); if((pcity=game_find_city_by_id(punit->homecity))) unit_list_insert(&pcity->units_supported, punit); /* this is ugly - prevent unit from being drawn if it's moved into * screen by a transporter - only works for ground_units.. yak */ if(!is_ground_unit(punit) || map_get_terrain(punit->x, punit->y)!=T_OCEAN) repaint_unit=1; else repaint_unit=0; } if(punit && punit==get_unit_in_focus()) update_unit_info_label(punit); if(repaint_unit) refresh_tile_mapcanvas(punit->x, punit->y, 1); update_unit_focus(); }