add checks to avoid potential segfaults. use more dfhack idiomatic code

develop
Dan Amlund 2018-01-31 20:01:49 +01:00
parent 537e94d75a
commit 38491b4be8
1 changed files with 43 additions and 36 deletions

@ -951,11 +951,16 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_announcelistst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_announcelistst, top))
{ {
if (screen->unit) {
// in (r)eports -> enter
auto *report = vector_get(screen->reports, screen->sel_idx); auto *report = vector_get(screen->reports, screen->sel_idx);
if (report)
{
for (df::unit *unit : world->units.all) for (df::unit *unit : world->units.all)
{ {
if (unit == screen->unit) if (unit && screen->report_type >= 0 && screen->report_type < 3
continue; && unit != screen->unit) // find 'other' unit related to this report
{
for (int32_t report_id : unit->reports.log[screen->report_type]) for (int32_t report_id : unit->reports.log[screen->report_type])
{ {
if (report_id == report->id) if (report_id == report->id)
@ -963,21 +968,27 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
} }
} }
} }
}
} else {
// in (a)nnouncements
return NULL; // cannot determine unit from reports
}
}
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_layer_militaryst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_layer_militaryst, top))
{ {
if (screen->page == df::viewscreen_layer_militaryst::T_page::Positions) { if (screen->page == df::viewscreen_layer_militaryst::T_page::Positions) {
auto positions = getLayerList(screen, 1); auto positions = getLayerList(screen, 1);
if (positions->enabled && positions->active) if (positions && positions->enabled && positions->active)
return vector_get(screen->positions.assigned, positions->cursor); return vector_get(screen->positions.assigned, positions->cursor);
auto candidates = getLayerList(screen, 2); auto candidates = getLayerList(screen, 2);
if (candidates->enabled && candidates->active) if (candidates && candidates->enabled && candidates->active)
return vector_get(screen->positions.candidates, candidates->cursor); return vector_get(screen->positions.candidates, candidates->cursor);
} }
if (screen->page == df::viewscreen_layer_militaryst::T_page::Equip) { if (screen->page == df::viewscreen_layer_militaryst::T_page::Equip) {
auto positions = getLayerList(screen, 1); auto positions = getLayerList(screen, 1);
if (positions->enabled && positions->active) if (positions && positions->enabled && positions->active)
return vector_get(screen->equip.units, positions->cursor); return vector_get(screen->equip.units, positions->cursor);
} }
} }
@ -994,6 +1005,9 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
if (!Gui::dwarfmode_hotkey(top)) if (!Gui::dwarfmode_hotkey(top))
return NULL; return NULL;
if (!ui)
return NULL;
// general assigning units in building, i.e. (q)uery cage -> (a)ssign // general assigning units in building, i.e. (q)uery cage -> (a)ssign
if (ui_building_in_assign && *ui_building_in_assign if (ui_building_in_assign && *ui_building_in_assign
&& ui_building_assign_units && ui_building_item_cursor && ui_building_assign_units && ui_building_item_cursor
@ -1006,7 +1020,7 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
switch (ui->main.mode) { switch (ui->main.mode) {
case ViewUnits: case ViewUnits:
{ {
if (!ui_selected_unit) if (!ui_selected_unit || !ui_selected_unit)
return NULL; return NULL;
return vector_get(world->units.active, *ui_selected_unit); return vector_get(world->units.active, *ui_selected_unit);
@ -1014,10 +1028,10 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
case ZonesPitInfo: // (i) zone -> (P)it case ZonesPitInfo: // (i) zone -> (P)it
case ZonesPenInfo: // (i) zone -> pe(N) case ZonesPenInfo: // (i) zone -> pe(N)
{ {
if (!ui_building_assign_units || !ui_building_item_cursor) if (ui_building_assign_units || ui_building_item_cursor)
return NULL;
return vector_get(*ui_building_assign_units, *ui_building_item_cursor); return vector_get(*ui_building_assign_units, *ui_building_item_cursor);
return NULL;
} }
case Burrows: case Burrows:
{ {
@ -1028,12 +1042,13 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
} }
case QueryBuilding: case QueryBuilding:
{ {
df::building *building = getAnyBuilding(top); if (df::building *building = getAnyBuilding(top))
if (building->getType() == df::building_type::Cage) {
if (VIRTUAL_CAST_VAR(cage, df::building_cagest, building))
{ {
auto *cage = static_cast<df::building_cagest*>(building); if (ui_building_item_cursor)
if (*ui_building_item_cursor < cage->assigned_units.size()) return df::unit::find(vector_get(cage->assigned_units, *ui_building_item_cursor));
return df::unit::find(cage->assigned_units[*ui_building_item_cursor]); }
} }
return NULL; return NULL;
} }
@ -1042,24 +1057,16 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
if (!ui_look_list || !ui_look_cursor) if (!ui_look_list || !ui_look_cursor)
return NULL; return NULL;
auto item = vector_get(ui_look_list->items, *ui_look_cursor); if (auto item = vector_get(ui_look_list->items, *ui_look_cursor))
if (item) { {
if (item->type == df::ui_look_list::T_items::Unit) if (item->type == df::ui_look_list::T_items::Unit)
return item->unit; return item->unit;
else if (item->type == df::ui_look_list::T_items::Item) else if (item->type == df::ui_look_list::T_items::Item)
{ {
if (item->item->getType() == df::item_type::CORPSE) if (VIRTUAL_CAST_VAR(corpse, df::item_corpsest, item->item))
{ return df::unit::find(corpse->unit_id); // loo(k) at corpse
// loo(k) at corpse else if (VIRTUAL_CAST_VAR(corpsepiece, df::item_corpsepiecest, item->item))
auto *corpse = static_cast<df::item_corpsest*>(item->item); return df::unit::find(corpsepiece->unit_id); // loo(k) at corpse piece
return df::unit::find(corpse->unit_id);
}
else if (item->item->getType() == df::item_type::CORPSEPIECE)
{
// loo(k) at corpse piece
auto *corpsepiece = static_cast<df::item_corpsepiecest*>(item->item);
return df::unit::find(corpsepiece->unit_id);
}
} }
else if (item->type == df::ui_look_list::T_items::Spatter) else if (item->type == df::ui_look_list::T_items::Spatter)
{ {