/// <summary> /// Sends <paramref name="entity"/> to be postprocessed into the appropriate method based on version. /// </summary> /// <param name="entity"><see cref="Entity"/> to postprocess.</param> private void PostProcessEntity(Entity entity) { if (entity.IsBrushBased) { Vector3 origin = entity.Origin; entity.Remove("origin"); entity.Remove("model"); if (origin != Vector3.Zero) { // If this brush has an origin MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3(-16, -16, -16), new Vector3(16, 16, 16), "common/origin"); entity.brushes.Add(neworiginBrush); } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } switch (_version) { case MapType.Nightfire: { PostProcessNightfireEntity(entity); break; } } }
/// <summary> /// Postprocesser to convert an <see cref="Entity"/> from a Call of Duty BSP to one for Gearcraft. /// </summary> /// <param name="entity">The <see cref="Entity"/> to parse.</param> private void PostProcessCoDEntity(Entity entity) { if (entity.IsBrushBased) { Vector3 origin = entity.Origin; entity.Remove("origin"); entity.Remove("model"); if (entity["classname"].ToUpper().Equals("func_rotating".ToUpper())) { // TODO: What entities require origin brushes in CoD? if (origin == Vector3.Zero) { // If this brush uses the "origin" attribute MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3(-16, -16, -16), new Vector3(16, 16, 16), "special/origin"); entity.brushes.Add(neworiginBrush); } } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } switch (entity["classname"].ToLower()) { case "light": { entity["_light"] = "255 255 255 " + entity["light"]; entity.Remove("light"); break; } case "mp_teamdeathmatch_spawn": case "mp_deathmatch_spawn": { entity["classname"] = "info_player_deathmatch"; break; } case "mp_searchanddestroy_spawn_allied": { entity["classname"] = "info_player_ctfspawn"; entity["team_no"] = "1"; entity.Remove("model"); break; } case "mp_searchanddestroy_spawn_axis": { entity["classname"] = "info_player_ctfspawn"; entity["team_no"] = "2"; entity.Remove("model"); break; } } }
/// <summary> /// Creates a new <see cref="MAPBrush"/> object using this <see cref="Face"/>. The brush will simply have the /// face as its front, the edges will be extruded by <paramref name="depth"/> and will be textured with the /// "nodraw" texture, as well as the back. /// </summary> /// <param name="face">This <see cref="Face"/>.</param> /// <param name="bsp">The <see cref="BSP"/> object this <see cref="Face"/> is from.</param> /// <param name="depth">The desired depth of the resulting brush.</param> /// <returns>A <see cref="MAPBrush"/> object representing the passed <paramref name="face"/>.</returns> public static MAPBrush CreateBrush(this Face face, BSP bsp, float depth) { TextureInfo texInfo; string texture; if (face.TextureInfoIndex >= 0) { texInfo = bsp.texInfo[face.TextureInfoIndex]; if (bsp.texDatas != null) { TextureData texData = bsp.texDatas[texInfo.TextureIndex]; texture = bsp.textures.GetTextureAtOffset((uint)bsp.texTable[texData.TextureStringOffsetIndex]); } else { Texture texData = bsp.textures[texInfo.TextureIndex]; texture = texData.Name; } } else { Vector3[] axes = TextureInfo.TextureAxisFromPlane(bsp.planes[face.PlaneIndex]); texInfo = new TextureInfo(axes[0], axes[1], Vector2.Zero, Vector2.One, 0, -1, 0); texture = "**cliptexture**"; } TextureInfo outputTexInfo = texInfo.BSP2MAPTexInfo(Vector3.Zero); // Turn vertices and edges into arrays of vectors Vector3[] froms = new Vector3[face.NumEdgeIndices]; Vector3[] tos = new Vector3[face.NumEdgeIndices]; for (int i = 0; i < face.NumEdgeIndices; ++i) { if (bsp.surfEdges[face.FirstEdgeIndexIndex + i] > 0) { froms[i] = bsp.vertices[bsp.edges[(int)bsp.surfEdges[face.FirstEdgeIndexIndex + i]].FirstVertexIndex].position; tos[i] = bsp.vertices[bsp.edges[(int)bsp.surfEdges[face.FirstEdgeIndexIndex + i]].SecondVertexIndex].position; } else { tos[i] = bsp.vertices[bsp.edges[(int)bsp.surfEdges[face.FirstEdgeIndexIndex + i] * (-1)].FirstVertexIndex].position; froms[i] = bsp.vertices[bsp.edges[(int)bsp.surfEdges[face.FirstEdgeIndexIndex + i] * (-1)].SecondVertexIndex].position; } } return(MAPBrushExtensions.CreateBrushFromWind(froms, tos, texture, "**nodrawtexture**", outputTexInfo, depth)); }
/// <summary> /// Postprocesser to convert an <see cref="Entity"/> from a Nightfire BSP to one for Gearcraft. /// </summary> /// <param name="entity">The <see cref="Entity"/> to parse.</param> private void PostProcessNightfireEntity(Entity entity) { if (entity.brushBased) { Vector3d origin = entity.origin; entity.Remove("origin"); entity.Remove("model"); if (origin != Vector3d.zero) { // If this brush has an origin MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3d(-16, -16, -16), new Vector3d(16, 16, 16), "special/origin"); entity.brushes.Add(neworiginBrush); } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } }
/// <summary> /// Postprocesser to convert an <see cref="Entity"/> from a Quake 3-based BSP to one for Gearcraft. /// </summary> /// <param name="entity">The <see cref="Entity"/> to parse.</param> private void PostProcessQuake3Entity(Entity entity) { if (entity.IsBrushBased) { Vector3 origin = entity.Origin; entity.Remove("origin"); entity.Remove("model"); if (entity.ValueIs("classname", "func_rotating") || entity.ValueIs("classname", "func_rotatingdoor")) { // TODO: What entities require origin brushes in Quake 3? if (origin != Vector3.Zero) { MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3(-16, -16, -16), new Vector3(16, 16, 16), "special/origin"); entity.brushes.Add(neworiginBrush); } } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } switch (entity["classname"].ToLower()) { case "worldspawn": { if (!entity["suncolor"].Equals("")) { Entity light_environment = new Entity("light_environment"); light_environment["_light"] = entity["suncolor"]; light_environment["angles"] = entity["sundirection"]; light_environment["_fade"] = entity["sundiffuse"]; entity.Remove("suncolor"); entity.Remove("sundirection"); entity.Remove("sundiffuse"); entity.Remove("sundiffusecolor"); _entities.Add(light_environment); } break; } case "team_ctf_blueflag": { // Blue flag entity["classname"] = "item_ctfflag"; entity["skin"] = "1"; // 0 for PHX, 1 for MI6 entity["goal_no"] = "1"; // 2 for PHX, 1 for MI6 entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; entity["model"] = "models/ctf_flag.mdl"; Entity flagBase = new Entity("item_ctfbase"); flagBase["origin"] = entity["origin"]; flagBase["angles"] = entity["angles"]; flagBase["angle"] = entity["angle"]; flagBase["goal_no"] = "1"; flagBase["model"] = "models/ctf_flag_stand_mi6.mdl"; flagBase["goal_max"] = "16 16 72"; flagBase["goal_min"] = "-16 -16 0"; _entities.Add(flagBase); break; } case "team_ctf_redflag": { // Red flag entity["classname"] = "item_ctfflag"; entity["skin"] = "0"; // 0 for PHX, 1 for MI6 entity["goal_no"] = "2"; // 2 for PHX, 1 for MI6 entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; entity["model"] = "models/ctf_flag.mdl"; Entity flagBase = new Entity("item_ctfbase"); flagBase["origin"] = entity["origin"]; flagBase["angles"] = entity["angles"]; flagBase["angle"] = entity["angle"]; flagBase["goal_no"] = "2"; flagBase["model"] = "models/ctf_flag_stand_phoenix.mdl"; flagBase["goal_max"] = "16 16 72"; flagBase["goal_min"] = "-16 -16 0"; _entities.Add(flagBase); break; } case "team_ctf_redspawn": case "info_player_axis": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "2"; goto case "info_player_start"; } case "team_ctf_bluespawn": case "info_player_allied": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "1"; goto case "info_player_start"; } case "info_player_start": case "info_player_coop": case "info_player_deathmatch": { Vector3 origin = entity.Origin; entity["origin"] = origin.X + " " + origin.Y + " " + (origin.Z + 24); break; } case "light": { Vector4 color; if (entity.ContainsKey("_color")) { color = entity.GetVector("_color"); } else { color = Vector4.One; } color *= 255; float intensity = entity.GetFloat("light", 1); entity.Remove("_color"); entity.Remove("light"); entity["_light"] = color.X + " " + color.Y + " " + color.Z + " " + intensity; break; } case "func_rotatingdoor": { entity["classname"] = "func_door_rotating"; break; } case "info_pathnode": { entity["classname"] = "info_node"; break; } case "trigger_ladder": { entity["classname"] = "func_ladder"; break; } case "trigger_use": { entity["classname"] = "func_button"; entity["spawnflags"] = "1"; entity["wait"] = "1"; break; } } }
/// <summary> /// Postprocesser to convert an <see cref="Entity"/> from a Quake 2-based BSP to one for Gearcraft. /// </summary> /// <param name="entity">The <see cref="Entity"/> to parse.</param> private void PostProcessQuake2Entity(Entity entity) { if (!entity["angle"].Equals("")) { entity["angles"] = "0 " + entity["angle"] + " 0"; entity.Remove("angle"); } if (entity.IsBrushBased) { Vector3 origin = entity.Origin; entity.Remove("origin"); entity.Remove("model"); if (entity.ValueIs("classname", "func_rotating")) { if (origin != Vector3.Zero) { MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3(-16, -16, -16), new Vector3(16, 16, 16), "special/origin"); entity.brushes.Add(neworiginBrush); } } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } switch (entity["classname"].ToLower()) { case "func_wall": { if (entity.SpawnflagsSet(2) || entity.SpawnflagsSet(4)) { entity["classname"] = "func_wall_toggle"; } break; } case "item_flag_team2": case "ctf_flag_hardcorps": { // Blue flag entity["classname"] = "item_ctfflag"; entity["skin"] = "1"; // 0 for PHX, 1 for MI6 entity["goal_no"] = "1"; // 2 for PHX, 1 for MI6 entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; Entity flagBase = new Entity("item_ctfbase"); flagBase["origin"] = entity["origin"]; flagBase["angles"] = entity["angles"]; flagBase["angle"] = entity["angle"]; flagBase["goal_no"] = "1"; flagBase["model"] = "models/ctf_flag_stand_mi6.mdl"; flagBase["goal_max"] = "16 16 72"; flagBase["goal_min"] = "-16 -16 0"; _entities.Add(flagBase); break; } case "item_flag_team1": case "ctf_flag_sintek": { // Red flag entity["classname"] = "item_ctfflag"; entity["skin"] = "0"; // 0 for PHX, 1 for MI6 entity["goal_no"] = "2"; // 2 for PHX, 1 for MI6 entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; Entity flagBase = new Entity("item_ctfbase"); flagBase["origin"] = entity["origin"]; flagBase["angles"] = entity["angles"]; flagBase["angle"] = entity["angle"]; flagBase["goal_no"] = "2"; flagBase["model"] = "models/ctf_flag_stand_phoenix.mdl"; flagBase["goal_max"] = "16 16 72"; flagBase["goal_min"] = "-16 -16 0"; _entities.Add(flagBase); break; } case "info_player_team1": case "info_player_sintek": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "2"; break; } case "info_player_team2": case "info_player_hardcorps": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "1"; break; } case "info_player_start": case "info_player_coop": case "info_player_deathmatch": { Vector3 origin = entity.Origin; entity["origin"] = origin.X + " " + origin.Y + " " + (origin.Z + 18); break; } case "light": { Vector4 color; if (entity.ContainsKey("_color")) { color = entity.GetVector("_color"); } else { color = Vector4.One; } color *= 255; float intensity = entity.GetFloat("light", 1); entity.Remove("_color"); entity.Remove("light"); entity["_light"] = color.X + " " + color.Y + " " + color.Z + " " + intensity; break; } case "misc_teleporter": { Vector3 origin = entity.Origin; Vector3 mins = new Vector3(origin.X - 24, origin.Y - 24, origin.Z - 24); Vector3 maxs = new Vector3(origin.X + 24, origin.Y + 24, origin.Z + 48); entity.brushes.Add(MAPBrushExtensions.CreateCube(mins, maxs, "special/trigger")); entity.Remove("origin"); entity["classname"] = "trigger_teleport"; break; } case "misc_teleporter_dest": { entity["classname"] = "info_teleport_destination"; break; } } }
/// <summary> /// Postprocesser to convert an <see cref="Entity"/> from a Source engine BSP to one for Gearcraft. /// </summary> /// <param name="entity">The <see cref="Entity"/> to parse.</param> private void PostProcessSourceEntity(Entity entity) { entity.Remove("hammerid"); if (entity.IsBrushBased) { Vector3 origin = entity.Origin; entity.Remove("origin"); entity.Remove("model"); if (entity.ValueIs("classname", "func_door_rotating")) { // TODO: What entities require origin brushes? if (origin != Vector3.Zero) { MAPBrush neworiginBrush = MAPBrushExtensions.CreateCube(new Vector3(-16, -16, -16), new Vector3(16, 16, 16), "special/origin"); entity.brushes.Add(neworiginBrush); } } foreach (MAPBrush brush in entity.brushes) { brush.Translate(origin); } } switch (entity["classname"].ToLower()) { case "func_breakable_surf": { entity["classname"] = "func_breakable"; break; } case "func_brush": { if (entity["solidity"] == "0") { entity["classname"] = "func_wall_toggle"; if (entity["StartDisabled"] == "1") { entity["spawnflags"] = "1"; } else { entity["spawnflags"] = "0"; } entity.Remove("StartDisabled"); } else { if (entity["solidity"] == "1") { entity["classname"] = "func_illusionary"; } else { entity["classname"] = "func_wall"; } } entity.Remove("solidity"); break; } case "env_fog_controller": { entity["classname"] = "env_fog"; entity["rendercolor"] = entity["fogcolor"]; entity.Remove("fogcolor"); break; } case "prop_static": { entity["classname"] = "item_generic"; break; } case "info_player_rebel": case "info_player_janus": // GoldenEye Source :3 case "ctf_rebel_player_spawn": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "2"; goto case "info_player_deathmatch"; } case "info_player_combine": case "info_player_mi6": case "ctf_combine_player_spawn": { entity["classname"] = "info_ctfspawn"; entity["team_no"] = "1"; goto case "info_player_deathmatch"; } case "info_player_deathmatch": { Vector3 origin = entity.Origin; entity["origin"] = origin.X + " " + origin.Y + " " + (origin.Z + 40); break; } case "ctf_combine_flag": { entity.Remove("targetname"); entity.Remove("SpawnWithCaptureEnabled"); entity["skin"] = "1"; entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; entity["goal_no"] = "1"; entity["model"] = "models/ctf_flag.mdl"; entity["classname"] = "item_ctfflag"; Entity newFlagBase = new Entity("item_ctfbase"); newFlagBase["origin"] = entity["origin"]; newFlagBase["angles"] = entity["angles"]; newFlagBase["goal_max"] = "16 16 72"; newFlagBase["goal_min"] = "-16 -16 0"; newFlagBase["goal_no"] = "1"; newFlagBase["model"] = "models/ctf_flag_stand_mi6.mdl"; _entities.Add(newFlagBase); break; } case "ctf_rebel_flag": { entity.Remove("targetname"); entity.Remove("SpawnWithCaptureEnabled"); entity["skin"] = "0"; entity["goal_max"] = "16 16 72"; entity["goal_min"] = "-16 -16 0"; entity["goal_no"] = "2"; entity["model"] = "models/ctf_flag.mdl"; entity["classname"] = "item_ctfflag"; Entity newFlagBase = new Entity("item_ctfbase"); newFlagBase["origin"] = entity["origin"]; newFlagBase["angles"] = entity["angles"]; newFlagBase["goal_max"] = "16 16 72"; newFlagBase["goal_min"] = "-16 -16 0"; newFlagBase["goal_no"] = "2"; newFlagBase["model"] = "models/ctf_flag_stand_phoenix.mdl"; _entities.Add(newFlagBase); break; } } }