{"action":"created","comment":{"url":"https://api.github.com/repos/SFTtech/openage/pulls/comments/35419115","id":35419115,"diff_hunk":"@@ -0,0 +1,253 @@\n+// Copyright 2015-2015 the openage authors. See copying.md for legal info.\n+\n+#include <epoxy/gl.h>\n+#include <SDL2/SDL.h>\n+#include <sys/stat.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+\n+#include \"console/console.h\"\n+#include \"coord/vec2f.h\"\n+#include \"engine.h\"\n+#include \"game_main.h\"\n+#include \"game_spec.h\"\n+#include \"input/input_manager.h\"\n+#include \"log/log.h\"\n+#include \"terrain/terrain.h\"\n+#include \"unit/action.h\"\n+#include \"unit/command.h\"\n+#include \"unit/producer.h\"\n+#include \"unit/unit.h\"\n+#include \"unit/unit_texture.h\"\n+#include \"util/timer.h\"\n+#include \"util/externalprofiler.h\"\n+\n+#include \"game_renderer.h\"\n+\n+namespace openage {\n+\n+render_settings::render_settings()\n+\t:\n+\tdraw_grid{false},\n+\tdraw_debug{false},\n+\tterrain_blending{true} {\n+}\n+\n+GameRenderer::GameRenderer(openage::Engine *e)\n+\t:\n+\tOptionNode{\"Renderer\"},\n+\tengine{e} {\n+\n+\t// set options structure\n+\tthis->set_parent(this->engine);\n+\n+\t// engine callbacks\n+\tthis->engine->register_draw_action(this);\n+\n+\tthis->add_bool(\"draw_grid\", &settings.draw_grid);\n+\tthis->add_bool(\"draw_debug\", &settings.draw_debug);\n+\tthis->add_bool(\"terrain_blending\", &settings.terrain_blending);\n+\tutil::Dir *data_dir = engine->get_data_dir();\n+\tutil::Dir asset_dir = data_dir->append(\"converted\");\n+\n+\t// load textures and stuff\n+\tgaben = new Texture{data_dir->join(\"gaben.png\")};\n+\n+\tstd::vector<gamedata::palette_color> player_color_lines;\n+\tutil::read_csv_file(asset_dir.join(\"player_palette_50500.docx\"), player_color_lines);\n+\n+\tGLfloat *playercolors = new GLfloat[player_color_lines.size() * 4];\n+\tfor (size_t i = 0; i < player_color_lines.size(); i++) {\n+\t\tauto line = &player_color_lines[i];\n+\t\tplayercolors[i*4]     = line->r / 255.0;\n+\t\tplayercolors[i*4 + 1] = line->g / 255.0;\n+\t\tplayercolors[i*4 + 2] = line->b / 255.0;\n+\t\tplayercolors[i*4 + 3] = line->a / 255.0;\n+\t}\n+\n+\t// shader initialisation\n+\t// read shader source codes and create shader objects for wrapping them.\n+\n+\tchar *texture_vert_code;\n+\tutil::read_whole_file(&texture_vert_code, data_dir->join(\"shaders/maptexture.vert.glsl\"));\n+\tauto plaintexture_vert = new shader::Shader(GL_VERTEX_SHADER, texture_vert_code);\n+\tdelete[] texture_vert_code;\n+\n+\tchar *texture_frag_code;\n+\tutil::read_whole_file(&texture_frag_code, data_dir->join(\"shaders/maptexture.frag.glsl\"));\n+\tauto plaintexture_frag = new shader::Shader(GL_FRAGMENT_SHADER, texture_frag_code);\n+\tdelete[] texture_frag_code;\n+\n+\tchar *teamcolor_frag_code;\n+\tutil::read_whole_file(&teamcolor_frag_code, data_dir->join(\"shaders/teamcolors.frag.glsl\"));\n+\tauto teamcolor_frag = new shader::Shader(GL_FRAGMENT_SHADER, teamcolor_frag_code);\n+\tdelete[] teamcolor_frag_code;\n+\n+\tchar *alphamask_vert_code;\n+\tutil::read_whole_file(&alphamask_vert_code, data_dir->join(\"shaders/alphamask.vert.glsl\"));\n+\tauto alphamask_vert = new shader::Shader(GL_VERTEX_SHADER, alphamask_vert_code);\n+\tdelete[] alphamask_vert_code;\n+\n+\tchar *alphamask_frag_code;\n+\tutil::read_whole_file(&alphamask_frag_code, data_dir->join(\"shaders/alphamask.frag.glsl\"));\n+\tauto alphamask_frag = new shader::Shader(GL_FRAGMENT_SHADER, alphamask_frag_code);\n+\tdelete[] alphamask_frag_code;\n+\n+\n+\n+\t// create program for rendering simple textures\n+\ttexture_shader::program = new shader::Program(plaintexture_vert, plaintexture_frag);\n+\ttexture_shader::program->link();\n+\ttexture_shader::texture = texture_shader::program->get_uniform_id(\"texture\");\n+\ttexture_shader::tex_coord = texture_shader::program->get_attribute_id(\"tex_coordinates\");\n+\ttexture_shader::program->use();\n+\tglUniform1i(texture_shader::texture, 0);\n+\ttexture_shader::program->stopusing();\n+\n+\n+\t// create program for tinting textures at alpha-marked pixels\n+\t// with team colors\n+\tteamcolor_shader::program = new shader::Program(plaintexture_vert, teamcolor_frag);\n+\tteamcolor_shader::program->link();\n+\tteamcolor_shader::texture = teamcolor_shader::program->get_uniform_id(\"texture\");\n+\tteamcolor_shader::tex_coord = teamcolor_shader::program->get_attribute_id(\"tex_coordinates\");\n+\tteamcolor_shader::player_id_var = teamcolor_shader::program->get_uniform_id(\"player_number\");\n+\tteamcolor_shader::alpha_marker_var = teamcolor_shader::program->get_uniform_id(\"alpha_marker\");\n+\tteamcolor_shader::player_color_var = teamcolor_shader::program->get_uniform_id(\"player_color\");\n+\tteamcolor_shader::program->use();\n+\tglUniform1i(teamcolor_shader::texture, 0);\n+\tglUniform1f(teamcolor_shader::alpha_marker_var, 254.0/255.0);\n+\t// fill the teamcolor shader's player color table:\n+\tglUniform4fv(teamcolor_shader::player_color_var, 64, playercolors);\n+\tteamcolor_shader::program->stopusing();\n+\tdelete[] playercolors;\n+\n+\n+\t// create program for drawing textures that are alpha-masked before\n+\talphamask_shader::program = new shader::Program(alphamask_vert, alphamask_frag);\n+\talphamask_shader::program->link();\n+\talphamask_shader::base_coord = alphamask_shader::program->get_attribute_id(\"base_tex_coordinates\");\n+\talphamask_shader::mask_coord = alphamask_shader::program->get_attribute_id(\"mask_tex_coordinates\");\n+\talphamask_shader::show_mask = alphamask_shader::program->get_uniform_id(\"show_mask\");\n+\talphamask_shader::base_texture = alphamask_shader::program->get_uniform_id(\"base_texture\");\n+\talphamask_shader::mask_texture = alphamask_shader::program->get_uniform_id(\"mask_texture\");\n+\talphamask_shader::program->use();\n+\tglUniform1i(alphamask_shader::base_texture, 0);\n+\tglUniform1i(alphamask_shader::mask_texture, 1);\n+\talphamask_shader::program->stopusing();\n+\n+\t// after linking, the shaders are no longer necessary\n+\tdelete plaintexture_vert;\n+\tdelete plaintexture_frag;\n+\tdelete teamcolor_frag;\n+\tdelete alphamask_vert;\n+\tdelete alphamask_frag;\n+\n+\t// Renderer keybinds\n+\t// TODO: a renderer settings struct\n+\t// would allow these to be put somewher better\n+\tauto &global_input_context = engine->get_input_manager().get_global_context();\n+\tglobal_input_context.bind(input::action_t::TOGGLE_BLENDING, [this](const input::action_arg_t &) {\n+\t\tthis->settings.terrain_blending = !this->settings.terrain_blending;\n+\t});\n+\tglobal_input_context.bind(input::action_t::TOGGLE_UNIT_DEBUG, [this](const input::action_arg_t &) {\n+\t\tthis->settings.draw_debug = !this->settings.draw_debug;\n+\n+\t\t// TODO remove this hack\n+\t\tUnitAction::show_debug = !UnitAction::show_debug;\n+\t});\n+\n+\tlog::log(MSG(dbg) << \"Loaded Renderer\");\n+}\n+\n+GameRenderer::~GameRenderer() {\n+\t// oh noes, release hl3 before that!\n+\tdelete this->gaben;\n+\n+\tdelete texture_shader::program;\n+\tdelete teamcolor_shader::program;\n+\tdelete alphamask_shader::program;\n+}\n+\n+bool GameRenderer::on_draw() {\n+\tEngine &engine = Engine::get();\n+\n+\t// draw terrain\n+\tGameMain *game = engine.get_game();\n+\tif (game) {\n+\n+\t\t// draw gaben, our great and holy protector, bringer of the half-life 3.\n+\t\tgaben->draw(coord::camgame{0, 0});\n+\n+\t\t// TODO move render code out of terrain\n+\t\tif (game->terrain) {\n+\t\t\tgame->terrain->draw(&engine, &this->settings);\n+\t\t}\n+\n+\t\tif (this->settings.draw_grid) {\n+\t\t\tthis->draw_debug_grid();\n+\t\t}\n+\t}\n+\treturn true;\n+}\n+\n+void GameRenderer::draw_debug_grid() {\n+\tEngine &e = Engine::get();\n+\n+\tcoord::camgame camera = coord::tile{0, 0}.to_tile3().to_phys3().to_camgame();\n+\n+\tint cam_offset_x = util::mod(camera.x, e.engine_coord_data->tile_halfsize.x * 2);\n+\tint cam_offset_y = util::mod(camera.y, e.engine_coord_data->tile_halfsize.y * 2);\n+\n+\tint line_half_width = e.engine_coord_data->window_size.x / 2;\n+\tint line_half_height = e.engine_coord_data->window_size.y / 2;\n+\n+\t// rounding so we get 2:1 proportion needed for the isometric perspective\n+\n+\tif (line_half_width > line_half_height * 2) {\n+\n+\t\tif (line_half_width & 1) {\n+\t\t\tline_half_width += 1; // round up if it's odd\n+\t\t}\n+\n+\t\tline_half_height = line_half_width / 2;\n+\n+\t} else {\n+\t\tline_half_width = line_half_height * 2;\n+\t}\n+\n+\t// quantity of lines to draw to each side from the center\n+\tint k = line_half_width / (e.engine_coord_data->tile_halfsize.x);\n+\n+\tint tilesize_x = e.engine_coord_data->tile_halfsize.x * 2;\n+\tint common_x   = cam_offset_x + e.engine_coord_data->tile_halfsize.x;\n+\tint x0         = common_x     - line_half_width;\n+\tint x1         = common_x     + line_half_width;\n+\tint y0         = cam_offset_y - line_half_height;\n+\tint y1         = cam_offset_y + line_half_height;\n+\n+\tglLineWidth(1);\n+\tglColor3f(0.0, 0.0, 0.0);\n+\tglBegin(GL_LINES); {\n+\n+\t\tfor (int i = -k; i < k; i++) {\n+\t\t\t\tglVertex3f(i * tilesize_x + x0, y1, 0);\n+\t\t\t\tglVertex3f(i * tilesize_x + x1, y0, 0);\n+\n+\t\t\t\tglVertex3f(i * tilesize_x + x0, y0 - 1, 0);\n+\t\t\t\tglVertex3f(i * tilesize_x + x1, y1 - 1, 0);\n+\t\t}","path":"cpp/game_renderer.cpp","position":239,"original_position":239,"commit_id":"06675b0463d287c49eade77659d3578691ecbd51","original_commit_id":"06675b0463d287c49eade77659d3578691ecbd51","user":{"login":"mic-e","id":796624,"avatar_url":"https://avatars.githubusercontent.com/u/796624?v=3","gravatar_id":"","url":"https://api.github.com/users/mic-e","html_url":"https://github.com/mic-e","followers_url":"https://api.github.com/users/mic-e/followers","following_url":"https://api.github.com/users/mic-e/following{/other_user}","gists_url":"https://api.github.com/users/mic-e/gists{/gist_id}","starred_url":"https://api.github.com/users/mic-e/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mic-e/subscriptions","organizations_url":"https://api.github.com/users/mic-e/orgs","repos_url":"https://api.github.com/users/mic-e/repos","events_url":"https://api.github.com/users/mic-e/events{/privacy}","received_events_url":"https://api.github.com/users/mic-e/received_events","type":"User","site_admin":false},"body":"/me is utterly horrified","created_at":"2015-07-24T12:55:19Z","updated_at":"2015-07-24T12:55:19Z","html_url":"https://github.com/SFTtech/openage/pull/321#discussion_r35419115","pull_request_url":"https://api.github.com/repos/SFTtech/openage/pulls/321","_links":{"self":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/comments/35419115"},"html":{"href":"https://github.com/SFTtech/openage/pull/321#discussion_r35419115"},"pull_request":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/321"}}},"pull_request":{"url":"https://api.github.com/repos/SFTtech/openage/pulls/321","id":38705514,"html_url":"https://github.com/SFTtech/openage/pull/321","diff_url":"https://github.com/SFTtech/openage/pull/321.diff","patch_url":"https://github.com/SFTtech/openage/pull/321.patch","issue_url":"https://api.github.com/repos/SFTtech/openage/issues/321","number":321,"state":"open","locked":false,"title":"Gamemain refactoring","user":{"login":"Jon0","id":3847361,"avatar_url":"https://avatars.githubusercontent.com/u/3847361?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon0","html_url":"https://github.com/Jon0","followers_url":"https://api.github.com/users/Jon0/followers","following_url":"https://api.github.com/users/Jon0/following{/other_user}","gists_url":"https://api.github.com/users/Jon0/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon0/subscriptions","organizations_url":"https://api.github.com/users/Jon0/orgs","repos_url":"https://api.github.com/users/Jon0/repos","events_url":"https://api.github.com/users/Jon0/events{/privacy}","received_events_url":"https://api.github.com/users/Jon0/received_events","type":"User","site_admin":false},"body":"Gamemain split across several classes\r\nSeperating existing map rendering code into GameRenderer\r\nThe input handling and ui rendering now done in GameControl\r\n\r\nDataManager renamed to GameSpec. this is supposed to be a class covering the available tile sets and unit types available (which may change with game data mods)\r\n\r\nThe file loading for Terrain now done by the GameSpec so it only needs loading once, Terrain objects now constructed just using meta data, which means constructing a new Terrain is easier. In future this makes exiting one game returning to the main menu and then creating another possible.\r\n\r\nThe GameControl splits the existing input code into EditorMode and ActionMode, to be handled seperatly, and a new mode CreateMode for constructing a game will eventually have gui elements to select settings for creating a new game.\r\n\r\nI am considering refactoring the KeybindManager to handle mouse actions as well, maybe renamed to InputManager -- this could avoid a bunch of duplicate mouse handling code\r\n\r\nThis pr slightly overlaps the existing gui and renderer pull requests but should be easy to intergrate with them","created_at":"2015-06-27T07:16:06Z","updated_at":"2015-07-24T12:55:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b643df7931dfa781759ca7569d65e70677aa0f08","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/SFTtech/openage/pulls/321/commits","review_comments_url":"https://api.github.com/repos/SFTtech/openage/pulls/321/comments","review_comment_url":"https://api.github.com/repos/SFTtech/openage/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SFTtech/openage/issues/321/comments","statuses_url":"https://api.github.com/repos/SFTtech/openage/statuses/06675b0463d287c49eade77659d3578691ecbd51","head":{"label":"Jon0:gamemain","ref":"gamemain","sha":"06675b0463d287c49eade77659d3578691ecbd51","user":{"login":"Jon0","id":3847361,"avatar_url":"https://avatars.githubusercontent.com/u/3847361?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon0","html_url":"https://github.com/Jon0","followers_url":"https://api.github.com/users/Jon0/followers","following_url":"https://api.github.com/users/Jon0/following{/other_user}","gists_url":"https://api.github.com/users/Jon0/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon0/subscriptions","organizations_url":"https://api.github.com/users/Jon0/orgs","repos_url":"https://api.github.com/users/Jon0/repos","events_url":"https://api.github.com/users/Jon0/events{/privacy}","received_events_url":"https://api.github.com/users/Jon0/received_events","type":"User","site_admin":false},"repo":{"id":25803186,"name":"openage","full_name":"Jon0/openage","owner":{"login":"Jon0","id":3847361,"avatar_url":"https://avatars.githubusercontent.com/u/3847361?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon0","html_url":"https://github.com/Jon0","followers_url":"https://api.github.com/users/Jon0/followers","following_url":"https://api.github.com/users/Jon0/following{/other_user}","gists_url":"https://api.github.com/users/Jon0/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon0/subscriptions","organizations_url":"https://api.github.com/users/Jon0/orgs","repos_url":"https://api.github.com/users/Jon0/repos","events_url":"https://api.github.com/users/Jon0/events{/privacy}","received_events_url":"https://api.github.com/users/Jon0/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Jon0/openage","description":"Free (as in freedom) open source clone of the Age of Empires II engine.","fork":true,"url":"https://api.github.com/repos/Jon0/openage","forks_url":"https://api.github.com/repos/Jon0/openage/forks","keys_url":"https://api.github.com/repos/Jon0/openage/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Jon0/openage/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Jon0/openage/teams","hooks_url":"https://api.github.com/repos/Jon0/openage/hooks","issue_events_url":"https://api.github.com/repos/Jon0/openage/issues/events{/number}","events_url":"https://api.github.com/repos/Jon0/openage/events","assignees_url":"https://api.github.com/repos/Jon0/openage/assignees{/user}","branches_url":"https://api.github.com/repos/Jon0/openage/branches{/branch}","tags_url":"https://api.github.com/repos/Jon0/openage/tags","blobs_url":"https://api.github.com/repos/Jon0/openage/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Jon0/openage/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Jon0/openage/git/refs{/sha}","trees_url":"https://api.github.com/repos/Jon0/openage/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Jon0/openage/statuses/{sha}","languages_url":"https://api.github.com/repos/Jon0/openage/languages","stargazers_url":"https://api.github.com/repos/Jon0/openage/stargazers","contributors_url":"https://api.github.com/repos/Jon0/openage/contributors","subscribers_url":"https://api.github.com/repos/Jon0/openage/subscribers","subscription_url":"https://api.github.com/repos/Jon0/openage/subscription","commits_url":"https://api.github.com/repos/Jon0/openage/commits{/sha}","git_commits_url":"https://api.github.com/repos/Jon0/openage/git/commits{/sha}","comments_url":"https://api.github.com/repos/Jon0/openage/comments{/number}","issue_comment_url":"https://api.github.com/repos/Jon0/openage/issues/comments{/number}","contents_url":"https://api.github.com/repos/Jon0/openage/contents/{+path}","compare_url":"https://api.github.com/repos/Jon0/openage/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Jon0/openage/merges","archive_url":"https://api.github.com/repos/Jon0/openage/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Jon0/openage/downloads","issues_url":"https://api.github.com/repos/Jon0/openage/issues{/number}","pulls_url":"https://api.github.com/repos/Jon0/openage/pulls{/number}","milestones_url":"https://api.github.com/repos/Jon0/openage/milestones{/number}","notifications_url":"https://api.github.com/repos/Jon0/openage/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Jon0/openage/labels{/name}","releases_url":"https://api.github.com/repos/Jon0/openage/releases{/id}","created_at":"2014-10-27T04:28:20Z","updated_at":"2015-05-07T03:07:40Z","pushed_at":"2015-07-22T09:18:09Z","git_url":"git://github.com/Jon0/openage.git","ssh_url":"git@github.com:Jon0/openage.git","clone_url":"https://github.com/Jon0/openage.git","svn_url":"https://github.com/Jon0/openage","homepage":"http://openage.sft.mx","size":5558,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"SFTtech:master","ref":"master","sha":"30c973baf3f3ae8fdc4b8b91584903e7c639e07b","user":{"login":"SFTtech","id":1783325,"avatar_url":"https://avatars.githubusercontent.com/u/1783325?v=3","gravatar_id":"","url":"https://api.github.com/users/SFTtech","html_url":"https://github.com/SFTtech","followers_url":"https://api.github.com/users/SFTtech/followers","following_url":"https://api.github.com/users/SFTtech/following{/other_user}","gists_url":"https://api.github.com/users/SFTtech/gists{/gist_id}","starred_url":"https://api.github.com/users/SFTtech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SFTtech/subscriptions","organizations_url":"https://api.github.com/users/SFTtech/orgs","repos_url":"https://api.github.com/users/SFTtech/repos","events_url":"https://api.github.com/users/SFTtech/events{/privacy}","received_events_url":"https://api.github.com/users/SFTtech/received_events","type":"Organization","site_admin":false},"repo":{"id":14095175,"name":"openage","full_name":"SFTtech/openage","owner":{"login":"SFTtech","id":1783325,"avatar_url":"https://avatars.githubusercontent.com/u/1783325?v=3","gravatar_id":"","url":"https://api.github.com/users/SFTtech","html_url":"https://github.com/SFTtech","followers_url":"https://api.github.com/users/SFTtech/followers","following_url":"https://api.github.com/users/SFTtech/following{/other_user}","gists_url":"https://api.github.com/users/SFTtech/gists{/gist_id}","starred_url":"https://api.github.com/users/SFTtech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SFTtech/subscriptions","organizations_url":"https://api.github.com/users/SFTtech/orgs","repos_url":"https://api.github.com/users/SFTtech/repos","events_url":"https://api.github.com/users/SFTtech/events{/privacy}","received_events_url":"https://api.github.com/users/SFTtech/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SFTtech/openage","description":"Free (as in freedom) open source clone of the Age of Empires II engine.","fork":false,"url":"https://api.github.com/repos/SFTtech/openage","forks_url":"https://api.github.com/repos/SFTtech/openage/forks","keys_url":"https://api.github.com/repos/SFTtech/openage/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SFTtech/openage/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SFTtech/openage/teams","hooks_url":"https://api.github.com/repos/SFTtech/openage/hooks","issue_events_url":"https://api.github.com/repos/SFTtech/openage/issues/events{/number}","events_url":"https://api.github.com/repos/SFTtech/openage/events","assignees_url":"https://api.github.com/repos/SFTtech/openage/assignees{/user}","branches_url":"https://api.github.com/repos/SFTtech/openage/branches{/branch}","tags_url":"https://api.github.com/repos/SFTtech/openage/tags","blobs_url":"https://api.github.com/repos/SFTtech/openage/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SFTtech/openage/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SFTtech/openage/git/refs{/sha}","trees_url":"https://api.github.com/repos/SFTtech/openage/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SFTtech/openage/statuses/{sha}","languages_url":"https://api.github.com/repos/SFTtech/openage/languages","stargazers_url":"https://api.github.com/repos/SFTtech/openage/stargazers","contributors_url":"https://api.github.com/repos/SFTtech/openage/contributors","subscribers_url":"https://api.github.com/repos/SFTtech/openage/subscribers","subscription_url":"https://api.github.com/repos/SFTtech/openage/subscription","commits_url":"https://api.github.com/repos/SFTtech/openage/commits{/sha}","git_commits_url":"https://api.github.com/repos/SFTtech/openage/git/commits{/sha}","comments_url":"https://api.github.com/repos/SFTtech/openage/comments{/number}","issue_comment_url":"https://api.github.com/repos/SFTtech/openage/issues/comments{/number}","contents_url":"https://api.github.com/repos/SFTtech/openage/contents/{+path}","compare_url":"https://api.github.com/repos/SFTtech/openage/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SFTtech/openage/merges","archive_url":"https://api.github.com/repos/SFTtech/openage/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SFTtech/openage/downloads","issues_url":"https://api.github.com/repos/SFTtech/openage/issues{/number}","pulls_url":"https://api.github.com/repos/SFTtech/openage/pulls{/number}","milestones_url":"https://api.github.com/repos/SFTtech/openage/milestones{/number}","notifications_url":"https://api.github.com/repos/SFTtech/openage/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SFTtech/openage/labels{/name}","releases_url":"https://api.github.com/repos/SFTtech/openage/releases{/id}","created_at":"2013-11-03T22:35:23Z","updated_at":"2015-07-24T03:47:32Z","pushed_at":"2015-07-24T12:49:49Z","git_url":"git://github.com/SFTtech/openage.git","ssh_url":"git@github.com:SFTtech/openage.git","clone_url":"https://github.com/SFTtech/openage.git","svn_url":"https://github.com/SFTtech/openage","homepage":"http://openage.sft.mx","size":9228,"stargazers_count":3019,"watchers_count":3019,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":275,"mirror_url":null,"open_issues_count":97,"forks":275,"open_issues":97,"watchers":3019,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/321"},"html":{"href":"https://github.com/SFTtech/openage/pull/321"},"issue":{"href":"https://api.github.com/repos/SFTtech/openage/issues/321"},"comments":{"href":"https://api.github.com/repos/SFTtech/openage/issues/321/comments"},"review_comments":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/321/comments"},"review_comment":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SFTtech/openage/pulls/321/commits"},"statuses":{"href":"https://api.github.com/repos/SFTtech/openage/statuses/06675b0463d287c49eade77659d3578691ecbd51"}}}}