Skip to content

Commit

Permalink
bridge and tunnel construction/removal simplified and hopefully fixed
Browse files Browse the repository at this point in the history
git-svn-id: svn://tron.homeunix.org/simutrans/simutrans/trunk@368 8aca7d54-2c30-db11-9de9-000461428c89
  • Loading branch information
prissi committed Nov 14, 2006
1 parent 0e7d64c commit 1c3aacf
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 179 deletions.
86 changes: 38 additions & 48 deletions bauer/brueckenbauer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ brueckenbauer_t::finde_ende(karte_t *welt, koord3d pos, koord zv, waytype_t wegt
return koord3d::invalid;
}



bool brueckenbauer_t::ist_ende_ok(spieler_t *sp, const grund_t *gr)
{
if(gr->gib_typ()!=grund_t::boden && gr->gib_typ()!=grund_t::monorailboden) {
Expand Down Expand Up @@ -407,9 +409,11 @@ bool brueckenbauer_t::baue_bruecke(karte_t *welt, spieler_t *sp,
weg->setze_max_speed(besch->gib_topspeed());
welt->access(pos.gib_2d())->boden_hinzufuegen(bruecke);
bruecke->neuen_weg_bauen(weg, ribi_t::doppelt(ribi), sp);

sp->add_maintenance( -weg_besch->gib_wartung() );
sp->add_maintenance( besch->gib_wartung() );
bruecke->obj_add(new bruecke_t(welt, bruecke->gib_pos(), 0, sp, besch, besch->gib_simple(ribi)));

bruecke->obj_add(new bruecke_t(welt, bruecke->gib_pos(), sp, besch, besch->gib_simple(ribi)));
bruecke->calc_bild();

//DBG_MESSAGE("bool brueckenbauer_t::baue_bruecke()","at (%i,%i)",pos.x,pos.y);
Expand Down Expand Up @@ -445,55 +449,48 @@ void
brueckenbauer_t::baue_auffahrt(karte_t *welt, spieler_t *sp, koord3d end, koord zv, const bruecke_besch_t *besch, const weg_besch_t *weg_besch)
{
grund_t *alter_boden = welt->lookup(end);
weg_t *weg=0;
ribi_t::ribi ribi_neu;
brueckenboden_t *bruecke;
int weg_hang = 0;
hang_t::typ grund_hang = alter_boden->gib_grund_hang();
bruecke_besch_t::img_t img;
int yoff;

ribi_neu = ribi_typ(zv);
if(grund_hang == hang_t::flach) {
weg_hang = hang_typ(zv); // nordhang - suedrampe
}
bruecke = new brueckenboden_t(welt, end, grund_hang, weg_hang);

weg_t *alter_weg = alter_boden->gib_weg(besch->gib_waytype());
weg = weg_t::alloc(besch->gib_waytype());

bruecke = new brueckenboden_t(welt, end, grund_hang, weg_hang);
// add the ramp
if(bruecke->gib_grund_hang() == hang_t::flach) {
yoff = 0;
img = besch->gib_rampe(ribi_neu);
}
else {
yoff = -16;
img = besch->gib_start(ribi_neu);
}
bruecke->obj_add(new bruecke_t(welt, end, yoff, sp, besch, img));
bruecke->setze_besitzer( sp );

if(alter_weg==NULL) {
weg->setze_besch(weg_besch);
sp->buche(weg_besch->gib_preis(), alter_boden->gib_pos().gib_2d(), COST_CONSTRUCTION);
weg_t *weg=alter_boden->gib_weg( besch->gib_waytype() );
// take care of everything on that tile ...
bruecke->take_obj_from( alter_boden );
welt->access(end.gib_2d())->kartenboden_setzen( bruecke, false );
if(weg) {
// has already a way
bruecke->weg_erweitern(besch->gib_waytype(), ribi_t::doppelt(ribi_neu));
}
else {
// here was a way before
weg->setze_besch(alter_weg->gib_besch());
weg->setze_ribi_maske( alter_weg->gib_ribi_maske() );
alter_boden->weg_entfernen(weg->gib_waytype(),false);
// take care of everything on that tile ...
bruecke->take_obj_from( alter_boden );
// needs still one
weg = weg_t::alloc( besch->gib_waytype() );
bruecke->neuen_weg_bauen( weg, ribi_t::doppelt(ribi_neu), sp );
}
weg->setze_max_speed( besch->gib_topspeed() );
welt->access(end.gib_2d())->kartenboden_setzen( bruecke, false );
bruecke->neuen_weg_bauen(weg, ribi_t::doppelt(ribi_neu), sp);
bruecke->obj_add(new bruecke_t(welt, end, sp, besch, img));
bruecke->calc_bild();

if(sp!=NULL) {
sp->add_maintenance( -weg_besch->gib_wartung() );
sp->add_maintenance( besch->gib_wartung() );
// no undo possible anymore
sp->init_undo(besch->gib_waytype(),0);
sp->init_undo( besch->gib_waytype(), 0 );
}
}

Expand All @@ -509,8 +506,6 @@ brueckenbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d pos, waytype_t weg
slist_tpl<koord3d> tmp_list;
const char *msg;

const bruecke_besch_t *br_besch=dynamic_cast<bruecke_t *>(welt->lookup(pos)->suche_obj(ding_t::bruecke))->gib_besch();

// Erstmal das ganze Außmaß der Brücke bestimmen und sehen,
// ob uns was im Weg ist.
tmp_list.insert(pos);
Expand Down Expand Up @@ -559,11 +554,9 @@ brueckenbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d pos, waytype_t weg
pos = part_list.remove_first();

grund_t *gr = welt->lookup(pos);
sp->add_maintenance( -br_besch->gib_wartung() );

gr->remove_everything_from_way(sp,wegtyp,ribi_t::keine); // removes stop and signals correctly
// we may have a second way here ...
gr->obj_loesche_alle(sp);
gr->weg_entfernen(wegtyp, false);
welt->access(pos.gib_2d())->boden_entfernen(gr);
delete gr;

Expand All @@ -589,29 +582,26 @@ brueckenbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d pos, waytype_t weg
else {
ribi &= ~ribi_typ(gr->gib_weg_hang());
}
const weg_besch_t *weg_besch=gr->gib_weg(wegtyp)->gib_besch();

// delete the bruecke
ding_t *bruecke = gr->suche_obj(ding_t::bruecke);
bruecke->entferne( sp );
delete bruecke;

// take care of everything on that tile ... (zero is the bridge itself)
grund_t *gr_new = new boden_t(welt, pos,gr->gib_grund_hang());

// remove all ways, copy the rest ...
gr_new->take_obj_from( gr );
if(gr->gib_weg_nr(1)) {
gr->weg_entfernen(gr->gib_weg_nr(1)->gib_waytype(), false);
// removes single signals, bridge head, pedestrians, stops, changes catenary etc
gr->remove_everything_from_way(sp,wegtyp,ribi); // removes stop and signals correctly

// corrects the ways
weg_t *weg=gr->gib_weg_nr(0);
if(weg) {
// may fail, if this was the last tile
weg->setze_besch(weg->gib_besch());
weg->setze_ribi( ribi );
if(gr->gib_weg_nr(1)) {
gr->gib_weg_nr(1)->setze_ribi( ribi );
}
}
gr->weg_entfernen(wegtyp, false);

// Neuen Boden wieder mit Weg versehen
welt->access(pos.gib_2d())->kartenboden_setzen(gr_new, true);
weg_t *weg = weg_t::alloc(wegtyp);
weg->setze_besch(weg_besch);
sp->add_maintenance( weg_besch->gib_wartung());
gr_new->neuen_weg_bauen(weg, ribi, sp);
// then add the new ground, copy everything and replace the old one
grund_t *gr_new = new boden_t(welt, pos, gr->gib_grund_hang());
gr_new->setze_besitzer( sp );
gr_new->take_obj_from( gr );
welt->access(pos.gib_2d())->kartenboden_setzen(gr_new, false);
gr_new->calc_bild();
}

Expand Down
104 changes: 44 additions & 60 deletions bauer/tunnelbauer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ DBG_MESSAGE("tunnelbauer_t::baue()","build from (%d,%d)", pos.x, pos.y);
ribi = welt->lookup(pos)->gib_weg_ribi_unmasked(wegtyp);
pos = pos + zv;

// Now we build the inviosible part
// Now we build the invisible part
while(pos.gib_2d()!=end.gib_2d()) {
tunnelboden_t *tunnel = new tunnelboden_t(welt, pos, 0);
// use the fastest way
Expand All @@ -393,8 +393,7 @@ DBG_MESSAGE("tunnelbauer_t::baue()","build from (%d,%d)", pos.x, pos.y);

baue_einfahrt(welt, sp, pos, -zv, besch, weg_besch, cost);

sp->buche(cost, start.gib_2d(), COST_CONSTRUCTION);
((tunnel_t *)(welt->lookup(start)->suche_obj(ding_t::tunnel)))->laden_abschliessen();
sp->buche( -cost, start.gib_2d(), COST_CONSTRUCTION);
return true;
}

Expand All @@ -405,35 +404,33 @@ tunnelbauer_t::baue_einfahrt(karte_t *welt, spieler_t *sp, koord3d end, koord zv
{
grund_t *alter_boden = welt->lookup(end);
ribi_t::ribi ribi = alter_boden->gib_weg_ribi_unmasked(besch->gib_waytype()) | ribi_typ(zv);
weg_t *alter_weg = alter_boden->gib_weg(besch->gib_waytype());

tunnelboden_t *tunnel = new tunnelboden_t(welt, end, alter_boden->gib_grund_hang());
tunnel->setze_besitzer(sp);
tunnel->obj_add(new tunnel_t(welt, end, sp, besch));

DBG_MESSAGE("tunnelbauer_t::baue_einfahrt()","at end (%d,%d) for %s", end.x, end.y, weg_besch->gib_name());

weg_t *weg = weg_t::alloc(besch->gib_waytype());
if(alter_weg) {
weg->setze_besch(alter_weg->gib_besch());
weg->setze_ribi_maske( alter_weg->gib_ribi_maske() );
tunnel->take_obj_from( alter_boden );
alter_boden->weg_entfernen(besch->gib_waytype(),false);
weg_t *weg=alter_boden->gib_weg( besch->gib_waytype() );
// take care of everything on that tile ...
tunnel->take_obj_from( alter_boden );
welt->access(end.gib_2d())->kartenboden_setzen( tunnel, false );
if(weg) {
// has already a way
tunnel->weg_erweitern(besch->gib_waytype(), ribi);
}
else {
weg->setze_besch(weg_besch);
cost += weg_besch->gib_preis();
// needs still one
weg = weg_t::alloc( besch->gib_waytype() );
tunnel->neuen_weg_bauen( weg, ribi, sp );
}
weg->setze_max_speed( besch->gib_topspeed() );
tunnel->calc_bild();

welt->access(end.gib_2d())->kartenboden_setzen( tunnel, false );
tunnel->neuen_weg_bauen(weg, ribi, sp);
sp->add_maintenance( -weg->gib_besch()->gib_wartung() );
sp->add_maintenance( besch->gib_wartung() );
cost += besch->gib_preis();

// no undo possible anymore
if(sp!=NULL) {
sp->init_undo(besch->gib_waytype(),0);
sp->add_maintenance( -weg_besch->gib_wartung() );
sp->add_maintenance( besch->gib_wartung() );
sp->init_undo( besch->gib_waytype(), 0 );
}
cost += besch->gib_preis();
}


Expand Down Expand Up @@ -497,21 +494,10 @@ tunnelbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d start, waytype_t weg
// Jetzt geht es ans löschen der Tunnel
while(!part_list.is_empty()) {
pos = part_list.remove_first();

grund_t *gr = welt->lookup(pos);

if(gr->gib_besitzer()) {
sp->add_maintenance( gr->gib_weg_nr(0)->gib_besch()->gib_wartung());
sp->add_maintenance( -besch->gib_wartung() );
}
// remove all ways ...
if(gr->gib_weg_nr(1)) {
gr->weg_entfernen(gr->gib_weg_nr(1)->gib_waytype(), false);
}
gr->weg_entfernen(gr->gib_weg_nr(0)->gib_waytype(), false);
gr->remove_everything_from_way(sp,wegtyp,ribi_t::keine); // removes stop and signals correctly
// we may have a second way here ...
gr->obj_loesche_alle(sp);
cost += besch->gib_preis();

welt->access(pos.gib_2d())->boden_entfernen(gr);
delete gr;
}
Expand All @@ -521,36 +507,34 @@ tunnelbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d start, waytype_t weg
pos = end_list.remove_first();

grund_t *gr = welt->lookup(pos);
if(gr->gib_besitzer()) {
sp->add_maintenance( gr->gib_weg_nr(0)->gib_besch()->gib_wartung());
sp->add_maintenance( -besch->gib_wartung() );
ribi_t::ribi ribi = gr->gib_weg_ribi_unmasked(wegtyp);
if(gr->gib_grund_hang()!=hang_t::flach) {
ribi &= ~ribi_typ(gr->gib_grund_hang());
}
else {
ribi &= ~ribi_typ(hang_t::gegenueber(gr->gib_weg_hang()));
}

grund_t *gr_new = new boden_t(welt, pos, gr->gib_grund_hang() );


ribi_t::ribi ribi = gr->gib_weg_ribi_unmasked(wegtyp) &~ribi_typ(gr->gib_grund_hang());
weg_besch = gr->gib_weg(wegtyp)->gib_besch();
ding_t *tunnel = gr->suche_obj( ding_t::tunnel );
tunnel->entferne( sp );
delete tunnel;
gr_new->take_obj_from( gr );

// remove all ways ...
if(gr->gib_weg_nr(1)) {
gr->weg_entfernen(gr->gib_weg_nr(1)->gib_waytype(), false);
// removes single signals, bridge head, pedestrians, stops, changes catenary etc
gr->remove_everything_from_way(sp,wegtyp,ribi); // removes stop and signals correctly

// corrects the ways
weg_t *weg=gr->gib_weg_nr(0);
if(weg) {
// fails if it was preivously the last ribi
weg->setze_besch(weg->gib_besch());
weg->setze_ribi( ribi );
if(gr->gib_weg_nr(1)) {
gr->gib_weg_nr(1)->setze_ribi( ribi );
}
}
gr->weg_entfernen(gr->gib_weg_nr(0)->gib_waytype(), false);
cost += besch->gib_preis();

// then add the new ground, copy everything and replace the old one
grund_t *gr_new = new boden_t(welt, pos, gr->gib_grund_hang());
gr_new->setze_besitzer( sp );
gr_new->take_obj_from( gr );
welt->access(pos.gib_2d())->kartenboden_setzen(gr_new, false);

// Neuen Boden wieder mit Weg versehen
weg_t *weg = weg_t::alloc(besch->gib_waytype());
weg->setze_besch( weg_besch );
gr_new->neuen_weg_bauen( weg, ribi, sp );
gr_new->calc_bild();
}
welt->setze_dirty();
sp->buche(-cost, start.gib_2d(), COST_CONSTRUCTION);
return NULL;
}
36 changes: 24 additions & 12 deletions boden/grund.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,17 +393,22 @@ grund_t::~grund_t()



// moves all object from the old to the new grund_t
// moves all objects from the old to the new grund_t
void
grund_t::take_obj_from( grund_t *other_gr)
{
const uint8 top=other_gr->gib_top();
for( uint8 i=top; i>0; i-- ) {
ding_t *d=other_gr->obj_bei(i-1);
if(!d->is_way()) {
other_gr->obj_remove( d, NULL );
dinge.add( d );
}
// transfer all things
while( other_gr->gib_top() ) {
dinge.add( other_gr->obj_remove_top() );
}
// transfer the way flags
if(other_gr->get_flag(has_way1)) {
flags |= has_way1;
other_gr->clear_flag(has_way1);
}
if(other_gr->get_flag(has_way2)) {
flags |= has_way2;
other_gr->clear_flag(has_way2);
}
}

Expand Down Expand Up @@ -922,8 +927,9 @@ long grund_t::neuen_weg_bauen(weg_t *weg, ribi_t::ribi ribi, spieler_t *sp)
}

// just add the cost
if(gib_besitzer() && !ist_wasser()) {
gib_besitzer()->add_maintenance(weg->gib_besch()->gib_wartung());
if(sp && !ist_wasser()) {
sp->add_maintenance(weg->gib_besch()->gib_wartung());
weg->setze_besitzer( sp );
}
weg->setze_ribi(ribi);
weg->setze_pos(pos);
Expand Down Expand Up @@ -1109,8 +1115,8 @@ bool grund_t::remove_everything_from_way(spieler_t *sp,waytype_t wt,ribi_t::ribi

for(uint8 i=0; i<gib_top(); i++ ) {
ding_t *d=obj_bei(i);
// roadsigns: check dir
if(d==NULL) {
// do not delete ways
if(d->is_way()) {
continue;
}
// roadsigns: check dir: dirs changed? delete
Expand Down Expand Up @@ -1141,6 +1147,12 @@ bool grund_t::remove_everything_from_way(spieler_t *sp,waytype_t wt,ribi_t::ribi
else if(d->gib_typ()==ding_t::verkehr || suche_obj(ding_t::fussgaenger)) {
delete d;
}
// remove tunnel portal/bridge
else if(d->gib_typ()==ding_t::bruecke || suche_obj(ding_t::tunnel)) {
d->entferne(sp);
delete d;
}

}


Expand Down
Loading

0 comments on commit 1c3aacf

Please sign in to comment.