MovableProducer::MovableProducer(DataManager &dm, const gamedata::unit_movable *um) : ObjectProducer(dm, um), unit_data(*um), on_move{dm.get_sound(this->unit_data.move_sound)}, on_attack{dm.get_sound(this->unit_data.move_sound)}, projectile{dm.get_type(this->unit_data.projectile_unit_id)} { // extra graphics if available // villagers have invalid attack and walk graphics // it seems these come from the command data instead auto walk = dm.get_unit_texture(this->unit_data.walking_graphics0); if (!walk) { // use standing instead walk = this->graphics[graphic_type::standing]; } this->graphics[graphic_type::walking] = walk; // reuse as carry graphic if not already set if (this->graphics.count(graphic_type::carrying) == 0) { this->graphics[graphic_type::carrying] = walk; } auto attack = dm.get_unit_texture(this->unit_data.attack_graphic); if (attack && attack->is_valid()) { this->graphics[graphic_type::attack] = attack; } // extra abilities this->type_abilities.emplace_back(std::make_shared<MoveAbility>(this->on_move)); this->type_abilities.emplace_back(std::make_shared<AttackAbility>(this->on_attack)); }
ProjectileProducer::ProjectileProducer(DataManager &dm, const gamedata::unit_projectile *pd) : unit_data{*pd}, tex{dm.get_unit_texture(this->unit_data.graphic_standing0)}, sh{dm.get_unit_texture(3379)}, // 3379 = general arrow shadow destroyed{dm.get_unit_texture(this->unit_data.graphic_dying0)} { // graphic set this->graphics[graphic_type::standing] = this->tex; this->graphics[graphic_type::shadow] = this->sh; if (destroyed) { this->graphics[graphic_type::dying] = destroyed; } // outline terrain_outline = radial_outline(pd->radius_size1); }
BuildingProducer::BuildingProducer(DataManager &dm, const gamedata::unit_building *ud) : datamanager(dm), unit_data{*ud}, texture{dm.get_unit_texture(ud->graphic_standing0)}, destroyed{dm.get_unit_texture(ud->graphic_dying0)}, trainable1{dm.get_type(83)}, // 83 = m villager trainable2{dm.get_type(293)}, // 293 = f villager projectile{dm.get_type(this->unit_data.projectile_unit_id)}, foundation_terrain{ud->terrain_id}, enable_collisions{this->unit_data.id0 != 109} { // 109 = town center // find suitable sounds int creation_sound = this->unit_data.sound_creation0; int dying_sound = this->unit_data.sound_dying; if (creation_sound == -1) { creation_sound = this->unit_data.sound_creation1; } if (creation_sound == -1) { creation_sound = this->unit_data.sound_selection; } if (dying_sound == -1) { dying_sound = 323; //generic explosion sound } on_create = dm.get_sound(creation_sound); on_destroy = dm.get_sound(dying_sound); // convert the float to the discrete foundation size... this->foundation_size = { static_cast<int>(this->unit_data.radius_size0 * 2), static_cast<int>(this->unit_data.radius_size1 * 2), }; // graphic set this->graphics[graphic_type::construct] = dm.get_unit_texture(ud->construction_graphic_id); this->graphics[graphic_type::standing] = dm.get_unit_texture(ud->graphic_standing0); this->graphics[graphic_type::attack] = dm.get_unit_texture(ud->graphic_standing0); auto dying_tex = dm.get_unit_texture(ud->graphic_dying0); if (dying_tex) { this->graphics[graphic_type::dying] = dying_tex; } this->terrain_outline = square_outline(this->foundation_size); }
ObjectProducer::ObjectProducer(DataManager &dm, const gamedata::unit_object *ud) : datamanager(dm), unit_data(*ud), terrain_outline{nullptr}, default_tex{dm.get_unit_texture(ud->graphic_standing0)}, dead_unit_producer{dm.get_type(ud->dead_unit_id)} { // for now just look for type names ending with "_D" this->decay = unit_data.name.substr(unit_data.name.length() - 2) == "_D"; // find suitable sounds int creation_sound = this->unit_data.sound_creation0; int dying_sound = this->unit_data.sound_dying; if (creation_sound == -1) { creation_sound = this->unit_data.sound_creation1; } if (creation_sound == -1) { creation_sound = this->unit_data.sound_selection; } if (dying_sound == -1) { dying_sound = 323; //generic explosion sound } on_create = dm.get_sound(creation_sound); on_destroy = dm.get_sound(dying_sound); // convert the float to the discrete foundation size... this->foundation_size = { static_cast<int>(this->unit_data.radius_size0 * 2), static_cast<int>(this->unit_data.radius_size1 * 2), }; // shape of the outline if (this->unit_data.selection_shape > 1) { this->terrain_outline = radial_outline(this->unit_data.radius_size0); } else { this->terrain_outline = square_outline(this->foundation_size); } // graphic set auto standing = dm.get_unit_texture(this->unit_data.graphic_standing0); if (!standing) { // indicates problems with data converion throw util::Error(MSG(err) << "Unit id " << this->unit_data.id0 << " has invalid graphic data, try reconverting the data"); } this->graphics[graphic_type::standing] = standing; auto dying_tex = dm.get_unit_texture(this->unit_data.graphic_dying0); if (dying_tex) { this->graphics[graphic_type::dying] = dying_tex; } // default extra graphics this->graphics[graphic_type::attack] = this->graphics[graphic_type::standing]; this->graphics[graphic_type::work] = this->graphics[graphic_type::standing]; // pull extra graphics from unit commands auto cmds = dm.get_command_data(this->unit_data.id0); for (auto cmd : cmds) { // same attack / work graphic if (cmd->action_graphic_id == -1 && cmd->proceed_graphic_id > 0) { auto task = dm.get_unit_texture(cmd->proceed_graphic_id); if (task) { this->graphics[graphic_type::work] = task; this->graphics[graphic_type::attack] = task; } } // seperate work and attack graphics if (cmd->action_graphic_id > 0 && cmd->proceed_graphic_id > 0 ) { auto attack = dm.get_unit_texture(cmd->proceed_graphic_id); auto work = dm.get_unit_texture(cmd->action_graphic_id); if (attack) { this->graphics[graphic_type::attack] = attack; } if (work) { this->graphics[graphic_type::work] = work; } } // villager carrying resources graphics if (cmd->carrying_graphic_id > 0) { auto carry = dm.get_unit_texture(cmd->carrying_graphic_id); this->graphics[graphic_type::carrying] = carry; if (carry) { } } } }