1239
1238
void Worker::start_task_transfer(Game & game, Transfer * t)
1241
// hackish override for gowarehouse
1242
if (State * const state = get_state(taskGowarehouse)) {
1243
assert(!state->transfer);
1240
// Hackish override for receiving transfers during gowarehouse,
1241
// and to correctly handle the stack during loading of games
1242
// (in that case, the transfer task already exists on the stack
1243
// when this is called).
1244
if (get_state(taskGowarehouse) || get_state(taskTransfer)) {
1245
assert(!m_transfer);
1245
state->transfer = t;
1246
1248
send_signal(game, "transfer");
1247
1249
} else { // just start a normal transfer
1248
1250
push_task(game, taskTransfer);
1249
top_state().transfer = t;
1255
void Worker::transfer_pop(Game & game, State & state)
1258
m_transfer->has_failed();
1254
1263
void Worker::transfer_update(Game & game, State & state) {
1255
1264
Map & map = game.map();
2269
2290
container_iterate_const(std::vector<ImmovableFound>, flags, i) {
2270
2291
Flag & flag = ref_cast<Flag, BaseImmovable>(*i.current->object);
2293
if (game.logic_rand() % 2 == 0)
2272
2296
int32_t const dist =
2273
2297
map.calc_distance(get_position(), i.current->coords);
2275
if (!best || dist < bestdist) {
2299
if (!best || bestdist > dist) {
2277
2301
bestdist = dist;
2283
static_cast<int32_t>(game.logic_rand() % 30) <= 30 - bestdist)
2305
if (best && bestdist > vision) {
2306
uint32_t chance = maxdist - (bestdist - vision);
2307
if (game.logic_rand() % maxdist >= chance)
2285
2312
molog("[fugitive]: try to move to flag\n");
2287
// \todo FIXME ??? \todo
2288
// warehouse could be on a different island, so check for failure
2314
// Warehouse could be on a different island, so check for failure
2315
// Also, move only a few number of steps in the right direction,
2316
// so that we could theoretically lose the flag again, but also
2317
// perhaps find a closer flag.
2290
2319
(start_task_movepath
2292
2321
best->get_position(),
2294
descr().get_right_walk_anims(does_carry_ware())))
2323
descr().get_right_walk_anims(does_carry_ware()),
2653
2684
draw_inner(game, dst, calc_drawpos(game, pos));
2688
==============================
2692
==============================
2695
#define WORKER_SAVEGAME_VERSION 2
2697
Worker::Loader::Loader()
2701
void Worker::Loader::load(FileRead& fr)
2703
Bob::Loader::load(fr);
2705
uint8_t version = fr.Unsigned8();
2706
if (!(1 <= version && version <= WORKER_SAVEGAME_VERSION))
2707
throw game_data_error("unknown/unhandled version %u", version);
2709
Worker& worker = get<Worker>();
2710
m_location = fr.Unsigned32();
2711
m_carried_item = fr.Unsigned32();
2712
worker.m_current_exp = fr.Signed32();
2715
if (fr.Unsigned8()) {
2716
worker.m_transfer = new Transfer(ref_cast<Game, Editor_Game_Base>(egbase()), worker);
2717
worker.m_transfer->read(fr, m_transfer);
2722
void Worker::Loader::load_pointers()
2724
Bob::Loader::load_pointers();
2726
Worker& worker = get<Worker>();
2729
worker.set_location(&mol().get<PlayerImmovable>(m_location));
2731
worker.m_carried_item = &mol().get<WareInstance>(m_carried_item);
2732
if (worker.m_transfer)
2733
worker.m_transfer->read_pointers(mol(), m_transfer);
2736
void Worker::Loader::load_finish()
2738
Bob::Loader::load_finish();
2740
// it's not entirely clear whether this is the best place to put this code,
2741
// keep an open mind once player immovables are also handled via the new save code
2742
Worker& worker = get<Worker>();
2743
Economy * economy = 0;
2744
if (PlayerImmovable * const location = worker.m_location.get(egbase()))
2745
economy = location->get_economy();
2746
worker.set_economy(economy);
2747
if (WareInstance * const carried_item = worker.m_carried_item.get(egbase()))
2748
carried_item->set_economy(economy);
2751
const Bob::Task* Worker::Loader::get_task(const std::string& name)
2753
if (name == "program") return &taskProgram;
2754
if (name == "transfer") return &taskTransfer;
2755
if (name == "buildingwork") return &taskBuildingwork;
2756
if (name == "return") return &taskReturn;
2757
if (name == "gowarehouse") return &taskGowarehouse;
2758
if (name == "dropoff") return &taskDropoff;
2759
if (name == "releaserecruit") return &taskReleaserecruit;
2760
if (name == "fetchfromflag") return &taskFetchfromflag;
2761
if (name == "waitforcapacity") return &taskWaitforcapacity;
2762
if (name == "leavebuilding") return &taskLeavebuilding;
2763
if (name == "fugitive") return &taskFugitive;
2764
if (name == "geologist") return &taskGeologist;
2765
if (name == "scout") return &taskScout;
2766
return Bob::Loader::get_task(name);
2769
const BobProgramBase* Worker::Loader::get_program(const std::string& name)
2771
Worker& worker = get<Worker>();
2772
return worker.descr().get_program(name);
2775
Worker::Loader* Worker::create_loader()
2781
* Load function for all classes derived from \ref Worker
2783
* Derived classes must override \ref create_loader to make sure
2784
* the appropriate actual load functions are called.
2786
Map_Object::Loader* Worker::load(Editor_Game_Base& egbase, Map_Map_Object_Loader& mol, FileRead& fr)
2789
// header has already been read by caller
2790
std::string tribename = fr.CString();
2791
std::string name = fr.CString();
2793
egbase.manually_load_tribe(tribename);
2795
const Tribe_Descr * tribe = egbase.get_tribe(tribename);
2797
throw game_data_error("unknown tribe '%s'", tribename.c_str());
2799
const Worker_Descr * descr = tribe->get_worker_descr(tribe->safe_worker_index(name));
2801
Worker * worker = static_cast<Worker*>(&descr->create_object());
2802
std::auto_ptr<Loader> loader(worker->create_loader());
2803
loader->init(egbase, mol, *worker);
2805
return loader.release();
2806
} catch (const std::exception & e) {
2807
throw wexception(_("loading worker: %s"), e.what());
2812
* Save the \ref Worker specific header and version info.
2814
* \warning Do not override this function, override \ref do_save instead.
2816
void Worker::save(Editor_Game_Base& egbase, Map_Map_Object_Saver& mos, FileWrite& fw)
2818
fw.Unsigned8(header_Worker);
2819
fw.CString(tribe().name());
2820
fw.CString(descr().name());
2822
do_save(egbase, mos, fw);
2826
* Save the data fields of this worker.
2828
* This is separate from \ref save because of the way data headers are treated.
2830
* Override this function in derived classes.
2832
void Worker::do_save(Editor_Game_Base& egbase, Map_Map_Object_Saver& mos, FileWrite& fw)
2834
Bob::save(egbase, mos, fw);
2836
fw.Unsigned8(WORKER_SAVEGAME_VERSION);
2837
fw.Unsigned32(mos.get_object_file_index_or_zero(m_location.get(egbase)));
2838
fw.Unsigned32(mos.get_object_file_index_or_zero(m_carried_item.get(egbase)));
2839
fw.Signed32(m_current_exp);
2843
m_transfer->write(mos, fw);