From 73beffa3ca8dd07e53347b4e00554ad72a6ea585 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Mon, 18 Sep 2023 15:14:29 +0300 Subject: [PATCH 33/33] Prepare client for receiving OWNER_NONE units - Add OWNER_NONE definition - unit_virtual_create() to accept ownerless units - Refactor unit unpackaging to work with ownerless units See osdn #48646 Signed-off-by: Marko Lindqvist --- client/packhand.c | 112 +++++++++++++++++++++------------- common/networking/packets.def | 2 +- common/player.h | 2 + common/unit.c | 24 ++++---- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/client/packhand.c b/client/packhand.c index 3762eaac0d..ce50a04ff7 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -264,9 +264,9 @@ static void packhand_init(void) static struct unit *unpackage_unit(const struct packet_unit_info *packet) { struct unit *punit = unit_virtual_create(player_by_number(packet->owner), - NULL, - utype_by_number(packet->type), - packet->veteran); + nullptr, + utype_by_number(packet->type), + packet->veteran); /* Owner, veteran, and type fields are already filled in by * unit_virtual_create() */ @@ -284,7 +284,7 @@ static struct unit *unpackage_unit(const struct packet_unit_info *packet) punit->activity_count = packet->activity_count; if (packet->activity_tgt == EXTRA_NONE) { - punit->activity_target = NULL; + punit->activity_target = nullptr; } else { punit->activity_target = extra_by_number(packet->activity_tgt); } @@ -293,7 +293,7 @@ static struct unit *unpackage_unit(const struct packet_unit_info *packet) punit->changed_from_count = packet->changed_from_count; if (packet->changed_from_tgt == EXTRA_NONE) { - punit->changed_from_target = NULL; + punit->changed_from_target = nullptr; } else { punit->changed_from_target = extra_by_number(packet->changed_from_tgt); } @@ -315,7 +315,7 @@ static struct unit *unpackage_unit(const struct packet_unit_info *packet) if (packet->carrying >= 0) { punit->carrying = goods_by_number(packet->carrying); } else { - punit->carrying = NULL; + punit->carrying = nullptr; } punit->battlegroup = packet->battlegroup; @@ -360,22 +360,34 @@ static struct unit *unpackage_unit(const struct packet_unit_info *packet) static struct unit * unpackage_short_unit(const struct packet_unit_short_info *packet) { - struct unit *punit = unit_virtual_create(player_by_number(packet->owner), - NULL, - utype_by_number(packet->type), - 0); + struct unit *punit; + struct player *owner; + + if (packet->owner == OWNER_NONE) { + /* Silently ignore for now. */ + return nullptr; +/* + owner = nullptr; +*/ + } else { + owner = player_by_number(packet->owner); + } + + punit = unit_virtual_create(owner, nullptr, + utype_by_number(packet->type), + 0); /* Owner and type fields are already filled in by unit_virtual_create() */ punit->id = packet->id; unit_tile_set(punit, index_to_tile(&(wld.map), packet->tile)); punit->facing = packet->facing; - punit->nationality = NULL; + punit->nationality = nullptr; punit->veteran = packet->veteran; punit->hp = packet->hp; punit->activity = packet->activity; if (packet->activity_tgt == EXTRA_NONE) { - punit->activity_target = NULL; + punit->activity_target = nullptr; } else { punit->activity_target = extra_by_number(packet->activity_tgt); } @@ -1695,19 +1707,26 @@ static bool handle_unit_packet_common(struct unit *packet_unit) bool need_units_report_update = FALSE; bool repaint_unit = FALSE; bool repaint_city = FALSE; /* regards unit's homecity */ - struct tile *old_tile = NULL; + struct tile *old_tile = nullptr; bool check_focus = FALSE; /* conservative focus change */ bool moved = FALSE; bool ret = FALSE; + struct player *owner = unit_owner(packet_unit); + struct player *plr = client_player(); - punit = player_unit_by_number(unit_owner(packet_unit), packet_unit->id); - if (!punit && game_unit_by_number(packet_unit->id)) { + if (owner == nullptr) { + punit = nullptr; + } else { + punit = player_unit_by_number(owner, packet_unit->id); + } + + if (punit == nullptr && game_unit_by_number(packet_unit->id)) { /* This means unit has changed owner. We deal with this here * by simply deleting the old one and creating a new one. */ handle_unit_remove(packet_unit->id); } - if (punit) { + if (punit != nullptr) { /* In some situations, the size of repaint units require can change; * in particular, city-builder units sometimes get a potential-city * outline, but to speed up redraws we don't repaint this whole area @@ -1728,8 +1747,8 @@ static bool handle_unit_packet_common(struct unit *packet_unit) if (punit->ssa_controller != packet_unit->ssa_controller) { punit->ssa_controller = packet_unit->ssa_controller; repaint_unit = TRUE; - /* AI is set: may change focus */ - /* AI is cleared: keep focus */ + /* AI is set: May change focus */ + /* AI is cleared: Keep focus */ if (packet_unit->ssa_controller != SSA_NONE && unit_is_in_focus(punit)) { check_focus = TRUE; @@ -1765,14 +1784,14 @@ static bool handle_unit_packet_common(struct unit *packet_unit) /* Wakeup Focus */ if (gui_options.wakeup_focus - && NULL != client.conn.playing - && is_human(client.conn.playing) - && unit_owner(punit) == client.conn.playing + && plr != nullptr + && is_human(plr) + && owner == plr && punit->activity == ACTIVITY_SENTRY && packet_unit->activity == ACTIVITY_IDLE && !unit_is_in_focus(punit) - && is_player_phase(client.conn.playing, game.info.phase)) { - /* many wakeup units per tile are handled */ + && is_player_phase(plr, game.info.phase)) { + /* Many wakeup units per tile are handled */ unit_focus_urgent(punit); check_focus = FALSE; /* and keep it */ } @@ -1794,8 +1813,8 @@ static bool handle_unit_packet_common(struct unit *packet_unit) if (punit->client.occupied != packet_unit->client.occupied) { if (get_focus_unit_on_tile(unit_tile(packet_unit))) { /* Special case: (un)loading a unit in a transporter on the same - *tile as the focus unit may (dis)allow the focus unit to be - * loaded. Thus the orders->(un)load menu item needs updating. */ + * tile as the focus unit may (dis)allow the focus unit to be + * loaded. Thus the orders->(un)load menu item needs updating. */ need_menus_update = TRUE; } punit->client.occupied = packet_unit->client.occupied; @@ -1812,10 +1831,9 @@ static bool handle_unit_packet_common(struct unit *packet_unit) free(punit->orders.list); } punit->orders.list = packet_unit->orders.list; - packet_unit->orders.list = NULL; + packet_unit->orders.list = nullptr; - if (NULL == client.conn.playing - || unit_owner(punit) == client.conn.playing) { + if (plr == nullptr || owner == plr) { refresh_unit_city_dialogs(punit); } } /*** End of Change in activity or activity's target. ***/ @@ -1884,8 +1902,8 @@ static bool handle_unit_packet_common(struct unit *packet_unit) /* Show where the unit is going. */ do_move_unit(punit, packet_unit); - if (ccity != NULL) { - if (can_player_see_units_in_city(client.conn.playing, ccity)) { + if (ccity != nullptr) { + if (can_player_see_units_in_city(plr, ccity)) { /* Unit moved out of a city - update the occupied status. */ bool new_occupied = (unit_list_size(ccity->tile->units) > 0); @@ -1907,7 +1925,7 @@ static bool handle_unit_packet_common(struct unit *packet_unit) } if ((ccity = tile_city(unit_tile(punit)))) { - if (can_player_see_units_in_city(client.conn.playing, ccity)) { + if (can_player_see_units_in_city(plr, ccity)) { /* Unit moved into a city - obviously it's occupied. */ if (!ccity->client.occupied) { ccity->client.occupied = TRUE; @@ -1992,7 +2010,9 @@ static bool handle_unit_packet_common(struct unit *packet_unit) punit = packet_unit; idex_register_unit(&wld, punit); - unit_list_prepend(unit_owner(punit)->units, punit); + if (owner != nullptr) { + unit_list_prepend(owner->units, punit); + } unit_list_prepend(unit_tile(punit)->units, punit); unit_register_battlegroup(punit); @@ -2050,6 +2070,7 @@ static bool handle_unit_packet_common(struct unit *packet_unit) /* First, we have to unload the unit from its old transporter. */ unit_transport_unload(punit); unit_transport_load(punit, ptrans, TRUE); + #ifdef DEBUG_TRANSPORT log_debug("load %s (ID: %d) onto %s (ID: %d)", unit_name_translation(punit), punit->id, @@ -2062,6 +2083,7 @@ static bool handle_unit_packet_common(struct unit *packet_unit) log_debug("%s (ID: %d) is not loaded", unit_name_translation(punit), punit->id); #endif /* DEBUG_TRANSPORT */ + } } @@ -2078,9 +2100,9 @@ static bool handle_unit_packet_common(struct unit *packet_unit) } if ((check_focus || get_num_units_in_focus() == 0) - && NULL != client.conn.playing - && is_human(client.conn.playing) - && is_player_phase(client.conn.playing, game.info.phase)) { + && plr != nullptr + && is_human(plr) + && is_player_phase(plr, game.info.phase)) { unit_focus_update(); } @@ -2088,7 +2110,7 @@ static bool handle_unit_packet_common(struct unit *packet_unit) menus_update(); } - if (!client_has_player() || unit_owner(punit) == client_player()) { + if (!client_has_player() || owner == plr) { if (need_economy_report_update) { economy_report_dialog_update(); } @@ -2158,13 +2180,15 @@ void handle_unit_short_info(const struct packet_unit_short_info *packet) /* Append a unit struct to the proper list. */ punit = unpackage_short_unit(packet); - if (packet->packet_use == UNIT_INFO_CITY_SUPPORTED) { - fc_assert(pcity->client.collecting_info_units_supported != NULL); - unit_list_append(pcity->client.collecting_info_units_supported, punit); - } else { - fc_assert(packet->packet_use == UNIT_INFO_CITY_PRESENT); - fc_assert(pcity->client.collecting_info_units_present != NULL); - unit_list_append(pcity->client.collecting_info_units_present, punit); + if (punit != nullptr) { + if (packet->packet_use == UNIT_INFO_CITY_SUPPORTED) { + fc_assert(pcity->client.collecting_info_units_supported != NULL); + unit_list_append(pcity->client.collecting_info_units_supported, punit); + } else { + fc_assert(packet->packet_use == UNIT_INFO_CITY_PRESENT); + fc_assert(pcity->client.collecting_info_units_present != NULL); + unit_list_append(pcity->client.collecting_info_units_present, punit); + } } /* Done with special case. */ @@ -2176,7 +2200,7 @@ void handle_unit_short_info(const struct packet_unit_short_info *packet) } punit = unpackage_short_unit(packet); - if (handle_unit_packet_common(punit)) { + if (punit != nullptr && handle_unit_packet_common(punit)) { punit->client.transported_by = -1; unit_virtual_destroy(punit); } diff --git a/common/networking/packets.def b/common/networking/packets.def index b58822a924..1eeda3577d 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -313,7 +313,7 @@ type GOVERNMENT = sint8(Government_type_id) type IMPROVEMENT = uint8(Impr_type_id) type MULTIPLIER = uint8(Multiplier_type_id) type NATION = sint16(Nation_type_id) -type PLAYER = UINT16 +type PLAYER = SINT16 type RESEARCH = UINT8 type RESOURCE = uint8(Resource_type_id) type SPECIALIST = uint8(Specialist_type_id) diff --git a/common/player.h b/common/player.h index 4d06f73d6a..15dbb28629 100644 --- a/common/player.h +++ b/common/player.h @@ -47,6 +47,8 @@ struct nation_type; * anonymous. */ #define ANON_USER_NAME N_("Unassigned") +#define OWNER_NONE (-1) + enum plrcolor_mode { PLRCOL_PLR_ORDER, PLRCOL_PLR_RANDOM, diff --git a/common/unit.c b/common/unit.c index 5ac3e4febb..da70fc126e 100644 --- a/common/unit.c +++ b/common/unit.c @@ -1609,7 +1609,7 @@ bool is_targeted_activity(enum unit_activity activity) } /**********************************************************************//** - Create a virtual unit skeleton. pcity can be NULL, but then you need + Create a virtual unit skeleton. pcity can be nullptr, but then you need to set tile and homecity yourself. **************************************************************************/ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, @@ -1624,26 +1624,26 @@ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, /* It does not register the unit so the id is set to 0. */ punit->id = IDENTITY_NUMBER_ZERO; - fc_assert_ret_val(NULL != punittype, NULL); /* No untyped units! */ + fc_assert_ret_val(punittype != nullptr, nullptr); /* No untyped units! */ punit->utype = punittype; - fc_assert_ret_val(NULL != pplayer, NULL); /* No unowned units! */ + fc_assert_ret_val(!is_server() || pplayer != nullptr, nullptr); /* No unowned units! */ punit->owner = pplayer; punit->nationality = pplayer; punit->refcount = 1; punit->facing = rand_direction(); - if (pcity) { + if (pcity != nullptr) { unit_tile_set(punit, pcity->tile); punit->homecity = pcity->id; } else { - unit_tile_set(punit, NULL); + unit_tile_set(punit, nullptr); punit->homecity = IDENTITY_NUMBER_ZERO; } memset(punit->upkeep, 0, O_LAST * sizeof(*punit->upkeep)); - punit->goto_tile = NULL; + punit->goto_tile = nullptr; max_vet_lvl = utype_veteran_levels(punittype) - 1; punit->veteran = MIN(veteran_level, max_vet_lvl); /* A unit new and fresh ... */ @@ -1663,17 +1663,17 @@ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, punit->paradropped = FALSE; punit->done_moving = FALSE; - punit->transporter = NULL; + punit->transporter = nullptr; punit->transporting = unit_list_new(); - punit->carrying = NULL; + punit->carrying = nullptr; set_unit_activity(punit, ACTIVITY_IDLE); punit->battlegroup = BATTLEGROUP_NONE; punit->has_orders = FALSE; punit->action_decision_want = ACT_DEC_NOTHING; - punit->action_decision_tile = NULL; + punit->action_decision_tile = nullptr; punit->stay = FALSE; @@ -1683,7 +1683,7 @@ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, punit->server.dying = FALSE; - punit->server.removal_callback = NULL; + punit->server.removal_callback = nullptr; memset(punit->server.upkeep_paid, 0, O_LAST * sizeof(*punit->server.upkeep_paid)); @@ -1691,7 +1691,7 @@ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, punit->server.ord_map = 0; punit->server.ord_city = 0; - punit->server.vision = NULL; /* No vision. */ + punit->server.vision = nullptr; /* No vision. */ punit->server.action_timestamp = 0; /* Must be an invalid turn number, and an invalid previous turn * number. */ @@ -1705,7 +1705,7 @@ struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity, punit->client.focus_status = FOCUS_AVAIL; punit->client.transported_by = -1; punit->client.colored = FALSE; - punit->client.act_prob_cache = NULL; + punit->client.act_prob_cache = nullptr; } return punit; -- 2.40.1