Comments (32)
The error is because you need to run the custom tool for https://github.com/Drake53/CSharp.lua/blob/master/CSharp.lua/MetaResources.resx
I don't use discord, if you have a question you can always open an issue or you can contact me on https://www.hiveworkshop.com
from war3net.
Explain please how to build this project as its not straightforward.
What tool? where is it included?
Why are most of the packages so outdated?
from war3net.
Id like to call the generators from the build process however...
War3Net.CodeAnalysis.Transpilers are .net 5.0
War3Net.Build is .net core 3.1
from war3net.
I simply use visual studio to build the solution. Since I have many uncommitted changes, I may accidentally cause build errors (mostly in test projects since I haven't updated those in a long time while making breaking changes in the libraries). You should be able to build War3Net.Build without errors though.
I had added the .resx designer files to gitignore because they are autogenerated, but since you (and others before you) then get an error because it's missing, I decided to add these files to source control, so you should no longer have issues with that.
The packages were outdated because I forgot to commit the file where I set the versions. If you build in debug mode you don't notice this since it then uses project references instead of package references.
Also, if the CSharpLua submodule is outdated for you, you should be able to update it by going to visual studio team explorer's Changes, rightclick the submodule and select update submodule. If you use the new visual studio git experience I don't know if it works the same way.
Let me know if you have any other issues or questions.
from war3net.
Thanks
So i did update my map and nearly everything broke lmao gonna take time fixing.
How do you use the new Build method which returns void rather then task?
Where do i feed the compiler options since they are not required now?
The build now succeeds on main libs, however besides Tests which are failing there are other things also failing:
6>CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point
6>Done building project "War3Net.Drawing.Blp.Benchmarks.csproj" -- FAILED.
13>C:\Users\Bia\source\repos\War3Net\src\War3Net.Replay\ReplayParser.cs(43,85,43,101): error CS0103: The name 'StreamExtensions' does not exist in the current context
13>CSC : warning SA0001: XML comment analysis is disabled due to project configuration
13>Done building project "War3Net.Replay.csproj" -- FAILED.
14>C:\Users\Bia\source\repos\War3Net\src\War3Net.Rendering\War3Net.Rendering.csproj : error NU1104: Unable to find project 'C:\Users\Bia\source\repos\War3Net\src\War3Net.Drawing.Tga\War3Net.Drawing.Tga.csproj'. Check that the project reference is valid and that the project file exists.
14>Done building project "War3Net.Rendering.csproj" -- FAILED.
15>CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point
15>CSC : warning CA1014: Mark assemblies with CLSCompliant
15>Done building project "War3Net.Modeling.Benchmarks.csproj" -- FAILED.
29>C:\Users\Bia\source\repos\War3Net\src\War3Net.Runtime.Core\War3Net.Runtime.Core.csproj : error NU1104: Unable to find project 'C:\Users\Bia\source\repos\War3Net\src\War3Net.Drawing.Tga\War3Net.Drawing.Tga.csproj'. Check that the project reference is valid and that the project file exists.
29>Done building project "War3Net.Runtime.Core.csproj" -- FAILED.
32>C:\Users\Bia\source\repos\War3Net\src\War3Net.Runtime.Api.Common\War3Net.Runtime.Api.Common.csproj : error NU1104: Unable to find project 'C:\Users\Bia\source\repos\War3Net\src\War3Net.Drawing.Tga\War3Net.Drawing.Tga.csproj'. Check that the project reference is valid and that the project file exists.
32>Done building project "War3Net.Runtime.Api.Common.csproj" -- FAILED.
35>C:\Users\Bia\source\repos\War3Net\src\War3Net.Runtime.Api.Blizzard\War3Net.Runtime.Api.Blizzard.csproj : error NU1104: Unable to find project 'C:\Users\Bia\source\repos\War3Net\src\War3Net.Drawing.Tga\War3Net.Drawing.Tga.csproj'. Check that the project reference is valid and that the project file exists.
35>Done building project "War3Net.Runtime.Api.Blizzard.csproj" -- FAILED.
34>C:\Users\Bia\source\repos\War3Net\src\War3Net.Runtime\War3Net.Runtime.csproj : error NU1104: Unable to find project 'C:\Users\Bia\source\repos\War3Net\src\War3Net.Drawing.Tga\War3Net.Drawing.Tga.csproj'. Check that the project reference is valid and that the project file exists.
34>Done building project "War3Net.Runtime.csproj" -- FAILED.
from war3net.
The easiest way to update War3Net.Build from v1.7.0 to v5.x is to keep using the 'old' MapBuilder. It has been renamed to LegacyMapBuilder. If you want to know how to use the new MapBuilder, you can simply look at how LegacyMapBuilder has been implemented.
I'm not really surprised most projects fail to build. For benchmark projects it's the same story as with tests. Also all the other projects which do not have a NuGet release yet are very WIP and I have a lot of uncommitted stuff there as well. You can simply ignore the errors for now, or you can unload the projects if they bother you.
from war3net.
k done that for now,
i have also noticed that the 5.2.0 transpiler update is breaking my generators.
i hope there wont be anymore breaking updates soon so i have time to adjust :)
btw how do i add players to force?
Legacy:
// Create teams
var team0 = new ForceData()
{
ForceName = "Heroes",
ForceFlags = ForceFlags.Allied | ForceFlags.AlliedVictory | ForceFlags.ShareVision,
};
var team1 = new ForceData()
{
ForceName = "Mutants",
ForceFlags = ForceFlags.Allied | ForceFlags.AlliedVictory | ForceFlags.ShareVision,
};
// Add players to teams
team0.SetPlayers(team0Players);
team1.SetPlayers(team1Player);
New:
// Create teams
var team0 = new ForceData()
{
Name = "Heroes",
//Players = ??
Flags = ForceFlags.Allied | ForceFlags.AlliedVictory | ForceFlags.ShareVision,
};
var team1 = new ForceData()
{
Name = "Mutants",
/Players = ??
Flags = ForceFlags.Allied | ForceFlags.AlliedVictory | ForceFlags.ShareVision,
};
Edit: What map format is MapInfo.Default ? MapInfoFormatVersion.Reforged?
from war3net.
For adding players to force:
team0.Players = new Bitmask32(team0Players.Select(player => player.Id).ToArray());
team1.Players = new Bitmask32(team1Players.Select(player => player.Id).ToArray());
Thanks for reminding me that I also removed MapInfo.Default property, I wanted to replace it with a method so you can choose some values (for example the tileset) just like when you create a new map with the world editor. For now you can add this method:
public static MapInfo Info(
uint mapWidth = 64,
uint mapHeight = 64,
Tileset tileset = Tileset.LordaeronSummer,
GamePatch gamePatch = GamePatch.v1_31_1)
{
if (gamePatch != GamePatch.v1_31_1)
{
throw new NotSupportedException();
}
var info = new MapInfo(MapInfoFormatVersion.Lua)
{
};
info.MapVersion = 1;
info.EditorVersion = 6072;
info.GameVersion = GamePatchVersionProvider.GetGameVersion(gamePatch);
info.MapName = "Just another Warcraft III map";
info.MapAuthor = "Unknown";
info.MapDescription = "Nondescript";
info.RecommendedPlayers = "Any";
const int DefaultLeftComplement = 6;
const int DefaultRightComplement = 6;
const int DefaultBottomComplement = 4;
const int DefaultTopComplement = 8;
const int DefaultHorizontalBoundsOffset = 4;
const int DefaultVerticalBoundsOffset = 2;
var horizontalOffset = (int)mapWidth / 2;
var verticalOffset = (int)mapWidth / 2;
info.CameraBounds = new Quadrilateral(
-TerrainTile.TileWidth * (horizontalOffset - DefaultLeftComplement - DefaultHorizontalBoundsOffset),
TerrainTile.TileWidth * (horizontalOffset - DefaultRightComplement - DefaultHorizontalBoundsOffset),
TerrainTile.TileHeight * (verticalOffset - DefaultTopComplement - DefaultVerticalBoundsOffset),
-TerrainTile.TileHeight * (verticalOffset - DefaultBottomComplement - DefaultVerticalBoundsOffset));
info.CameraBoundsComplements = new RectangleMargins(DefaultLeftComplement, DefaultRightComplement, DefaultBottomComplement, DefaultTopComplement);
info.PlayableMapAreaWidth = (int)mapWidth - info.CameraBoundsComplements.Left - info.CameraBoundsComplements.Right;
info.PlayableMapAreaHeight = (int)mapHeight - info.CameraBoundsComplements.Bottom - info.CameraBoundsComplements.Top;
info.MapFlags
= MapFlags.UseItemClassificationSystem
| MapFlags.ShowWaterWavesOnRollingShores
| MapFlags.ShowWaterWavesOnCliffShores
| MapFlags.MeleeMap
| MapFlags.MaskedAreasArePartiallyVisible
| MapFlags.HasMapPropertiesMenuBeenOpened;
info.Tileset = tileset;
info.LoadingScreenBackgroundNumber = -1;
info.LoadingScreenPath = string.Empty;
info.LoadingScreenText = string.Empty;
info.LoadingScreenTitle = string.Empty;
info.LoadingScreenSubtitle = string.Empty;
info.GameDataSet = GameDataSet.Unset;
info.PrologueScreenPath = string.Empty;
info.PrologueScreenText = string.Empty;
info.PrologueScreenTitle = string.Empty;
info.PrologueScreenSubtitle = string.Empty;
info.FogStyle = FogStyle.Linear;
info.FogStartZ = 3000f;
info.FogEndZ = 5000f;
info.FogDensity = 0.5f;
info.FogColor = Color.Black;
info.GlobalWeather = WeatherType.None;
info.SoundEnvironment = string.Empty;
info.LightEnvironment = 0;
info.WaterTintingColor = Color.White;
if (gamePatch >= GamePatch.v1_32_0)
{
info.SupportedModes = SupportedModes.SD | SupportedModes.HD;
info.GameDataVersion = GameDataVersion.TFT;
}
var player0 = new PlayerData
{
Id = 0,
Controller = PlayerController.User,
Race = PlayerRace.Human,
Flags = 0,
Name = "Player 1",
StartPosition = new Vector2(0f, 0f),
AllyLowPriorityFlags = new Bitmask32(0),
AllyHighPriorityFlags = new Bitmask32(0),
};
info.Players.Add(player0);
var team0 = new ForceData
{
Flags = 0,
Players = new Bitmask32(-1),
Name = "Team 1",
};
info.Forces.Add(team0);
return info;
}
Also can you explain how the transpiler update broke your generators? Is it because the CSharpLua attributes are no longer generated?
from war3net.
So why have you chosen to use Bitmask32 for players representation? If possible id like to stay away from having a need to use bit manipulation for every minor stuff.
Also can you explain how the transpiler update broke your generators? Is it because the CSharpLua attributes are no longer generated?
from war3net.
The players in ForceData have always been represented as a single int, because the classes like MapInfo, MapEnvironment, etc are simply a representation of the binary file formats, so if something is an int the the war3map file then I also use an int in these classes. The SetPlayers method was a helper method that converted players to this int, it didn't actually get stored as a list of players. I made the Bitmask class to make it clear when an int is used for something like this. The fact that these classes (MapInfo, etc) represent a binary file is also why I removed most helper methods, they are basically model classes so shouldn't have too much extra stuff, for that I prefer to use extension methods now. I'll probably add SetPlayers back as an extension method.
About the generator, I rewrote the jass syntax project from scratch because it was very badly made (I only made it for War3Api initially, didn't put much effort into optimizing it). The old syntax classes were basically a 1:1 mapping of the grammar (making it hard to use and requiring SyntaxFactory methods to make creation in code easier). I remade the library using an existing parsing library for better performance, and also remade all the syntax classes from scratch so they are a lot more similar to the lua syntax classes found in CSharpLua. For example, instead of FileSyntax you now have JassCompilationUnitSyntax (similar to LuaCompilationUnitSyntax in CSharpLua).
Also useful to know, I remade the transpiler classes so they are no longer static with extension methods. This makes it easier to add settings to the transpiler, as you don't have to pass them around as method parameters.
I also intend to have the functionality in your screenshot built-in in the War3Net.Build project. For regions I already made this:
public static IEnumerable<MemberDeclarationSyntax> RegionsApi(Map map, JassToCSharpTranspiler transpiler)
{
return Regions(map).Select(region => transpiler.Transpile(region));
}
Note that this only returns the members, so you still have to create your own class+namespace+compilationunit around it.
EDIT: forgot to mention, the Regions method it calls can be found here: https://github.com/Drake53/War3Net/blob/master/src/War3Net.Build/MapScriptBuilder/Variables/Regions.cs
It's a protected method, so if you want access to it you need to make a subclass of MapScriptBuilder.
from war3net.
okay, ill check it out later.
how do you access the build in data like loading screens? where do you get the path from?
how do i access this loading screen? this is likely not the correct path.
maps/frozenthrone/campaign/nightelfx06interlude.w3x:war3mapmap.blp
from war3net.
To access files inside an mpq archive you can use MpqFile.OpenRead (this method used to exist in the FileProvider class).
from war3net.
Back to map info example
the parameter defaults to GamePatch gamePatch = GamePatch.v1_31_1
if (gamePatch != GamePatch.v1_31_1)
{
throw new NotSupportedException();
}
which disqualifies anything else... and yet later
if (gamePatch >= GamePatch.v1_32_0)
{
info.SupportedModes = SupportedModes.SD | SupportedModes.HD;
info.GameDataVersion = GameDataVersion.TFT;
}
and there is no touch of gamePatch in between the code
from war3net.
The method to create MapInfo is intended to behave exactly like the world editor (so if I do a byte-by-byte comparison of the war3map.w3i created by the world editor and my library, they should be exactly the same). I only tested this on 1.31, which is why I put that condition there, but you can safely remove it.
from war3net.
I just uploaded War3Net.Build v5.0.0-preview3, you can now use the SetPlayers method again to add players to a team, and I also included the RegionsApi method that I mentioned earlier (along with similar methods for the camera, random unit group, unit, and sound variables).
from war3net.
sounds great,
ill keep this open as reference till I address what u said.
from war3net.
Updated War3Net.Build to preview 4, fixing the CSharpLua.Template for generated globals. Example of how you would use it:
var mapScriptBuilder = new MapScriptBuilder();
mapScriptBuilder.SetDefaultOptionsForMap(map);
var jassToCSharpTranspiler = new JassToCSharpTranspiler();
jassToCSharpTranspiler.ApplyCSharpLuaTemplateAttribute = true;
jassToCSharpTranspiler.JassToLuaTranspiler = new JassToLuaTranspiler();
var compilationUnit = SyntaxFactory.CompilationUnit(
default,
SyntaxFactory.SingletonList(
SyntaxFactory.UsingDirective(
SyntaxFactory.Token(SyntaxKind.StaticKeyword),
null,
SyntaxFactory.ParseName($"{nameof(War3Api)}.{nameof(War3Api.Common)}"))),
default,
new SyntaxList<MemberDeclarationSyntax>(
SyntaxFactory.NamespaceDeclaration(
SyntaxFactory.ParseName("GeneratedGlobals"),
default,
default,
SyntaxFactory.List(new MemberDeclarationSyntax[]
{
SyntaxFactory.ClassDeclaration(
default,
new SyntaxTokenList(
SyntaxFactory.Token(SyntaxKind.PublicKeyword),
SyntaxFactory.Token(SyntaxKind.StaticKeyword)),
SyntaxFactory.Identifier("Regions"),
null,
null,
default,
new SyntaxList<MemberDeclarationSyntax>(
mapScriptBuilder.RegionsApi(map, jassToCSharpTranspiler))),
SyntaxFactory.ClassDeclaration(
default,
new SyntaxTokenList(
SyntaxFactory.Token(SyntaxKind.PublicKeyword),
SyntaxFactory.Token(SyntaxKind.StaticKeyword)),
SyntaxFactory.Identifier("Units"),
null,
null,
default,
new SyntaxList<MemberDeclarationSyntax>(
mapScriptBuilder.UnitsApi(map, jassToCSharpTranspiler))),
}))));
compilationUnit.NormalizeWhitespace().WriteTo(streamWriter);
This should help you update your Generate method that you posted earlier.
from war3net.
so after updating i tried to build however failed to obtain build result have i set anything wrong in the compiler options?
since it has something to do with PlayerData heres how my player and force settings looks like:
from war3net.
It's because the ally priority flags are null (these were also changed from int to bitmask).
from war3net.
i c, thx
now i get this one
at War3Net.Build.MapScriptBuilder.main(Map map)
at War3Net.Build.MapScriptBuilder.<>c__DisplayClass27_0.<Build>g__AppendBannerAndFunction|1(String bannerText, Func`2 function, Func`2 condition)
at War3Net.Build.MapScriptBuilder.Build(Map map)
at War3Net.Build.Extensions.MapExtensions.CompileScript(Map map)
at War3Net.Build.LegacyMapBuilder.Build(ScriptCompilerOptions compilerOptions, String[] assetsDirectories)
at MutantTag.Launcher.Program.Build(Boolean launch) in C:\Users\Bia\source\repos\MutantTag\src\MutantTag.Launcher\Program.cs:line 65
from war3net.
What's the exception's type and message?
from war3net.
What's the exception's type and message?
from war3net.
Either the MapInfo's CameraBounds and CameraBoundsComplements are both null, or the MapEnvironment is null.
After inspecting my code it's probably the MapEnvironment being null. If you don't set the map environment using ScriptCompilerOptions.MapEnvironment, it will always be null. You should still be able to set it using MapBuilder.AddFiles (which legacymapbuilder uses on the passed assetsDirectories), but this method is not allowed to overwrite existing properties on the Map object, and because MapEnvironment is not allowed to be null, it assumes it already exists and doesn't check null.
This bug should be fixed in preview5.
I also noticed your code is calling CompileScript(Map), which means the map is set to jass instead of lua.
from war3net.
Yup it was MapEnvironment , how am i supposed to know which options are required if even mapinfo field is marked ?
I also noticed your code is calling CompileScript(Map), which means the map is set to jass instead of lua.
yes, was default, set to lua now.
Well tested both on jass and lua map compiles and executes :]
from war3net.
The only required files to run a map are war3map.w3i, war3map.w3e, and war3map.j or war3map.lua, that's why in the Map class, these three (Info, Environment, and Script properties) are not nullable. However when you use the LegacyMapBuilder, the info and environment files can come from either the ScriptCompilerOptions or from the assetsDirectories. That is why the MapInfo and MapEnvironment properties are marked as nullable in ScriptCompilerOptions.
Good to hear you got it all working again now, and thanks for helping me improve the library by finding these issues and bugs.
Let me know if you have any more questions, otherwise feel free to close the issue.
from war3net.
hmm not yet it seems!
well began updating the generators and results are bamboozling
According to live debug there are 28 units to be parsed:
However the result seems unfinished as there are only 24 units and no closing braces for both units class and namespace, however none exceptions occurred.
btw: is the Id = 0, field required for each player data? if i have multiple different player data can i simply put it for first one and will it auto increment?
from war3net.
Make sure you flush the stream/writer.
Also the playerdata Id will not auto-increment, you need to set it.
EDIT: What works for me is to do it like this:
using (var stream = File.Create(path))
{
using (var writer = new SteamWriter(stream))
{
// ...
compilationUnit.NormalizeWhitespace().WriteTo(writer);
}
}
from war3net.
yeah i forgot using declaration
is it fine to set the Id to 0? Or where do i obtain the correct value?
from war3net.
The id is 0-indexed so yeah it can be zero. Correct value is whatever you want it to be, just make sure it's unique.
0 = player 1 (red)
1 = player 2 (blue)
etc
from war3net.
Thanks,
btw how do i set high priority flags for allies? i came up with something like this:
foreach (var playerData in team0Players)
{
playerData.AllyHighPriorityFlags = SetHighToOtherPlayers(playerData.Id, team0Players);
}
private static Bitmask32 SetHighToOtherPlayers(int curPlayerId, IEnumerable<PlayerData> players)
{
var playerArray = players.Select(player => player.Id)
.Where(id => id != curPlayerId)
.ToArray();
return new Bitmask32(playerArray);
}
is that okay?
also id like to be able to manipulate enemiesLowPriorityFlag and enemiesHighPriorityFlags
how does one set these flags to none all i see is some unknowns :/
public Bitmask32 AllyLowPriorityFlags { get; set; }
public Bitmask32 AllyHighPriorityFlags { get; set; }
public int Unk1 { get; set; }
public int Unk2 { get; set; }
from war3net.
Should be fine, I don't really care for the ally priority flags since it seems more like a feature for melee maps.
Do you have a source or own research that shows those Unks' meaning is enemy priority flags? A test map would also be appreciated if you have it, which I can test by comparing the generated war3map.j to the one generated by the world editor (the map should not use triggers/vjass/lua since that stuff is not supported by my MapScriptBuilder).
from war3net.
K, thanx for cooperation.
okay ill research that later.
closing
from war3net.
Related Issues (20)
- Implement .wgc HOT 6
- Value '3' is not defined for enum of type ObjectDataFormatVersion HOT 2
- Issues with exporting to .json HOT 5
- Cannot cast Char to Tileset & anything to enum really HOT 4
- Invalid Cast Exception (Imported BLPs) HOT 6
- Unable to parse value '0.15' HOT 3
- 'Value '6115' is not defined for enum of type EditorVersion.' HOT 1
- Compiler can crash rather than offering error message HOT 1
- Map builder broken HOT 2
- All destructible on compiled maps are duplicated HOT 8
- MapBuilder method 'AddFiles' fails to add files correctly. HOT 1
- Update .w3i Info file parser HOT 5
- Map.Open does not read object names or tooltips HOT 3
- Editing custom tile pathing HOT 2
- War3 Server HOT 1
- Is it possible to build a Map as a folder instead of a .w3x file? HOT 2
- Zopfli Compression HOT 2
- Expose more should be internal API to become public HOT 2
- What's the difference between Field/LevelField/ArrayLevelField?
- OpenFile() in MpqArchive seems to keep file handle open even when calling Close/Dispose HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from war3net.