~widelands-dev/widelands/trunk

« back to all changes in this revision

Viewing changes to src/logic/worker.cc

  • Committer: sigra
  • Date: 2010-01-04 03:32:50 UTC
  • Revision ID: git-v1:82d9f24adcbde7d19f90434aac5f96c7df58aa10
Fix bug #2924988 (crash when initialization removed between game preload and game start) reported by qcs - Qcumber-some.

Before the game is set up, the tribes are preloaded, which means that it is checked which tribes exist and which initializations each tribe has, so that each player can select a tribe and an initialization. The selected initialization is saved as an index. When the game is finally started, the tribes are fully read. Then a player is initialized with the initialization with the stored index.

But if for example a player has selected the initialization with index 1, then the tribe is edited so that there is no initialization with that index (such as only the initialization with index 0 remains), then the game i started, the tribe fully read, the player initialized with initialization 1, an assertion will fail in debug builds (and an out-of-range access will be done in release builds.

Now throw game_data_error when this happens. Of course it may still behave a bit unexpected if a player selects initialization a with index 0 and then initializaion a is removed and initialization b has index 0, but at least a crash is fixed.

Also make donkey breeding less broken.

git-svn-id: https://widelands.svn.sourceforge.net/svnroot/widelands/trunk@4870 37b2a8de-5219-0410-9f54-a31bc463ab9c

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team
 
2
 * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU General Public License
1736
1736
        // flag is removed or a warehouse connects to the Economy).
1737
1737
        if (!m_supply)
1738
1738
                m_supply = new IdleWorkerSupply(*this);
 
1739
        if (name() == "donkey")
 
1740
                molog
 
1741
                        ("Worker::gowarehouse_update: donkey at (%i, %i): nothing to do, "
 
1742
                         "starting task idle\n", get_position().x, get_position().y);
1739
1743
        return start_task_idle(game, get_animation("idle"), 1000);
1740
1744
}
1741
1745
 
1764
1768
        0
1765
1769
};
1766
1770
 
 
1771
const Bob::Task Worker::taskReleaserecruit = {
 
1772
        "releaserecruit",
 
1773
        static_cast<Bob::Ptr>(&Worker::releaserecruit_update),
 
1774
        0,
 
1775
        0
 
1776
};
 
1777
 
1767
1778
/**
1768
1779
 * Walk to the building's flag, drop the given item, and walk back inside.
1769
1780
 */
1806
1817
                                flag->add_item(game, *fetch_carried_item(game));
1807
1818
 
1808
1819
                                set_animation(game, descr().get_animation("idle"));
1809
 
                                schedule_act(game, 50);
1810
 
                                return;
 
1820
                                return schedule_act(game, 50);
1811
1821
                        }
1812
1822
 
1813
1823
                        molog("[dropoff]: flag is overloaded\n");
1846
1856
}
1847
1857
 
1848
1858
 
 
1859
/// Give the recruit his diploma and say farwell to him.
 
1860
void Worker::start_task_releaserecruit(Game & game, Worker & recruit)
 
1861
{
 
1862
        push_task(game, taskReleaserecruit);
 
1863
        molog
 
1864
                ("Starting to release %s %u...\n",
 
1865
                 recruit.descname().c_str(), recruit.serial());
 
1866
        return schedule_act(game, 5000);
 
1867
}
 
1868
 
 
1869
void Worker::releaserecruit_update(Game & game, State &)
 
1870
{
 
1871
        molog("\t...done releasing recruit\n");
 
1872
        return pop_task(game);
 
1873
}
 
1874
 
1849
1875
/**
1850
1876
 * ivar1 is set to 0 if we should move to the flag and fetch the item, and it
1851
1877
 * is set to 1 if we should move into the building.
2457
2483
                while (list.empty() and fringe_size < 10) {
2458
2484
                        while (mr.advance(map)) {
2459
2485
                                idx = map.get_index(mr.location(), map.get_width());
2460
 
                                Vision v = owner().vision(idx);
 
2486
                                Vision const v = owner().vision(idx);
2461
2487
                                if (v == 0) {
2462
2488
                                        // nominate this
2463
2489
                                        list.push_back(mr.location());
2474
2500
                        mr.extend(map);
2475
2501
                }
2476
2502
 
2477
 
                while (list.size() > 0) {
2478
 
                        // select a random field
2479
 
                        uint8_t lidx = game.logic_rand() % list.size();
2480
 
                        Coords coord = list[lidx];
 
2503
                while (list.size() > 0) { //  select a random node
 
2504
                        uint8_t const lidx = game.logic_rand() % list.size();
 
2505
                        Coords const coord = list[lidx];
2481
2506
                        list.erase(list.begin() + lidx);
2482
2507
                        if
2483
2508
                                (start_task_movepath
2484
 
                                 (game, coord, 0,
2485
 
                                  descr().get_right_walk_anims(does_carry_ware())))
 
2509
                                        (game, coord, 0,
 
2510
                                         descr().get_right_walk_anims(does_carry_ware())))
2486
2511
                        {
2487
2512
                                return;
2488
2513
                        }
2507
2532
        // Area around our home
2508
2533
        Area<FCoords> owner_area
2509
2534
                (map.get_fcoords
2510
 
                 (ref_cast<Building, PlayerImmovable>
2511
 
                  (*get_location(game)).get_position()),
2512
 
                  1);
 
2535
                        (ref_cast<Building, PlayerImmovable>
 
2536
                                (*get_location(game)).get_position()),
 
2537
                 1);
2513
2538
 
2514
2539
        // and we are not already home
2515
2540
        if (get_position() == owner_area)