예제 #1
0
파일: Init.cpp 프로젝트: Stro21/TSP-GA
	void ReadTowns()
	{
		ntowns=0;
		char c;
		while(!isnum(c=getchar()))
		{
			while((c=getchar())!='\n');
		}
		ungetc(c, stdin);
		int id;
		float x, y;

		while(scanf("%d", &id)&&!feof(stdin))
		{
			scanf("%f%f", &x, &y);
			ntowns++;
			towns.push_back(Town(x, y));
		}
	}
예제 #2
0
파일: iomap_otmm.cpp 프로젝트: mattyx14/rme
bool IOMapOTMM::loadMap(Map& map, NodeFileReadHandle& f, const FileName& identifier, bool showdialog) {
	BinaryNode* root = f.getRootNode();
	if(!root) {
		error(wxT("Could not read root node."));
		return false;
	}
	root->skip(1); // Skip the type byte

	uint8_t u8;
	uint16_t u16;
	uint32_t u32;

	if(!root->getU32(u32) || u32 != 1) { // Version
		error(wxT("Unsupported or damaged map version."));
		return false;
	}

	if(!root->getU16(u16)) {
		error(wxT("Could not read root header."));
		return false;
	}
	map.width = u16;
	if(!root->getU16(u16)) {
		error(wxT("Could not read root header."));
		return false;
	}
	map.height = u16;

	if(!root->getU32(u32) || u32 > (unsigned long)item_db.MajorVersion) { // OTB major version
		if(queryUser(wxT("Map error"), wxT("The loaded map appears to be a items.otb format that deviates from the items.otb loaded by the editor. Do you still want to attempt to load the map?"))) {
			warning(wxT("Unsupported or damaged map version"));
		} else {
			error(wxT("Outdated items.otb, could not load map."));
			return false;
		}
	}

	if(!root->getU32(u32) || u32 > (unsigned long)item_db.MinorVersion) { // OTB minor version
		warning(wxT("The editor needs an updated items.otb version."));
	}

	BinaryNode* mapHeaderNode = root->getChild();
	if(mapHeaderNode == NULL || !mapHeaderNode->getByte(u8) || u8 != OTMM_MAP_DATA) {
		error(wxT("Could not get root child node. Cannot recover from fatal error!"));
		return false;
	}

	
	int nodes_loaded = 0;

	BinaryNode* mapNode = mapHeaderNode->getChild();
	if(mapNode) do {
		++nodes_loaded;
		if(showdialog && nodes_loaded % 15 == 0) {
			gui.SetLoadDone(int(100.0 * f.tell() / f.size()));
		}
		uint8_t node_type;
		if(!mapNode->getByte(node_type)) {
			warning(wxT("Invalid map node"));
			continue;
		}
		switch(node_type) {
			case OTMM_EDITOR: {
			} break;
			case OTMM_DESCRIPTION: {
				std::string desc;
				mapNode->getString(desc);
				map.setMapDescription(desc);
			} break;
			case OTMM_TILE_DATA: {
				BinaryNode* tileNode = mapNode->getChild();
				if(tileNode) do {
					Tile* tile = NULL;
					uint8_t tile_type;
					if(!tileNode->getByte(tile_type)) {
						warning(wxT("Invalid tile type"));
						continue;
					}
					if(tile_type != OTMM_TILE && tile_type != OTMM_HOUSETILE) {
						warning(wxT("Unknown type of tile node"));
						continue;
					}

					uint16_t x_offset, y_offset;
					uint8_t z_offset;
					if(!tileNode->getU16(x_offset) ||
							!tileNode->getU16(y_offset) ||
							!tileNode->getU8(z_offset)
						)
					{
						warning(wxT("Could not read position of tile"));
						continue;
					}
					const Position pos(x_offset, y_offset, z_offset);
					
					if(map.getTile(pos)) {
						warning(wxT("Duplicate tile at %d:%d:%d, discarding duplicate"), pos.x, pos.y, pos.z);
						continue;
					}
					
					tile = map.allocator(pos);
					House* house = NULL;
					if(tile_type == OTMM_HOUSETILE) {
						uint32_t house_id;
						if(!tileNode->getU32(house_id)) {
							warning(wxT("House tile without house data, discarding tile"));
							continue;
						}
						if(house_id) {
							house = map.houses.getHouse(house_id);
							if(!house) {
								house = newd House(map);
								house->id = house_id;
								map.houses.addHouse(house);
							}
						} else {
							warning(wxT("Invalid house id from tile %d:%d:%d"), pos.x, pos.y, pos.z);
						}
					}

					uint16_t ground_id;
					tileNode->getU16(ground_id);
					if(ground_id != 0) {
						tile->addItem(Item::Create(ground_id));
					}

					uint8_t attribute;
					while(tileNode->getU8(attribute)) {
						switch(attribute) {
							case OTMM_ATTR_TILE_FLAGS: {
								uint32_t flags = 0;
								if(!tileNode->getU32(flags)) {
									warning(wxT("Invalid tile flags of tile on %d:%d:%d"), pos.x, pos.y, pos.z);
								}
								tile->setMapFlags(flags);
							} break;
							default: {
								warning(wxT("Unknown tile attribute at %d:%d:%d"), pos.x, pos.y, pos.z);
							} break;
						}
					}
					
					BinaryNode* itemNode = tileNode->getChild();
					if(itemNode) do {
						Item* item = NULL;
						uint8_t item_type;
						if(!itemNode->getByte(item_type)) {
							warning(wxT("Unknown item type %d:%d:%d"), pos.x, pos.y, pos.z);
							continue;
						}
						if(item_type == OTMM_ITEM) {
							item = Item::Create_OTMM(*this, itemNode);
							if(item) {
								if(item->unserializeItemNode_OTMM(*this, itemNode) == false) {
									warning(wxT("Couldn't unserialize item attributes at %d:%d:%d"), pos.x, pos.y, pos.z);
								}
								tile->addItem(item);
							}
						} else {
							warning(wxT("Unknown type of tile child node"));
						}
					} while(itemNode->advance());

					tile->update();
					if(house) {
						house->addTile(tile);
					}
					map.setTile(pos, tile);
				} while(tileNode->advance());
			} break;
			case OTMM_SPAWN_DATA: {
				BinaryNode* spawnNode = mapNode->getChild();
				if(spawnNode) do {
					uint8_t spawn_type;
					if(!spawnNode->getByte(spawn_type)) {
						warning(wxT("Could not read spawn type."));
						continue;
					}
					if(spawn_type != OTMM_SPAWN_AREA) {
						warning(wxT("Invalid spawn type."));
						continue;
					}
					
					// Read position
					uint16_t spawn_x, spawn_y;
					uint8_t spawn_z;
					uint32_t radius;
					if(!spawnNode->getU16(spawn_x) ||
							!spawnNode->getU16(spawn_y) ||
							!spawnNode->getU8(spawn_z)
						)
					{
						warning(wxT("Could not read spawn position."));
						continue;
					}
					const Position spawnpos(spawn_x, spawn_y, spawn_z);
					
					// Read radius
					if(!spawnNode->getU32(radius)) {
						warning(wxT("Could not read spawn radius."));
						continue;
					}
					// Adjust radius
					radius = min(radius, uint32_t(settings.getInteger(Config::MAX_SPAWN_RADIUS)));

					// Create and assign spawn
					Tile* spawn_tile = map.getTile(spawnpos);
					if(spawn_tile && spawn_tile->spawn) {
						warning(wxT("Duplicate spawn on position %d:%d:%d\n"), spawn_tile->getX(), spawn_tile->getY(), spawn_tile->getZ());
						continue;
					}

					Spawn* spawn = newd Spawn(radius);
					if(!spawn_tile) {
						spawn_tile = map.allocator(spawnpos);
						map.setTile(spawnpos, spawn_tile);
					}
					spawn_tile->spawn = spawn;
					map.addSpawn(spawn_tile);

					// Read any creatures associated with the spawn
					BinaryNode* creatureNode = spawnNode->getChild();
					if(creatureNode) do {
						uint8_t creature_type;
						if(!creatureNode->getByte(creature_type)) {
							warning(wxT("Could not read type of creature node."));
							continue;
						}
						bool isNPC;
						std::string name;
						uint32_t spawntime = 0; // Only applicable for monsters

						if(creature_type == OTMM_NPC) {
							isNPC = true;
							if(!creatureNode->getString(name)) {
								warning(wxT("Could not read name of NPC."));
								return false;
							}
						} else if(creature_type == OTMM_MONSTER) {
							isNPC = false;
							if(!creatureNode->getString(name)) {
								warning(wxT("Could not read name of monster."));
								return false;
							}
							if(!creatureNode->getU32(spawntime)) {
								warning(wxT("Could not read spawn time of monster."));
								return false;
							}
						} else {
							warning(wxT("Unknown creature node type (0x%.2x)."), creature_type);
							return false;
						}

						// Read creature position
						uint16_t creature_x, creature_y;
						uint8_t creature_z;
						if(!creatureNode->getU16(creature_x) ||
								!creatureNode->getU16(creature_y) ||
								!creatureNode->getU8(creature_z)
							)
						{
							warning(wxT("Could not read creature position."));
							continue;
						}
						const Position creaturepos(creature_x, creature_y, creature_z);

						// Check radius
						if(uint32_t(abs(creaturepos.x - spawnpos.x)) > radius || uint32_t(abs(creaturepos.y - spawnpos.y)) > radius) {
							// Outside of the spawn...
						}

						// Create creature and put on map
						Tile* creature_tile;
						if(creaturepos == spawnpos) {
							creature_tile = spawn_tile;
						} else {
							creature_tile = map.getTile(creaturepos);
						}
						if(!creature_tile) {
							warning(wxT("Discarding creature \"%s\" at %d:%d:%d due to invalid position"), name.c_str(), creaturepos.x, creaturepos.y, creaturepos.z);
							break;
						}
						if(creature_tile->creature) {
							warning(wxT("Duplicate creature \"%s\" at %d:%d:%d, discarding"), name.c_str(), creaturepos.x, creaturepos.y, creaturepos.z);
							break;
						}
						CreatureType* type = creature_db[name];
						if(!type) {
							type = creature_db.addMissingCreatureType(name, isNPC);
						}
						Creature* creature = newd Creature(type);
						creature->setSpawnTime(spawntime);
						creature_tile->creature = creature;
						if(creature_tile->spawn_count == 0) {
							// No spawn, create a newd one (this happends if the radius of the spawn has been decreased due to settings)
							ASSERT(creature_tile->spawn == NULL);
							Spawn* spawn = newd Spawn(5);
							creature_tile->spawn = spawn;
							map.addSpawn(creature_tile);
						}
					} while(creatureNode->advance());
				} while(spawnNode->advance());
			} break;
			case OTMM_TOWN_DATA: {
				BinaryNode* townNode = mapNode->getChild();
				if(townNode) do {
					uint8_t town_type;
					if(!townNode->getByte(town_type)) {
						warning(wxT("Could not read town type"));
						continue;
					}
					if(town_type != OTMM_TOWN) {
						warning(wxT("Unknown town type"));
						continue;
					}
					uint32_t town_id;
					if(!townNode->getU32(town_id)) {
						warning(wxT("Invalid town id"));
						continue;
					}

					Town* town = map.towns.getTown(town_id);
					if(town) {
						warning(wxT("Duplicate town id %d, discarding duplicate"), town_id);
						continue;
					} else {
						town = newd Town(town_id);
						if(!map.towns.addTown(town)) {
							delete town;
							continue;
						}
					}
					std::string town_name;
					if(!townNode->getString(town_name)) {
						warning(wxT("Invalid town name"));
						continue;
					}
					town->setName(town_name);
					Position pos;
					uint16_t x;
					uint16_t y;
					uint8_t z;
					if(!townNode->getU16(x) ||
							!townNode->getU16(y) ||
							!townNode->getU8(z))
					{
						warning(wxT("Invalid town temple position"));
						continue;
					}
					pos.x = x;
					pos.y = y;
					pos.z = z;
					town->setTemplePosition(pos);
				} while(townNode->advance());
			} break;
			case OTMM_HOUSE_DATA: {
				BinaryNode* houseNode = mapNode->getChild();
				if(houseNode) do {
					uint8_t house_type;
					if(!houseNode->getByte(house_type)) {
						warning(wxT("Could not read house type"));
						continue;
					}
					if(house_type != OTMM_HOUSE) {
						warning(wxT("Unknown house type."));
						continue;
					}
					uint32_t house_id;
					if(!houseNode->getU32(house_id)) {
						warning(wxT("Could not read house id."));
						continue;
					}

					House* house = map.houses.getHouse(house_id);
					if(!house) {
						continue;
					}

					std::string house_name;
					if(!houseNode->getString(house_name)) {
						warning(wxT("Could not read house name."));
						continue;
					}
					
					uint32_t town_id;
					if(!houseNode->getU32(town_id)) {
						warning(wxT("Could not read house town id."));
						continue;
					}
					
					uint32_t rent;
					if(!houseNode->getU32(rent)) {
						warning(wxT("Could not read house rent."));
						continue;
					}

					house->name = house_name;
					house->townid = town_id;
					house->rent = rent;

					uint16_t x;
					uint16_t y;
					uint8_t z;
					if(!houseNode->getU16(x) ||
							!houseNode->getU16(y) ||
							!houseNode->getU8(z))
					{
						warning(wxT("Invalid town temple position"));
						continue;
					}
					house->setExit(Position(x, y, z));
				} while(houseNode->advance());
			} break;
		}
	} while(mapNode->advance());
	return true;
}
예제 #3
0
파일: Run.cpp 프로젝트: segrax/sgbb
bool _d2Run::Update(float Lag) {
	vector<item>::iterator inventoryIt;

	if(ticksDiff > 0.35f) {

		if( beltPotionsRejuve.size() < 8) {
			if( inventoryPotionsRejuve.size() > 0) {

				if( transferItem.Id == 0) {
					for(inventoryIt = inventoryPotionsRejuve.begin(); inventoryIt != inventoryPotionsRejuve.end(); inventoryIt++) {
						 
						if(inventoryIt->pickupAttempted == false) {
							transferItem = *inventoryIt;
							inventoryIt->Id = 0;
							
							Core->itemToBelt( transferItem );

							inventoryIt->pickupAttempted = true;

							ticksEnd = GetTickCount();
							return true;
						}

					}	// for
			
				 
				}	else	{ // transferItem.id == 0
					transferCount++;
					
					if(transferCount > 10) {
						transferItem.Id = 0;
						ticksEnd = GetTickCount();
						return true;
					}

						ticksEnd = GetTickCount();
						return true;
				 }

			 }	// inventoryPotions
		 }

	 }	// ticksDiff >0.2

	 if(waitTimer && ticksDiff > 0.10f) {
		waitTimer--;

		ticksEnd = GetTickCount();
		return true;
	 }

	// 0 is right hand
	if(skillTargetID[0] != 0 || skillTargetID[1] != 0) {

		// Check our skills
		// Right Hand
		if(skillCurrentID[0] != skillTargetID[0]) {

			if(skillCounter[0]++ == 0) {

				Core->SkillSelect( skillTargetID[0], false);
				ticksEnd = GetTickCount();

			} else {
				if(skillCounter[0] > 1000) {
					skillCounter[0] = 0;
					//Core->GameOver("Right Skill change failed!", true);
				}
				return true;
			}

			attackRecast = false;
			return true;
		}	// skillCurrentID[0]

		// Left Hand
		if(skillCurrentID[1] != skillTargetID[1]) {
			if(skillCounter[1]++ == 0) {

				Core->SkillSelect( skillTargetID[1], true);
				ticksEnd = GetTickCount();

			} else {
				if(skillCounter[1] > 1000) {
					skillCounter[1] = 0;
					//Core->GameOver("Left Skill change failed!", true);
				}
				return true;
			}
			
			attackRecast = false;
			return true;

		}	//skillCurrentID[1]

	}	// TargetIDs != 0

	if(ticksDiff > 0.20f && pickItems.size() > 0 && pickTime && pickingItem.Id == 0) {
		if(pickupTele && !teleporting)
			pickupTele = false;

		if(!teleporting && !pickupTele)
			if(itemsPickup()) {
				ticksEnd = GetTickCount();
				return true;
			}
	}

	if(groundItems.size() > 0 || pickingItem.Id) {
		item Item;

		if(pickupTele && !teleporting)
			pickupTele = false;

		if(ticksDiff > 0.20f && !teleporting && !pickupTele) {
			
			if(pickingItem.Id == 0) {

				for(size_t i = 0; i < groundItems.size(); i++) {

					// Need to clear this flag at the end of the monster waves
					if(groundItems[i].pickupAttempted)
						continue;


					strTmp.str("");
					strTmp << "Picking Up ";

					if( !Item.Id )
						if(groundItems[i].BaseItem == "rvl") {

							if(inventoryPotionsRejuve.size() < 5) {
								
								Item = groundItems[i];

								strTmp << "Rejuvination Potion";
								if(!Core->WithinRangePick( Item.Pos.xPos, Item.Pos.yPos ) ) {
									Item.Id = 0;
									teleSet( Item.Pos.xPos, Item.Pos.yPos, false );
									pickupTele = true;
									return true;
								}
							}

						}

					if( !Item.Id && beltPotionsHealth.size() < 4) 
						if(groundItems[i].BaseItem == "hp5") {
							Item = groundItems[i];
							strTmp << "Health Potion";
							if(!Core->WithinRangePick( Item.Pos.xPos, Item.Pos.yPos ) ) {
								Item.Id = 0;
								continue;
							}
						}


					if( !Item.Id && beltPotionsMana.size() < 4)
						if(groundItems[i].BaseItem == "mp5") {
							Item = groundItems[i];
							strTmp << "Mana Potion";
							if(!Core->WithinRangePick( Item.Pos.xPos, Item.Pos.yPos ) ) {
								Item.Id = 0;
								continue;
							}
						}

					if(Item.Id) {
						groundItems[i].pickupAttempted = true;

						pickedItem = false;
						pickingItem = Item;
						Core->pickItem( Item );
						Core->Debug(2, strTmp.str());

						ticksEnd = GetTickCount();
						return true;
					}
				}	// for

			} else {	// pickingItem != 0
				pickItemFailed++;
				ticksEnd = GetTickCount();

				if(pickItemFailed > 5) {
					//if(groundItems.size())
						//groundItemRemove(pickingItem.Id);

					pickingItem.Id = 0;
					return true;
				}


				return true;
			}

		}	// ticksDiff > 0.20
		
		if(pickingItem.Id != 0)
			return true;

	}	// groundItems.size

	if(ticksDiff > 0.24f || walkComplete || (teleportFirstStep && !cta)) {

		if(followBots) {
			map<DWORD, _d2Player>::iterator Player;

			if(followMode == 0) {
				
				//if(publicMode)
					playersMuteAll(false);

			}	// flowMode = 0

			//if(followMode == 1)
				//Core->SpeakToAll("1");

			if(followAllow)
				if(followMode == 2)
					Core->SpeakToAll("follow");

			if(followMode == 3)
				Core->SpeakToAll("precast");

			//if(followMode == 4)
			//	Core->SpeakToAll("!bo");

			// Check all bounds just incase
			if(followMode >= 4 || followMode < 0) {
				followMode = 0;
				followBots = false;
			}
			
			
			followMode++;
			ticksEnd = GetTickCount();
			return true;
		}	// followBots


		if(Running) {

			if(purchasing && purchaseComplete) {
				
				if(purchaseAmount--) {
					purchaseComplete = false;
					shoppingPurchasing = true;

					Core->TownPurchaseItem( unitMalah, purchaseItem, false );
					ticksEnd = GetTickCount();
					return true;

				} else {
					stepTown++;

					purchasing = false;
					shoppingPurchasing = false;

					ticksEnd = GetTickCount();
					return true;
				}

			} else if (purchasing && !purchaseComplete)	 {// purchasing
				
				return true;
			}

			if(!town && cta) {
				CTARun();
				ticksEnd = GetTickCount();
				return true;
			}	// !town && cta

			// CTAing before out of town
			if(town && cta) {
				if(currentStep == 0) {
					Core->GameOver("CTA in town!", false);
					return true;
				} else
					town = false;
			}

			if(portalCasting) {
				// Make it wait 3 seconds before rechucking
				if(!portalCast || ticksDiff > 4.0f) {
					portalCast = true;
					ThrowTP();
				}
				//ticksEnd = GetTickCount();
				return true;
			}	// portalCasting

		}	// Running


		if(interacting) {

			currentLevel = GetCurrentLevel();
			if(currentLevel)
				if(currentLevel->dwLevelNo == LevelTarget) {

					Sleep(100);
					if(cMap.GenerateMap() == false)
						return true;

					Core->AllowPlayerReassign();
					playerStop();					
					currentStep++;

					groundItems.clear();
					LevelTarget = 0;
					interacting = false;
					interactingCount = 0;

				} else
					interactingCount++;
			
				if(interactingCount > 5) {
					Core->Debug(0, "Interaction failed");
					interactingCount = 0;

					interacting = false;
				}

			free(currentLevel);
			ticksEnd = GetTickCount();
			return true;
		}	// Interacting


		if(Running && walking) {
			if(walkComplete) {
				
				walkComplete = false;

				if(walkStep == 0) {
					Core->playerMove( walkSteps[walkStep].X, walkSteps[walkStep].Y );
					ticksEnd = GetTickCount();
					return true;
				}

			} else {
				walkFailCounter++;

				if(walkFailCounter > 6) {
					walkFailCounter = 0;
					walkStep++;					

					if(walkSteps[walkStep].X == 0) {
						
						walkComplete = false;
						walkStep--;
						Hero->posX = walkSteps[walkStep].X;
						Hero->posY = walkSteps[walkStep].Y;

						playerStop();
						
						Core->playerMove(walkSteps[walkStep].X, walkSteps[walkStep].Y);
						walkCompleted(walkSteps[walkStep].X, walkSteps[walkStep].Y );

						ticksEnd = GetTickCount();
						return true;
					}


				}

				if(walkFailCounter == 0 || walkFailCounter == 5 || walkFailCounter == 10 || walkFailCounter == 15)
					Core->playerMove( walkSteps[walkStep].X, walkSteps[walkStep].Y );

				walkComplete = false;
				ticksEnd = GetTickCount();
			}
			
			return true;
		}	// Running/Walking
		
		if(teleporting || teleportMoving) {
			if(ticksDiff > 0.30f || teleportFirstStep) {

				teleportFirstStep = false;

				if(teleStep >= teleSteps) {
					teleportTimeout++;

					if(( teleSteps > 1 && teleportTimeout > 150) || (teleportTimeout > 250)) {
						Core->Debug(0, "Teleport Timeout");
						teleportTimeout = 0;
						teleStep = teleportCompleted + 1;
						teleFail++;

						if(telePath[ teleStep ].x == 0 || telePath[ teleStep ].y == 0) {
							teleStep--;
							if(teleStep < 0)
								teleStep = 0;
						}

						teleportMoving = true;

						if(teleFail > 3) {
							Core->Debug(0, "Teleport Failed");
							teleporting = false;
							teleportMoving = false;
							teleportCompleted = 0;

							teleFail = 0;
							if(teleAbort) {
								gameTeleTimeout++;
								Core->GameOver("Teleporting Failed!", true);
							}

							return true;
						}

						return true;
					} else
						return true;
				}	//telestep

				if(!teleportMoving) {
					teleportTimeout++;

					if(teleportTimeout > 300) {
						teleportTimeout = 0;
						//teleporting = false;
						teleportMoving = true;
						teleStep = teleportCompleted + 1;
					}

					return true;
				}

				if(telePath[ teleStep ].x == 0 || telePath[ teleStep ].y == 0) {
					//teleporting = false;
					teleportMoving = false;	// This basically means we are waiting for us to arrive at our destination
					//teleSteps = 0;
					teleFail++;
					if(teleFail >= 3) {
						Core->Debug(0, "Teleport Failed");
						teleporting = false;
						teleportMoving = false;
						teleportCompleted = 0;
						teleStep = 0;
						teleFail = 0;
					}
					return true;
				}

				Core->RightSkillFire( (WORD) telePath[ teleStep ].x, (WORD) telePath[ teleStep ].y );
				teleStep++;
				ticksEnd = GetTickCount();
				
			}	// ticksdiff
			
			
			return true;
		}	// teleporting

		if(ticksDiff > 0.30f) {
			if(town) {
				Running = true;
				Town();
				ticksEnd = GetTickCount();
				return true;
			}	// Town
		
		}	// ticksDiff (0.30)
	}

	float ticksDiffStart;
	ticksDiffStart =  ((float) (ticksStartup - ticksEnd)) / 1000;

	if(ticksDiffStart > 10.0f) {

		if(firstLoad) {
			
			EnableDebugPriv();

			if(!cMap.InitMemory("Diablo II", D2WindowTitle)) {
				//Quit = true;
				//Paused = true;	
				//Core->Debug(0, "Init memory Failed!");
				return true;
			} else {

				firstLoad = false;

				return true;
			}
		}

		currentLevel = GetCurrentLevel();
		if(currentLevel) {
			if(currentLevel->dwLevelNo == 109) {	// 109 = harrogath		
				town = true;		
			} else {
				if(town)
					firstTownLeave = true;

				town = false;
			}

			free(currentLevel);


			if(town && (currentStep > 0)) {
				if(realmCreateNewGame == true)
					return true;

				if(!manualMode)
					Core->GameOver("Found ourselves in town mid run!", true);
				
				Running = false;

				return true;
			}

		}
		
	} else // ticksdiffstart
		ticksEnd = GetTickCount();

	return false;
}