Jump to content

new scenario map - malta island


Recommended Posts

Hello,

I created a scenario map based on malta island topography and inspired from the island's history. But I have to face many issues:

I can't play my scenario map in 0AD. I know I need to copy my .xml and .ppm created files in a folder in the "main" binaries folder, or alternatively in the "mod" folder. I tried to copy my files everywhere based on informations from this forum, but I am still unable to find and play my new map in 0AD. I just would like to select it in single player mode to test it easily. When creating a map using Atlas, the file is listed in the Atlas file browser (atlas -> open file). Is it possible for you to set the path of newly created maps in the same folder than the default map ? It would help a lot. Also, could you give updated information about how to play created maps ? Obviously, I would like to test it and balance the available units/resources on the map before a real submission on this forum.

I tried to upload some screenshot of my map, but new forum accounts seems to be limited in attaching files. A 5MB limit is indicated on my account, but I can't even upload a 300KB single file. So I can't show you my WIP. No need to mention I can't upload a .zip file of my map.

I would also like to add some JS to create a real scenario. Do you have any examples of scripts used in scenarios to generate triggers and control the AI while player progresses ?

Thank you for your help and informations.

  • Like 1
Link to comment
Share on other sites

If you saved your map in Atlas than you don't need to copy it to a different folder. Copying it to a folder is only needed when you download someone else's map. Also make sure to check whether you saved it as scenario out skirmish. Also double-check the name of the map (the filename is not (!) the name of the map in the game! You need to fill it in in a tekstbox in Atlast)

  • Like 3
Link to comment
Share on other sites

Ok guys, thank you for your very fast answer.

I finally found out how to use my map. The problem was I didn't set up anything in the "name" field of Atlas. So the name was blank, not listed, and the "filename" is different from the name of the file as you said niektb. It was the origin of my troubles.

I tried to play the map but as it contains more than 1 AI bot, the game lag and finally freeze after a while. I have the same problem with any other map with more than a single AI. I can "simulate" the scenario using Atlas, probably because there is no active AI in Atlas (if I am right ?), so I can't test it for now, until the lag problem will be corrected. Can you guys play maps with more than 1 AI on your systems ? If so, I would be pleased that you test my map. You surely could help me to improve it.

About the screenshot, it seems to be unlocked as I posted my first message. Here are some teasers :

Here is malta Island :

map.jpg.caf9c750330114a6870a72830d73f1bc

And here is my map :

screenshot0001.thumb.png.0805890fc44fd0d

screenshot0002.thumb.png.a6e8ae8b03d207f

I'll post other screenshots if I do land major updates, but I need to focus on scenario more.

