News:

Simutrans.com Portal
Our Simutrans site. You can find everything about Simutrans from here.

Assertion failed (rev6646)

Started by whoami, August 15, 2013, 12:34:41 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

whoami

Maybe this occurs to other people, too: After updating vom rev6585 to 6646 (Win-SDL nightly, with pak64), Simutrans stumbled twice over the same assertion (simplan.cc line 201). At the second instant, I ignored the error and was able to continue in fast-forward without interaction and without another error for quite some time. So it was likely caused by some changes in the game by me, but tries to reproduce have not been successful yet.


kierongreen

Was there anything in particular you were doing at the time - using a tool, altering landscape? Or was it during map load/generation?

whoami

I have changed a few slopes in order to prepare roads for a useful city layout (the city building rules often create blocks with width 1), but I mostly replaced and added vehicles on train and bus lines.

Ters

Did you use a specific tool which triggered this? As far as I can tell, this error can only occur when someone, human player or AI, changes the landscape.

whoami

#4
As far as I remember, I used only up ('u') and down ('d') to keep natural slopes. I will try to reproduce with the info from your comments. The assertion contains is_halt - can an inaccessible waypoint (after changing the landscape) be the reason?

EDIT: removed duplicate characters

kierongreen

The code around this assert is:

void planquadrat_t::boden_ersetzen(grund_t *alt, grund_t *neu)
{
assert(alt!=NULL  &&  neu!=NULL  &&  !alt->is_halt()  );
...


Now neu and alt should always be valid (see below). is_halt here refers to actual stations rather than waypoints.  So the most likely scenario I think is that you were doing something which required changing grounds at a station. A full backtrace from a reproducible error would of course be very handy :)

boden ersetzen itself is not called from that many places in simutrans:

gebaeude_t* hausbauer_t::baue(karte_t* welt, spieler_t* sp, koord3d pos, int org_layout, const haus_besch_t* besch, void* param)
{
...
for(k.y = 0; k.y < dim.y; k.y ++) {
for(k.x = 0; k.x < dim.x; k.x ++) {
...
grund_t *gr = welt->lookup_kartenboden(pos.get_2d() + k);
...
grund_t *gr2 = new fundament_t(welt, gr->get_pos(), gr->get_grund_hang());
welt->access(gr->get_pos().get_2d())->boden_ersetzen(gr, gr2);
...

Here there are numerous places before boden_ersetzen which assume gr is valid, and gr2 must be valid.


fabrik_t::~fabrik_t()
{
...
if (plan) {
grund_t *gr = plan->get_kartenboden();
...
plan->boden_ersetzen( gr, new boden_t( welt, gr->get_pos(), hang_t::flach ) );
...

Here plan and thus gr must be valid , as is new boden_t.


void fabrik_t::baue(sint32 rotate, bool build_fields, bool force_initial_prodbase)
{
...
for(  uint16 i=0;  i<fields.get_count();  i++   ) {
const koord k = fields[i].location;
grund_t *gr=welt->lookup_kartenboden(k);
...
grund_t *gr2 = new fundament_t(welt, gr->get_pos(), gr->get_grund_hang());
welt->access(k)->boden_ersetzen(gr, gr2);
...

Here gr should be valid assuming fields have been allocated valid positions.


bool fabrik_t::add_random_field(uint16 probability)
{
...
grund_t *gr = welt->lookup_kartenboden(pos.get_2d()+koord(xoff,yoff));
if (gr != NULL &&
...
build_locations.append(gr);
...
if (!build_locations.empty()) {
grund_t *gr = build_locations.at(simrand(build_locations.get_count()));
...
grund_t *gr2 = new fundament_t(welt, gr->get_pos(), gr->get_grund_hang());
welt->access(k)->boden_ersetzen(gr, gr2);
...

Here  gr and gr2 must be valid.


void planquadrat_t::kartenboden_setzen(grund_t *bd)
{
assert(bd);
grund_t *tmp = get_kartenboden();
if(tmp) {
boden_ersetzen(tmp,bd);

Here tmp and bd must be valid.


bool wkz_remover_t::wkz_remover_intern(spieler_t *sp, karte_t *welt, koord3d pos, const char *&msg)
{
...
grund_t *gr = welt->lookup(pos);
if (!gr) {
msg = "";
return false;
}
...
koord k(pos.get_2d());
...
welt->access(k)->boden_ersetzen( gr, new boden_t(welt, gr->get_pos(), welt->recalc_natural_slope(k,dummy) ) );
...

Here gr and boden_t must be valid.


...
const char *wkz_wayremover_t::do_work( karte_t *welt, spieler_t *sp, const koord3d &start, const koord3d &end )
{
...
grund_t *gr=welt->lookup(verbindung.position_bei(i));

// ground can be missing after deleting a bridge ...
if(gr  &&  !gr->ist_wasser()) {
...
grund_t *gr_new = new boden_t(welt, gr->get_pos(), gr->get_grund_hang());
welt->access(gr->get_pos().get_2d())->boden_ersetzen(gr, gr_new);
...

Here gr and gr_new must be valid.


kierongreen

Ok - here's a hunch. Were you by any chance swapping between players (including between human and public service), building and/or demolishing station tiles possibly belonging to a different player than built them, and then editing the landscape after?