void buildatlas_creature(std::vector<Creature>& atlas) { // Fill the atlas // Creature(Name, Health, Armour Class, Attack Mod, Damage Mod, Str, End, Dex, Level, Type) atlas.push_back(Creature("Rat", 25, 13, 1, 1, 8, 8, 12, 1)); return; }
Creature* Creature::deepCopy() const { Creature* copy = newd Creature(type_name); copy->spawntime = spawntime; copy->direction = direction; copy->selected = selected; copy->saved = saved; return copy; }
void CreatureBrush::draw(BaseMap* map, Tile* tile, void* parameter) { ASSERT(tile); ASSERT(parameter); if(canDraw(map, tile->getPosition())) { undraw(map, tile); if(creature_type) { tile->creature = newd Creature(creature_type); tile->creature->setSpawnTime(*(int*)parameter); } } }
int main() { sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Main"); // Setup test creature Creature creature = Creature(); creature.position[0] = 100; creature.position[1] = 100; // creature.velocity[0] = 20; // creature.velocity[1] = 20; creature.setRotation(50); env.addObject(&creature); // Setup creatures for (int i = 0; i < NUM_CREATURES; ++i) { creatures[i] = Creature(); creatures[i].position[0] = 50 * (i + 1); creatures[i].position[1] = 50 * (i + 1); creatures[i].setRotation(0); env.addObject(&creatures[i]); } // Setup food for (int i = 0; i < NUM_FOOD; ++i) { Food f = Food(); f.reset(WIDTH, HEIGHT); food.push_back(f); } sf::Clock frame_clock; sf::Clock gen_clock; int frame_count = 0; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::Closed: window.close(); break; case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::W) { creature.moveForward(); } else if (event.key.code == sf::Keyboard::S) { printf("%s\n", "S PRESSED"); } else if (event.key.code == sf::Keyboard::A) { creature.setRotation(creature.getRotation() + 5); } else if (event.key.code == sf::Keyboard::D) { creature.setRotation(creature.getRotation() - 5); } else if (event.key.code == sf::Keyboard::P) { launchConsole(); frame_clock.restart(); } break; case sf::Event::MouseButtonPressed: if (event.mouseButton.button == sf::Mouse::Right) { sf::Vector2f position = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)); } break; default: break; } } window.clear(); for (int i = 0; i < NUM_FOOD; ++i) { if (!food[i].isConsumed()) window.draw(food[i]); } // Debug creature creature.draw(&window); for (int i = 0; i < NUM_FOOD; ++i) { if (creature.isPointInFOV(food[i].getPosition())) { // printf("%f\n", creature.distanceToPoint(food[i].getPosition())); } } for (int i = 0; i < NUM_CREATURES; ++i) { creatures[i].process(&food); creatures[i].draw(&window); } // Handle generations if (gen_clock.getElapsedTime().asSeconds() > GENERATION_LENGTH_SECONDS) { std::cout << "Generation: " << ++gen_count << std::endl; writeOutData(); // Reset food for (int i = 0; i < NUM_FOOD; ++i) { food[i].reset(WIDTH, HEIGHT); } // Sort by energy level std::sort(creatures, creatures + NUM_CREATURES, compareCreatures); // Select and mutate the top 50% of creatures Mutator mutator = Mutator(); for (int i = 0; i < NUM_CREATURES/2; ++i) { printf("Creature %d %f\n", i, creatures[i].getEnergy()); mutator.setTarget(&creatures[i]); creatures[i].resetEnergy(); creatures[i].position[0] = WIDTH / 2; creatures[i].position[1] = HEIGHT / 2; mutator.mutate(&creatures[NUM_CREATURES - 1 - i]); creatures[NUM_CREATURES - 1 - i].resetEnergy(); creatures[NUM_CREATURES - 1 - i].position[0] = WIDTH / 2; creatures[NUM_CREATURES - 1 - i].position[1] = HEIGHT / 2; } gen_clock.restart(); } window.display(); sf::Time elapsed = frame_clock.restart(); env.step(elapsed.asSeconds()); } return 0; }
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; }