I tried to respect the topography of the island as much as I could. The scenario game is as follow : some romans troups invade the island from the north (gozo), then cross the blue lagoon bay (take a look at this beautiful place : https://en.wikipedia.org/wiki/File:The_Blue_Lagoon.jpg) then eventually conquer the malta island, already colonized by greek and carthagian villagers (there was phenician between 200 BC and 300 AD but no phenicians yet in the game). I would like to add some triggers, depending on how will react the AI, and as player progress through the island. I hope you'll enjoy it, when I'll be able to upload the scenario. I hope it could fit your quality expectations for this game too.

Thank you for the JS example, I haven't noticed there was an example in this page (treasure_islands.js). I'll try to set some script from this. How can you define or see the name of each objects inserted on the map (like object properties) to define triggers from specified units/ressources or even animals ?

Looking forward your feedback,

Thanks for the infos guys.

  • Like 1
Link to comment
Share on other sites

@sanderd17: thanks!

So I can finally post my map, here is the original scenario I plan to develop:

 

I already described the content of the scenario earlier. If you try to play this scenario, here is what I have in mind and what I would like to improve by JS / AI tweaking :

So you play Romanian (blue) and the enemies are Athenians (orange) and Carthagians (red).

Spoiler

When you first attack orange player, as it is the start it is quite easy to conquer the north Island (Gozo), then take across the little island (comino/blue lagoon) before really try to conquer Malta. The problem is you will have a continuous flow of red ships trying to flood Gozo island at start. I want to avoid this problem. The idea is to face sequentially two enemies with a different difficulty. Orange are quite pacific, mostly merchant, while red is the real challenge with military ships. What I have in mind is to prevent red attacking blue before blue reach a certain point on the map, or directly attack the red faction. Even if orange is attacked, red shouldn't do anything (greeks and carthagians were commercial partners in the island, not military partners). So taking the orange positions first would be the best thing to do.

So it is why I would like to put some JS to control the invasion.

Here is another comment about the design of the map:

Spoiler

Is it quite difficult to construct some buildings on some areas, because there is not enough room in some parts. This is part of the gameplay for this scenario. Basically, when you come directly from comino/blue lagoon, it would be difficult to build some military positions on the extreme north part of malta. The shortest way is not the best way. Player should have to visit the coast to find the most appropriate place to build any military buildings.

I also post a 2 player version of this map, if other players have problems with AI and would like to try to face a single AI bot. This is actually the only version of my scenario I was able to play, and I tested and completed:

 

Looking forward your feedback, I hope you'll have some fun with the map!

Edited by AtlasMapper
Outdated files
  • Like 1
Link to comment
Share on other sites

I can't find any help about functions/objects used on map for tiggers/scripting.
I would like to add a simple script in the <ScriptSettings> part, to prevent red from attacking at start. I guess that I could set a "neutral" status on start, then add a simple function to switch from "neutral" to "enemy" status when player 1 reaches a certain point. A big issue for me is that Atlas freezes when I select some "trigger" entities (point A, point B, etc.).

One other question is how are objects (entities) recognized on the map, is it by the <Entity uid="X"> as I think ? So what is the use of the <Actor seed="X"/> ? How can I find any entity uid on a map ?
I also can't find any help with a more complete list of functions useful for triggers. I know that all of this is still experimental, and there is no documentation. But I think my AI problem would be solved with a very simple script like :

set diplomacy player 2 status = neutral
if player 1 attack <Entity uid="X"> (let's say a tower for example) then set diplomacy player 2 status = enemy

Can anybody help me with the script syntax used in this game ?
Thanks.

Link to comment
Share on other sites

For triggers, you'd best start with reading this page: http://trac.wildfiregames.com/wiki/Triggers , and also take a look at the existing maps with triggers (like the trigger demo).

Then if you've been able to reproduce some basic triggers, you can look into creating the exact behaviour you want.

For the question on how to find entities. We've made it easy to find trigger points by their reference letter. And when you have that point location, you can look for entities a certain distance around it by using the range manager (which you can filter by class or component f.e.). So it should be quite easy to filter the "nearest CC to trigger point A", and then you can still easily edit the map by just making sure the CC and trigger point A are always close enough together.

Link to comment
Share on other sites

I've tried your first map, and without triggers it isn't a lot of fun indeed. Red and orange start a lot stronger than blue. This will be a very hard map to balance, even if you find a way to limit the powers of red and orange with triggers.

Another thing I noticed: you should watch the ownership of stuff. There are multiple fish, goats, chickens, ... that are owned by a player. And sometimes they give that player "vision" in enemy territory. It should be best if you can just make them gaia-owned.

Link to comment
Share on other sites

@sanderd17: Thank you for your help. Yes I already tried to review the trigger help page. But there are not enough example of function to solve my problem. But I finally found some js examples in the game directory. I think I can balance the game with triggers/scripts. But I am not good in js/coding and as I have to do it by myself, it will take some time. By the way, here is what I started to code, to give you an idea about what I have in mind to balance the scenario :

The idea is to set two other factions as neutral at start, to prevent any attack. If player one is able to reach and take the west dock in time, so help from player 3 will stop him to take the island. Then Player 3 will only ripost when beeing directly attacked (trigger not implemented yet).

But I have to face many issues. First, I have some errors while loading the scenario (message error about line 46, problem with JSON), I added

  "TriggerScripts": [
	"scripts/TriggerHelper.js",
	"scenarios/malta.js"
	]

In my .xml file, but the script doesn't seems to be loaded. Can you see any error ?

Secondly, there are some missing function to me in the examples, like a "timer" one. I'm using the var = timerdata to try to generate a timer and check for its value with other triggers, but I am not even sure I can do it this way. Do you have any other tips for this ?

About the ownership: you're right, I added these entities too fastly, without checking their ownership. I still don't know the use of a ownership of a goat in-game. But I now understand the gameplay problems it can generate. I'll review all of this and reattribute Gaia ownership for them. Thanks for noticing me!

Edited by AtlasMapper
  • Like 1
Link to comment
Share on other sites

You're always welcome on IRC to ask direct code questions: https://kiwiirc.com/client/irc.quakenet.org#0ad-dev

The first remark is that everything with

Trigger.prototype.xxx = function()

is just defining functions under a namespace (so they don't collide with other functions), but these functions don't get executed yet. As such, you should always define these at the top level of your file, and not inside other functions.

Secondly, you're missing something to boot your triggers. You can either listen to various messages (the ones defined in the reference table), or you can start them from the beginning. Take a look here: http://trac.wildfiregames.com/browser/ps/trunk/binaries/data/mods/public/maps/scenarios/treasure_islands.js#L99 The function "IntroductionMessage" is started after a delay of 2 seconds in the game (which gives the game enough time to render the first things). And you can use this delay trick for every next function. But f.e. the function "TreasureCollected" is only fired when there is an actual treasure collected (so triggered by some user action).

They also keep a certain state and count under the cmpTrigger variable (referred to as "this" for functions belonging to the Trigger prototype). The values you store under cmpTrigger are saved when you save a game, so you can load it again like you left it.

 

As for your problems, the part of the JSON you show is correct, but there's likely something wrong with the surrounding code. JSON fields need to be separated by commas, so if you add a new field (TriggerScripts), then you need to put a comma after the previous field.

About the ownership thing, the Gaia player exists to make no exception for a lot of code. F.e. the colour of the selection ring is derived from the player data, but if something doesn't have player data, it would be an exception. The owner can also send commands to the units. You can think that sending a command to a tree isn't very useful, but in the past, it has been very useful to change perspective to the gaia player, and send a delete command to some tree or other object that was blocking the AI (and a blocked AI could cause nasty lag).

 

For adding an icon, you could try by using our GUI code directly, but I'm not sure if it will work.

Link to comment
Share on other sites

@sanderd17: Again, thank you very much for taking some time to help me and share your knowledge. I think I now have all the indications to make my script working. It will take some time, surely, but it seems feasible now. I guess I'll figure out how to manage my timer problem by tries, as well as for the icon use.

Keep going with good help!

  • Like 1
Link to comment
Share on other sites

Things are going on. I can load my map with a script, most of the script is working (with simple things, I can display some messages after certain time, etc). I still have a problem with a specific trigger. I think is is easier to explain it here. I want to generate a trigger function when a dock is conquered. So I started with this :

cmpTrigger.RegisterTrigger("OnOwnershipChanged", "RipostCheck")
data = {
	"entity": 483,			// it's the dock entity uid 
	"from": 2,
	"to": 1,
  	};

But it doesn't seems to work, even if this is the right entity uid. So problem 1. Then when player 1 takes the dock, the following function is supposed to be triggered :

Spoiler

Trigger.prototype.RipostCheck = function(data)
{
	if (time < 60000)
	{	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
		cmpGUIInterface.PushNotification({
		"players": [1], 
		"message": markForTranslation("scenario message"),
		translateMessage: true
    		});
	}
	
	else
	{	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
		cmpGUIInterface.PushNotification({
		"players": [1], 
		"message": markForTranslation("another scenario message"),
		translateMessage: true
    		});
	};

 

So depending on the time the player needed to take the dock, two different messages or events could happen. What is the time variable ? It is supposed to be the amount of time from the start of the scenario. I tried to retrieve this value with the following function: Engine.GuiInterfaceCall("GetExtendedSimulationState").timeElapsed, but I don't know if I am really able to invoke such functions on a JS map file ? I tried with something like:

Trigger.prototype.CheckAttackTime = function(data)
{	var cmpGUIInterface = Engine.GuiInterfaceCall("GetExtendedSimulationState");
	var time = this.cmpGUIInterface.timeElapsed
};

But it doesn't works. How can I do it ? Can we invoke any game function in a map.js file ? Can we also directly retrieve some var values from the game ? Or is it necessary to create functions ?

Link to comment
Share on other sites

The data for the RegisterTrigger is just a boolean to enable (or not yet enable) the trigger. See the "accepted data" on the table of the triggers page. Only some special triggers require extra data.

And you also didn't put the data inside the function call.

 

So you have to make a trigger that listens to every ownership change (note that this also includes creation of new units, as they change from no owner to a valid owner). Then in that function do the checks you want based on the returned data (the data you have as function argument). That data will include the entity id (which you can compare with a hard-coded ID, or query other things from it). And also the from- and to-ownership.

 

In the function, it will also not know about a time variable. Perhaps it's better to only enable the trigger after a delay (so first execute a delay function, then register the capture trigger in that delay function). Or you can query the current time from cmpTimer. So something like

var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
cmpTimer.GetTime();

 

  • Like 1
Link to comment
Share on other sites

I have some pseudo code:

Trigger.prototype.RipostCheck = function(data)
{
	// Now every time some entity changes ownership, this function gets called
	// and you'll get an JS object 'data' with some variables inside, with the following lay-out:
	// 	{
    	//		"entity": entityId,
    	//		"from": playerId,
    	//		"to": playerId
  	//	}
	// What you need to do is to check whether the right entity is in the event, like this:
	
	if(data.entity == 483) && (data.from == 2) && (data.to == 1) {
		// do something
	}
};

cmpTrigger.RegisterTrigger("OnOwnershipChanged", "RipostCheck", {"enabled": true});

 

Edited by niektb
  • Like 1
Link to comment
Share on other sites

@sanderd17: Oh I see, I did think you can "filter" the trigger during the cmpTrigger call by imposing some option, or arguments (then impose my entity, from, to data..). I did believe that the OnOwnerShipChanged function could retrieve these informations during the trigger call and activate or not depending on arguments. That is what I interpreted from the Trigger Reference Table. I can get informations from the wiki trigger page, some other from JS lessons, but I still encounter some gaps between them. Some things on the wiki might be obvious for coders, but as I am a newbie there are some missing things.

So in your example, the value of the time will be attributed to the variable cmpTimer ? So if I am right, I should set up two functions, one that retrieve the time at start (with var = cmpStartTime), then one at the time of the attack (var = cmpAttackTime), then calculate the time for the attack in milliseconds var time = cmpAttackTime - cmpStartTime. The challenge is to register and call these functions in the right place of the script.

@niektb: Thanks, this illustration example is exactly what I needed to know how to manage the triggers. I wish there were such practical example in the trigger wiki page. It would really help newbies.

@niektb: There was actually a little syntax error in your condition test, the game refused to use it. This one worked:

if(data.entity == 483 && data.from == 2 && data.to == 1)

 

Edited by AtlasMapper
script syntax error
Link to comment
Share on other sites

cmp stands for "component". cmpTimer is a component that keeps track of the time, and you can also use it to register certain timing events. It's similar to cmpTrigger, which is a component that looks after the triggers, and fires them when some change is noticed. Both cmpTimer and cmpTrigger belong to the SYSTEM_ENTITY (and are some kind of global components), but most components actually belong to other entities (like units or buildings). For example: all units have a cmpIdentity component, that you can use to get their name, or their classes. Units that can attack also have a cmpAttack component, that stores that attack statistics and executes attacks (calculates the damage to the enemy). For these other components, you need to call them on the entity id instead of the SYSTEM_ENTITY.

To get data from the components, you usually have to execute functions on them. Like to get the time from the Timer component, you should use its GetTime() function ( http://trac.wildfiregames.com/browser/ps/trunk/binaries/data/mods/public/simulation/components/Timer.js#L17 ).

 

And the reason why the triggers don't offer many filters (and you have to filter it by yourself), is that we prefer to not have hard-coded id filters (directly referencing the entity id), but we prefer softer filters (your function gets the entity id, and can then, via cmpIdentity, query the classes or the name of the entity). The problem with directly referencing the entity id is that the entity id isn't as stable as you would like. F.e. when a unit promotes, it is actually replaced by a different entity (with a new id). Or if you create a skirmish map, the skirmish structures are replaced by civ-specific structures which all get a new id. But also if you save the map, the ids can change. So it's better to not use the ids directly in your script.

 

To see examples, it's best to look at the available triggers. Normally all *.js files in the scenario and skirmish directory are trigger scripts. So you can see how these are made and what the result in-game is.

 

Link to comment
Share on other sites

@sanderd17: One of the trouble I encounter is also to decipher the scripts/commands that are specific to 0ad (so belongs to the SYSTEM_ENTITY if I am right) from those that are a part of whole JS. And because 0ad Triggers are experimental, their uses or examples are unclear to me. I try to get some examples from all *.js files, but here are not many and some seems to be used differently. Moreover the getTime(); command is a regular JS command (I mean, you can use them in web pages or so), and then it is hard for me to know if I need to check the normal JS syntax and use this regular command, or use some special 0ad components to retrieve the time.

So the game cmp are triggered on scripts by calls. If I call a cmpTimer I don't need to calculate the difference from the start, from what I see in the Timer.js. If I understand well, your code will call for the Timer.prototype.GetTime 0ad component. What is the benefit of using a SYSTEM_ENTITY function over "normal" JS functions (I guess I could get the time with a regular var time = getTime(); ?) I mean, in my case, I just need to check just once the time spent in a function, not to keep the track of it.

Anyway so I can retrieve the time from the start by calling the cmpTimer on attack time :

var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
var AttackTime = {"enabled": true}
cmpTimer.GetTime(AttackTime);

or rather

AttackTime = cmpTimer.getTime();

 

Link to comment
Share on other sites

We can't use native time in JavaScript because clocks aren't synchronised. cmpTimer keeps track of the game time, and takes things into account like slower or faster play or pauses, or even saved games. And it is guaranteed to be the same for all players.

Btw, "getTime" isn't a native function in JS. You can use the Date object to retrieve the local computer time. But as said above, that will not by synchronised amongst players.

And you also use some strange terminology:

3 hours ago, AtlasMapper said:

So the game cmp are triggered on scripts by calls

The components aren't triggered, they are queried (or requested) by the engine call (Engine.QueryInterface)

3 hours ago, AtlasMapper said:

If I call a cmpTimer

You can call a method (or function) of a component (f.e. you can call cmpTimer.getTime() ), but calling a component is strange (and unclear) terminology.

3 hours ago, AtlasMapper said:

a SYSTEM_ENTITY function

That's not even a thing. There are components that belong to the system entity, and functions in those components.

Link to comment
Share on other sites

1 hour ago, sanderd17 said:

that will not by synchronised amongst players.

Oh I understand. I only play single player because of my lag/freeze problems. I understand its need now.

1 hour ago, sanderd17 said:

you also use some strange terminology

 

1 hour ago, sanderd17 said:

you also use some strange terminology

Haha yes sorry. Surely, you noticed that I am a newbie. Moreover, english is not my native language, so I might try to find expression unsuitable for what I try to say. So I used a wrong terminology. I'm sorry if it produced ambiguous ideas in my phrase, I was trying to explain the way I understand it. Next time I'll rather say "if I use a cmpTimer", "a SYSTEM_ENTITY stuff", "that cmp thing", etc, it will be less ambigous, and it will underline that I am doing it in an beginner and amatory way.

By the way, I gave up with the cmpTimer.GetTime(); stuff. I wasn't able to manage it the way I should, probably because I mix concepts when trying to understand how it should work. So I changed my strategy, and tried the other option you suggested previously

19 hours ago, sanderd17 said:

Perhaps it's better to only enable the trigger after a delay

I think it is much more complicated, because it requires more stuffs, and crossed things (sorry for my wrong terminology, I mean a stuff in a thing in another stuff) rather than a -to me - simpler condition check (the timer stuff). But in the end, it was possible to produce something from this strategy. I finally succeed in doing my trigger stuff (at least for my 2-players testing map).

Here is what I finally wrote and is working on my tests, if it could serve as an example to help other newbies by dealing with the trigger stuffs on maps (who knows ?).

Spoiler

//triggers state part-----------

//Introduction dialog
Trigger.prototype.FirstDialog = function(data)
{   
	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
	cmpGUIInterface.PushNotification({
	"players": [1], 
        "message": markForTranslation("Bla bla bla"),
        translateMessage: true
	});
};
//--

//Second dialog
Trigger.prototype.AthenAlertDialog = function(data)
{
	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
	cmpGUIInterface.PushNotification({
	"players": [1],
        "message": markForTranslation("Another bla bla"),
        translateMessage: true
	});
};
//--

//Diplomacy control
Trigger.prototype.DiplomacyNoAttack = function(data) {
	var cmpPlayer = TriggerHelper.GetPlayerComponent(2);	//for player 2
	cmpPlayer.SetNeutral(1);								//player one is neutral
	cmpPlayer.SetLockTeams(true);							//lock diplomacy

};

Trigger.prototype.DiplomacyAttack = function(data) {
		var cmpPlayer = TriggerHelper.GetPlayerComponent(2);	//for player 2
		cmpPlayer.SetEnemy(1);									//player 1 is enemy
		cmpPlayer.SetLockTeams(true);	

};
//--


//Registers/Activates triggers depending on the time of the dock attack
Trigger.prototype.FastAttack = function(data)
{
	var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
	cmpTrigger.RegisterTrigger("OnOwnershipChanged", "NoCounter", data);
	cmpTrigger.EnableTrigger("OnOwnershipChanged", "NoCounter", data);
};

Trigger.prototype.SlowAttack = function(data)
{
	var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
	cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CounterAttack", data);
	cmpTrigger.EnableTrigger("OnOwnershipChanged", "CounterAttack", data);
	cmpTrigger.DisableTrigger("OnOwnershipChanged", "NoCounter", data);
};
//--


//Dock script
Trigger.prototype.NoCounter = function(data)
{
	if (data.entity == 487 && data.from == 2 && data.to == 1)

	{	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
		cmpGUIInterface.PushNotification({
		"players": [1], 
		"message": markForTranslation("More bla bla bla (don't want to spoil the scenario yet)"),
		translateMessage: true
		});
	}
};

Trigger.prototype.CounterAttack = function(data)
{
	if (data.entity == 487 && data.from == 2 && data.to == 1)
	
	{	var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
		cmpGUIInterface.PushNotification({
		"players": [1], 
		"message": markForTranslation("Yet another bla bla (still no spoilers here)"),
		translateMessage: true
    	});

		var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 
		cmpTrigger.DoAfterDelay(0, "DiplomacyAttack", {});
		
	};
};
//--

//Inducing events from start------------
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 
var data = {"enabled": true}

cmpTrigger.DoAfterDelay(0, "DiplomacyNoAttack", {});
cmpTrigger.DoAfterDelay(0, "FastAttack", {});
cmpTrigger.DoAfterDelay(60000, "SlowAttack", {});
cmpTrigger.DoAfterDelay(2000, "FirstDialog", {});
cmpTrigger.DoAfterDelay(30000, "AthenAlertDialog", {});

 

My goal wasn't to waste your time in any way. I appreciate your help with all of this. I couldn't succeed without you. I think that examples are much better that explanations, that's why I also post my stuff here. I know there are some examples.js on the site, but there are not much, and they don't cover all the simples concepts needed to understand how it works, in my opinion. I also know the trigger stuff is quite new and is still an ongoing work and experimental. By the way, I think it is always a good think that you understand how people that are complete strangers of your game/script/system could deal with it. It might help you to improve it by seeing what is accessible and what is complicated (if you plan to improve the system).

There are lots of way to improve my trigger stuff here, especially in a visual way. For example, that would be nice to have a window with a "ok" button to display the "scenario" messages, (and putting the game in pause mode when displayed) especially because it would let the user close the text when read. But I wasn't able to find any examples on how to use them (if any exists). That would be also very nice if we could easily link a unit icon from the GUI inside the message windows, to illustrate easily and quickly who is talking in the message.

Now I have to adapt my trigger stuff on my 3-player scenario (that shouldn't be long, but requires some testing) but I am not really in a hurry, as I still can't play this game in multi. Actually, the game even freeze in 1 player mode sometimes, but whatever. I reported this, but I am no more expecting this issue to be solved (it is not considered as an issue, just a personal defect of hardware).

Again guys, thanks for your help, especially sanderd17 for so much patience and knowledge sharing!

Keep going with good work.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...