Grapjas Posted December 18, 2020 Report Share Posted December 18, 2020 I'm trying to give players a random position on the map im currently making. I took a look at the rmgen scripts but im a lil lost honestly. To be clear, my map already has civic centers placed, aswell as the resources, so these things do not have to be randomized. The only thing i want random is where each player will be put into existing CC, while being adjacent to team members. If up until this part of what i'm asking is not possible the way i discribe it, is it possible to make a custom rmgen2 script and put the exact coordinates where i want players to have their CC placed? I think i need some parts of rmgen2/setup.js but im doubtful as to how to approach this. Quote Link to comment Share on other sites More sharing options...
Stan` Posted December 18, 2020 Report Share Posted December 18, 2020 You need to somehow randomize the buildings owners by group. I assume there is a method for this in triggers Quote Link to comment Share on other sites More sharing options...
badosu Posted December 19, 2020 Report Share Posted December 19, 2020 (edited) Grapjas, that's possible but not too straightforward to implement. You'll basically need to redefine one of:`placePlayerBase`, `placeCivDefaultStartingEntities` functions or any other function that starts with `placePlayerBase*`. Edited December 19, 2020 by badosu 1 Quote Link to comment Share on other sites More sharing options...
badosu Posted December 19, 2020 Report Share Posted December 19, 2020 (edited) If you don't need full control: Just assign a variable to the result of the placer function, usually that's `playerPlacementCircle` for typical maps e.g. nobland, get the playerPositions which is the second return argument, add some randomization to the positions and give it back on `placePlayerBases`, e.g.: let playerPlacements = playerPlacementCircle( // ... or whatever is being used as the player placer function let [playerIDs, playerPositions] = playerPlacements; // iterate and modify playerPositions e.g. playerPlacements = [playerIds, playerPositions.map((pos) => _modify_pos_)]; placePlayerBases({ "PlayerPlacement": playerPlacements, // give it back to 0ad The root of the territory is the cc location itself, so you can't do much better than this. That's what will be positioned on what you specify there, you can only change the distribution of entities around it via heavy patching or some other clever way of the functions I mentioned on the previous post. Edited December 19, 2020 by badosu 1 1 Quote Link to comment Share on other sites More sharing options...
badosu Posted December 19, 2020 Report Share Posted December 19, 2020 19 hours ago, Grapjas said: The only thing i want random is where each player will be put into existing CC, while being adjacent to team members. Also, can you describe what you mean here? The player is literally the CC and the entities they start with, I'm not sure what you want. Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 19, 2020 Author Report Share Posted December 19, 2020 (edited) 4 hours ago, badosu said: Also, can you describe what you mean here? The player is literally the CC and the entities they start with, I'm not sure what you want. What im aiming for is: I want fixed starting places on the map, but randomize to which fixed place the player will be assigned to. This way e.g. player 3 wont always end up on position 3, but can be assigned to position 8, or 5, etc. However the team members need to be adjacent to eachother. Im not sure i can formulate it clearly than this . Plan A: I already have 8 CC's on the current map im making where i want them to be. I was looking for a way via js to change ownerships of said CC's randomly on start of the game. Plan B: Delete current existing CC's, let the gen make bases for players, but at 1 of the 8 coördinates provided in the code (if possible at all). I'll crack my brain with your code , ty for help. Edited December 19, 2020 by Grapjas Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 19, 2020 Author Report Share Posted December 19, 2020 (edited) 59 minutes ago, Grapjas said: I already have 8 CC's on the current map im making where i want them to be. I was looking for a way via js to change ownerships of said civs randomly on start of the game. I just realised this gives problems if there are less than 8 players, there would still be extra CC's. So no-go i guess. zzZZzz it's not easy being stupid. Edited December 19, 2020 by Grapjas Quote Link to comment Share on other sites More sharing options...
Stan` Posted December 19, 2020 Report Share Posted December 19, 2020 Well you could delete them by script? Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted December 19, 2020 Report Share Posted December 19, 2020 This feature should be a core game feature, IMHO. Quote Link to comment Share on other sites More sharing options...
badosu Posted December 20, 2020 Report Share Posted December 20, 2020 (edited) 13 hours ago, Grapjas said: What im aiming for is: I want fixed starting places on the map, but randomize to which fixed place the player will be assigned to. This way e.g. player 3 wont always end up on position 3, but can be assigned to position 8, or 5, etc. However the team members need to be adjacent to eachother. Im not sure i can formulate it clearly than this . Ah, that's super straightforward to do. Just assign playerids and playerpositions to your liking as I mentioned on my previous post. For randomizing playerids grouping by team look for `sortPlayers(playerIDs)` in player.js. 4 hours ago, wowgetoffyourcellphone said: This feature should be a core game feature, IMHO. Which feature? Player positioning is map dependent. With A24 would be nice to have specific 1v1, 2v2, 3v3, 4v4 maps with fixed positions but unequal distribution. You could then enable the flag for unequal distribution and you'd be assigned to one spot of the map. Could be diagonally opposed, vertical or horizontal, the opponent wouldn't know your position ahead of time. Biggest issue with that is that harassment capability is greatly impaired with bigger map size, so for a 1v1 I think at most 4 to (arguably) 6 positions can be feasibly done (medium to normal size). If the feature is enabling this random distribution then it would require a revamp of all maps, which is not a terrible idea but unfeasible in the short time. Map balance is in a worse state than that for example. This is something from Starcraft 2 that would definitely be super great to have. I thought about putting it into balanced-maps but I'd rather wait for A24 flags (whenever it happens, if I'm still around) Edited December 20, 2020 by badosu Quote Link to comment Share on other sites More sharing options...
badosu Posted December 20, 2020 Report Share Posted December 20, 2020 (edited) @Grapjas Implementation is simple, store an array of n positions of the coordinates of the starting locations you want (or whatever is the number of max players you want for map). The algorithm below randomizes position assignments: let fixedPositions = [...]; // your fixed set of positions let playerPositions = []; for (int i=0; i<playerIDs.length; i++) { fixedPositions = shuffleArray(fixedPositions); // shuffle available positions to take random spot or do whatever you want to assign player positioning playerPositions.push(fixedPositions.pop()); // add position to players, pop to take one available position out of the array } let playerPlacements = [playerIDs, playerPositions]; // Pass to placePlayerBases To make it respect adjacency you'd have to make it a bit more complicated, sorting playerIds as I mentioned on post above and sorting fixedPositions with assignment respecting that could work, though I'd require a bit more work to handle edge cases. Edited December 20, 2020 by badosu 1 Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 20, 2020 Author Report Share Posted December 20, 2020 12 hours ago, badosu said: let fixedPositions = [...]; // your fixed set of positions What is the format to specify the coordinates? Could i also use triggerpoints as positions for this? Quote Link to comment Share on other sites More sharing options...
badosu Posted December 20, 2020 Report Share Posted December 20, 2020 (edited) Array of Vector2D with the coordinates u want. e.g. let fixedPositions = [ new Vector2D(x1, y1), new Vector2D(x2, y2), //... ]; For a programmatic approach see distributePointsonCircularSegment, e.g. for a circle: let points = []; let angle = []; let startAngle = 0; let maxAngle = 2 * Math.PI; let center = g_Map.getCenter(); let radius = fractionToTiles(0.35); pointCount = Math.round(pointCount); for (let i = 0; i < pointCount; ++i) { angle = startAngle + maxAngle * i / Math.max(1, pointCount - 1); points[i] = Vector2D.add(center, new Vector2D(radius, 0).rotate(-angle)); } Edited December 20, 2020 by badosu 1 Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 20, 2020 Author Report Share Posted December 20, 2020 @badosu let fixedPositions = [ new Vector2D(x:434, y:562), new Vector2D(x:466, y:946), new Vector2D(x:526, y:1392), new Vector2D(x:892, y:1365), new Vector2D(x:1224, y:1390), new Vector2D(x:1334, y:936), new Vector2D(x:1303, y:517), new Vector2D(x:866, y:499), ]; gives me syntax error: missing ) after argument list Can't find out why. Also one probably important thing i forgot to point out, is that i'm not using rmgen, because it's a skirmish map and i assume they can't work together. Starting to think i bit off more than i can chew though, im not a scripter at all. Quote Link to comment Share on other sites More sharing options...
badosu Posted December 20, 2020 Report Share Posted December 20, 2020 The syntax is wrong, just pass the x and y numbers. If it's not rmgen u need to import the libraries. See how on the map codes, you can also check balanced-maps on github 1 Quote Link to comment Share on other sites More sharing options...
badosu Posted December 21, 2020 Report Share Posted December 21, 2020 Wait, if you are doing this on a skirmish map players will start already with cc. Otherwise you will duplicate ccs, unless u delete autogenerated by map ones like @Stan` said, I'm not sure how to do that. It would be nice to be able to load a skirmish map on rmgen and scripting player positions and other stuff there. Maybe it's possible dunno, but would be the correct approach for your situation. Quote Link to comment Share on other sites More sharing options...
Stan` Posted December 21, 2020 Report Share Posted December 21, 2020 You can save terrain data in the js file I believe. But I don't think you can open the pmp directly. Check jebel barca for an example on how to use a height array. 1 Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 21, 2020 Author Report Share Posted December 21, 2020 15 hours ago, badosu said: If it's not rmgen u need to import the libraries I already tried doing this with: Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmgen-common"); but it gives me: Engine.LoadLibrary is not a function. If i understand this correctly; it's because it's a skirmish map, and not generated from the ground up in js. ---------------------------------------------------------------------------------------------------------------- 11 hours ago, badosu said: Wait, if you are doing this on a skirmish map players will start already with cc. which is why this was plan A; On 19/12/2020 at 2:22 PM, Grapjas said: Plan A: I already have 8 CC's on the current map im making where i want them to be. I was looking for a way via js to change ownerships of said CC's randomly on start of the game. ---------------------------------------------------------------------------------------------------------------- I've tried working with triggers before i tried to incorperate rmgen with a skirmish map. It does somewhat work (at least i was able to spawn something which gave me hope, lol) but has major issues. What i did was delete all the CC's on the map in atlas, then let triggers spawn CC"s at the start of the game. The script: Spoiler Trigger.prototype.spawnP1 = function() { var p1 = TriggerHelper.SpawnUnitsFromTriggerPoints( pickRandom(["A", "B", "C", "D", "E", "F", "G", "H"]), "skirmish/structures/default_civil_centre", 1, 1); }; { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); cmpTrigger.timerspawnP1 = 0; cmpTrigger.DoAfterDelay(cmpTrigger.timerspawnP1, "spawnP1", {}); } The issues: This way it's very likely that players will spawn on top of eachother, and i understand why it's happening, but don't know how to fix it. @badosu in your code you popped one position out of the equation if it was used, but idk how to do that here. I don't know how to spawn a group of units/building. I've tried understanding maps like danubius and jebel for this, but can't figure out how to create and use templates and make a proper connection to them from this. I've tried Spoiler var baseTemplate = [ { "count": 1, "templates": ["skirmish/structures/default_civil_centre"] }, { "count": 2, "templates": ["skirmish/units/default_infantry_melee_b"] }, { "count": 2, "templates": ["skirmish/units/default_infantry_ranged_b"] }, { "count": 4, "templates": ["skirmish/units/default_support_female_citizen"] } ]; Trigger.prototype.spawnP1 = function() { var p1 = TriggerHelper.SpawnUnitsFromTriggerPoints( pickRandom(["A", "B", "C", "D", "E", "F", "G", "H"]), this.baseTemplate, 1, 1); }; { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); cmpTrigger.timerspawnP1 = 0.01; cmpTrigger.DoAfterDelay(cmpTrigger.timerspawnP1, "spawnP1", {}); } which gives me syntaxerror: missing ] after element list (the format is probably completely wrong though). The map needs to be compatiable with AI for the people that like to play with them. Right now i get error "petra AI doesnt know how to interpret this map", likely because the AI gets loaded before the CC's are spawned. Unassigned players CC need to be deleted via js, like @Stan` already said. Or they simply just shouldnt spawn at all if there is a way for the script to check if the player is assigned before placing the CC's. Haven't looked into this yet because the other issues have priority tbh. ---------------------------------------------------------------------------------------------------------------- 6 hours ago, Stan` said: You can save terrain data in the js file I believe. Is this so that i can use it with rmgen? Also what is stored in terrain data? elevation+textures? ---------------------------------------------------------------------------------------------------------------- This is all i have right now. Don't laugh at my nooby codes , i do plenty myself. Quote Link to comment Share on other sites More sharing options...
Stan` Posted December 21, 2020 Report Share Posted December 21, 2020 4 hours ago, Grapjas said: Engine.LoadLibrary("rmgen"); IIRC that function uses the current directory as reference. So for Random maps it's fine, cause the folders are in mod/maps/random, but for skirmishes it isn't. 1 Quote Link to comment Share on other sites More sharing options...
badosu Posted December 22, 2020 Report Share Posted December 22, 2020 (edited) 17 hours ago, Grapjas said: @badosu in your code you popped one position out of the equation if it was used, but idk how to do that here. Same thing, instead of pickrandom: let availablePositions = ["A", "B", "C", "D", "E", "F", "G", "H"]; Trigger.prototype.spawnP1 = function() { availablePositions = shuffleArray(availablePositions); var p1 = TriggerHelper.SpawnUnitsFromTriggerPoints( availablePositions.pop(), this.baseTemplate, 1, 1); }; 17 hours ago, Grapjas said: I don't know how to spawn a group of units/building. I've tried understanding maps like danubius and jebel for this, but can't figure out how to create and use templates and make a proper connection to them from this. I never placed structures, units, only gaia stuff. You probably need rmgen for this: new SimpleObject("gaia/geology_metal_mediterranean_slabs", 1, 1, 0, 4).place( new Vector2D(x, y), playerID, false, NullConstraint(), 30 // Retries, never would be necessary for non random maps, should pass on first attempt. Otherwise, learn how to use a placer, like ODiskPlacer on balanced-maps or increase 5th argument on SimpleObject initializer on first line ) Edited December 22, 2020 by badosu 1 Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 22, 2020 Author Report Share Posted December 22, 2020 (edited) @badosu have you got any idea why i cant use the popped position? Spoiler let availablePositions = ["A", "B", "C", "D", "E", "F", "G", "H"]; let lastPosition = availablePositions.pop(); Trigger.prototype.spawnPlayers = function() { availablePositions = shuffleArray(availablePositions); var p1 = TriggerHelper.SpawnUnitsFromTriggerPoints( availablePositions.pop(), "skirmish/structures/default_civil_centre", 1, 1); TriggerHelper.SpawnUnitsFromTriggerPoints( lastPosition, "skirmish/units/default_infantry_melee_b", 2, 1); TriggerHelper.SpawnUnitsFromTriggerPoints( lastPosition, "skirmish/units/default_infantry_ranged_b", 2, 1); TriggerHelper.SpawnUnitsFromTriggerPoints( lastPosition, "skirmish/units/default_support_female_citizen", 4, 1); }; Everything spawns, but the units only go for position "H". Never mind! figured it out! progessss lol. Edited December 22, 2020 by Grapjas Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 23, 2020 Author Report Share Posted December 23, 2020 @Stan` @badosu would it be possible to store playernames as a variable? looked through most, if not all the documentation but cant find info on it. What i need it for is to filter out the 'Unassigned' players with an if statement. Quote Link to comment Share on other sites More sharing options...
badosu Posted December 23, 2020 Report Share Posted December 23, 2020 (edited) g_Players, though I'm not sure it's available at triggers level. What is an 'Unassigned' player? Can't rely on documentation, look ay other mods source or directly into the source code. Edited December 23, 2020 by badosu Quote Link to comment Share on other sites More sharing options...
Stan` Posted December 23, 2020 Report Share Posted December 23, 2020 Or update the documentation Not sure about detecting ai and player settings. Quote Link to comment Share on other sites More sharing options...
Grapjas Posted December 24, 2020 Author Report Share Posted December 24, 2020 (edited) 5 hours ago, badosu said: What is an 'Unassigned' player? Unassigned player is neither AI or human player. Though i could still spawn player 2 like this (which is the issue). It's just nothing controlling it. I did find where player assignments are being handled @ gui/gamesetup/gamesetup.js. The issue is probably like you said, can't reach that level, because whatever i try it aint working. I'll keep looking. Edited December 24, 2020 by Grapjas Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.