FreeOrion

Forums for the FreeOrion project
It is currently Sat May 26, 2018 12:14 pm

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Feb 06, 2018 7:54 pm 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
I come in piece!

So i'm stuck with the custom Sitreps and just can't get this thing to work.
I want to check my fleets for their health percent to see if i should send them back or can push my luck.


So here is my first Sitrep i made to show planets i have in my territory and i could build a colony at.
Thats pretty much where my progress is with ships, i can show one of their stats as "rawtext", like Target.Structure or Target.MaxStructure.

Code:
EffectsGroup
     scope = And [
         Planet
         Not Species
       Not Planet Type = GasGiant
       Not Enqueued
       Ownedby empire = Source.Owner
                 VisibleToEmpire empire = Source.Owner
     ]
     activation = Source
     effects =
         GenerateSitRepMessage
             message = "The planet %planet% is without colony."
             label = "Missing_Colony"
             NoStringtableLookup
             icon = "icons/planet/terran.png"
             parameters = [
                tag = "planet" data = Target.ID
             ]
             empire = Source.Owner


But fleets are more complicated as i understand they are containers with ships inside and i just can't make the conection to get the ship info out.


The commented parts are old trial and error.
Code:
EffectsGroup
   scope = And [
      Fleet
      OwnedBy empire = Source.Owner
      //Contains Ship low = 2
   ]
   activation = Source
   effects =
         GenerateSitRepMessage
             message = "The ship is at %rawtext% percent."
             label = "Fleet_Detail"
             NoStringtableLookup
             icon = "icons/planet/gasgiant.png"
             parameters = [
                                //tag = "rawtext" data = ((Target.Structure / Target.MaxStructure)*100)
            //tag = "rawtext" data = Sum value = ((LocalCandidate.Structure / LocalCandidate.MaxStructure)*100) condition = Ship
            //tag = "rawtext" data = LocalCandidate.Structure
            tag = "rawtext" data = Sum value = LocalCandidate.Structure
             ]
             empire = Source.Owner


The part with:
Code:
tag = "rawtext" data = ((Target.Structure / Target.MaxStructure)*100)

works perfect for single ships but it will spam the Sitrep :(

What i want to achive is a Sitrep like:

"The fleet %fleet% at system %system% is at %rawtext% percent health"

Could someone please help me out?


Top
 Profile  
 
PostPosted: Tue Feb 06, 2018 8:42 pm 
Offline
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12195
Location: Munich
You probably want to sum before dividing, and you probably want to add something in the condition to select only ships within the fleet that is the target of the effect... Not tested, but something like...
Code:
data = 100 * (Sum value = LocalCandidate.Structure condition = ContainedBy Target) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy Target)


Top
 Profile  
 
PostPosted: Tue Feb 06, 2018 9:08 pm 
Offline
AI Lead, Programmer
User avatar

Joined: Sat Sep 22, 2012 6:25 pm
Posts: 4613
Ah, while i was typing and doublechecking things Geoff already posted a more succinct message with the main suggestion, but I have a bit more advice, so here it is anyways...

Well, what you are trying to do does sound a bit tricky, but here are a few tips/suggestions.

* I am pretty sure that LocalCandidate only has meaning within a Condition (at least, that's what our scripting details page says), so that's why some of those commented-out sitrep messages didn't work for you.

* the only way to avoid being spammed by such things is to have a more restrictive scope, right now you will always get a sitrep for every fleet you own. I suggest picking some cutoff percentage, like 30% of maxHealth or whatever, and then instead of the "Contains Ship low 2" line, using a statistic, something like the following might work
Code:
((Sum value = LocalCandidate.Structure condition = ContainedBy RootCandidate) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy RootCandidate) < 0.30)


And then a very similar form of statistic, referencing Target instead of RootCandidate, might possibly work for you in the message

Code:
tag = "rawtext" data = 100*((Sum value = LocalCandidate.Structure condition = ContainedBy Target) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy Target))

_________________
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 10:30 am 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
Thanks for trying to help!

But sadly none does work.

Code:
tag = "rawtext" data = 100 * (Sum value = LocalCandidate.Structure condition = ContainedBy Target) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy Target)

Does not produce any Sitrep output or message with ERROR in it (yes i have them activated in options)

Code:
tag = "rawtext" data = ((Sum value = LocalCandidate.Structure condition = ContainedBy RootCandidate) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy RootCandidate) < 0.99)

Same, no output. (i replaced 0.3 with 0.99 for testing purpose, i have a damaged fleet)

Code:
tag = "rawtext" data = 100*((Sum value = LocalCandidate.Structure condition = ContainedBy Target) / (Sum value = LocalCandidate.MaxStructure condition = ContainedBy Target))

Same, no output

Because there is no ERROR or any output i fear that the Sitrep is blocked by the engine because it might be "cheating".
I don't know how much info is accessable from custom Sitreps and the Wiki names specific variables like "rawtext", "system", "planet" etc.

The problem in the first place is that the variables for Fleet.Structure and Fleet.MaxStructure are not used/set correctly by the engine(i think).

Code:
tag = "rawtext" data = Target.Structure

output is 0.00 for every fleet

Code:
tag = "rawtext" data = Target.MaxStructure

output is 0.00 for every fleet
If i do both for Scope = Ship then i get the correct ship values.

In the Combat Report after a fight you can clearly see the "current structure / structure before fight" below the health bars.
Its even named "fleet health".

How does the UI access the Fleet.Structure? Does it count every ships current structure every time i click on a different fleet?
Code:
tag = "rawtext" data = Target.NumShips

Will output exact number of ships in fleet, 1 for single ship "fleet"

Maybe the solution is to change the hardcoded unused Fleet.Structure and Fleet.MaxStructure.
Then we could just do

Code:
EffectsGroup
   scope = And [
      Fleet
      OwnedBy empire = Source.Owner
      
   ]
   activation = Source
   effects =
         GenerateSitRepMessage
             message = "At %system% the fleet is at %rawtext% percent."
             label = "Fleet_Detail"
             NoStringtableLookup
             icon = "icons/planet/gasgiant.png"
             parameters = [
                              tag = "system" data = Target.SystemID
                              tag = "rawtext" data = ((Target.Structure / Target.MaxStructure)*100)            
          ]
             empire = Source.Owner


Which would also use less processing power.


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 11:08 am 
Offline
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12195
Location: Munich
Klaus wrote:
The problem in the first place is that the variables for Fleet.Structure and Fleet.MaxStructure are not used/set correctly by the engine(i think).
They are not valid values. Fleets don't have structure or max structure meters. The ships they contain do, but not the fleets themselves.
Quote:
How does the UI access the Fleet.Structure? Does it count every ships current structure every time i click on a different fleet?
Yes: https://github.com/freeorion/freeorion/ ... .cpp#L1596
Quote:
Does not produce any Sitrep output or message with ERROR in it (yes i have them activated in options)
There could be a parser error that prevents the effect from running at all. Check earlier in the logs for relevant error output.


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 11:36 am 
Offline
Vacuum Dragon
User avatar

Joined: Mon Apr 10, 2017 4:25 pm
Posts: 529
You could rethink the sitrep as aimed at ships instead of fleets, so that you get one sitrep for each ship (alone or within a fleet) with structure under X%. Or ideally only once, when the ship's structure crosses that threshold downwards. It would be spammer than sitreps for whole fleets but also be more informative (it's not the same a fleet of 5 ships at 100% HP and 5 ships at 2% HP than a fleet of 10 ships at 51%, but both fleets have an average structure of 51%).


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 12:43 pm 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
@Geoff the Medio

Thanks for clarification and link, will check that out.

@Oberlus

That kinda was my first idea, to do it with ships. But i canceled it because of the spam. And did not think of a way to limit the output.
I was hoping to get some elegant solution :wink:

I think because of the limitations and current problems i should try to go with ships again.
And do something like:
"At %system% the %ship% is at %rawtext% percent and needs repair."

or

"The captain of %ship% in %system% complains about poor work conditions. Structure at %rawtext% percent." :twisted:


Edit:
So here is my current progress with it

Code:
EffectsGroup
   scope = And [
      Ship
      OwnedBy empire = Source.Owner
      Structure high = (LocalCandidate.MaxStructure * 0.25)  // structure below 25%
   ]
   activation = Source
   effects =
         GenerateSitRepMessage
            message = "At %system%: the captain of %ship% complains about poor work conditions. Structure at %rawtext% percent."
            label = "Ship_Poor_Condition"
            NoStringtableLookup
            icon = "icons/sitrep/riot.png"
            parameters = [
              tag = "system" data = Target.SystemID
              tag = "rawtext" data = ((Target.Structure / Target.MaxStructure)*100)
              tag = "ship" data = Target.ID
            
          ]
             empire = Source.Owner




Thanks everyone for the tips!

If anyone finds out how to do it for fleets please post a solution.

Cheers


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 1:52 pm 
Offline
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12195
Location: Munich
If you're going to refer to the system in the sitrep, you should probably ensure that the fleet / ship is in a system in the scope.


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 4:20 pm 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
How can a fleet no be in a system?

Is deep space not a "system" or is it lane travel?

What would the check look like? Should i check for stationary?


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 5:28 pm 
Offline
Vacuum Dragon
User avatar

Joined: Mon Apr 10, 2017 4:25 pm
Posts: 529
Klaus wrote:
is it lane travel?
Right, a fleet can be traveling between two systems (either named, if there is a star in it, or unnamed, if it's a "deep space" system).

If it is possible, the sitrep could appear only the turn after the fleet/ship has participated in a combat. This way you get only once for each ship and only for ships that were actually in a system (otherwise they couln't participate in any combat).

No idea how to make those checks, though.


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 6:11 pm 
Offline
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12195
Location: Munich
Klaus wrote:
What would the check look like?
Code:
InSystem


Top
 Profile  
 
PostPosted: Wed Feb 07, 2018 10:51 pm 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
Oh that looks easy, thanks.


Top
 Profile  
 
PostPosted: Thu Feb 08, 2018 2:36 pm 
Offline
Krill Swarm

Joined: Tue Feb 06, 2018 7:22 pm
Posts: 10
I tried to work with fleets again but i just can't get anywhere.
I just don't know enough about syntax and whats possible or not.

Because extracting info about every ship in "GenerateSitRepMessage" is not possible i want to do it in the scope.
Which worked fine for single ship info.

First try:

Code:
scope = And [
      Fleet
      OwnedBy empire = Source.Owner
      Number high = (LocalCandidate.NumShips * 0.66) condition = And [   // LocalCandidate should be Fleet
         Ship
         ContainedBy RootCandidate                                                 //RootCandidate should be Fleet
         Structure high = (LocalCandidate.MaxStructure * 0.30)           // LocalCandidate should now refer to Ship
         
      ]
]


Idea is to count at least 66% of fleets ship which are bad damaged with < 30% structure.
But the parser already complains about first high not a real number.
Which is pretty much true for all my expression i try to do (lack of knowledge and examples to know whats possible or not)


Next try:

Code:
If condition = And [
         If value = (Sum value = LocalCandidate.Structure condition = ContainedBy RootCandidate) condition = high = ((Sum value = LocalCandidate.MaxStructure condition = ContainedBy RootCandidate) * 0.3)
      ]


Here i want to know if sum of current structure is below 30% of max structure.
I use the outer If to work with LocalCandidate and RootCandidate, without it i think RootCandidate would refer to Source.
I also don't know if "condition = high = ((Sum value = etc." is alowed or not, cause i have not seen this or similar done anywhere yet.


Btw i use
http://www.freeorion.org/index.php/FOCS ... ng_Details
and
http://www.freeorion.org/index.php/FOCS ... g_Tutorial

but there are just not enough examples for practical use.

For example Sum

Code:
Sum                - Returns the sum of property values of objects that match the selection condition
Example
Sum value = LocalCandidate.Population condition = Planet


But there is no complicated use of it or how its used in other code
So is "If value = (Sum...) condition = high = <some number>" valid code or not.

The most frequent parser error i get is "]" expected to close the scope, which tells me basicly not enough.


Top
 Profile  
 
PostPosted: Thu Feb 08, 2018 4:26 pm 
Offline
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12195
Location: Munich
Klaus wrote:
So is "If value = (Sum...) condition = high = <some number>" valid code or not.
It is not a valid expression. I'm not sure what you're trying to do, but maybe:
Code:
condition = ((Sum value = etc.) <= number)
for the condition. I don't know what "If value = (Sum...)" is supposed to be... If you're trying to calculate something, you could use
Code:
Statistic If condition = (LocalCandidate.Structure < LocalCandidate.MaxStructure)
which evaluates to 0 or 1 depending on the condition matching something or not.

Quote:
Here i want to know if sum of current structure is below 30% of max structure.
For that, your expression
Code:
Structure high = (LocalCandidate.MaxStructure * 0.30)
should be fine...

The Number condition might be expecting an integer, not a real-valued number. Might work to use
Code:
LocalCandidate.NumShips * 2 / 3


I suggest starting with a working script and making it more complicated in small steps, rather than trying to jump to a final complicated script. Try inner conditions as an activation or scope condition first, to make sure it works or at least parses outside the context of a larger more complicated expression.


Top
 Profile  
 
PostPosted: Thu Feb 08, 2018 4:32 pm 
Offline
AI Lead, Programmer
User avatar

Joined: Sat Sep 22, 2012 6:25 pm
Posts: 4613
Klaus wrote:
I use the outer If to work with LocalCandidate and RootCandidate, without it i think RootCandidate would refer to Source.
RootCandidate does not necessarily refer to Source (except following a top-level Source condition, in which case you simply have filtered out all other candidates). Wrapping in some extra condition, like "If", will not change what RootCandidate refers to. It looks like you are talking about using that in a Scope clause, in which case RootCandidate refers to the current object being considered for falling within the Scope.

Quote:
I also don't know if "condition = high = ((Sum value = etc." is alowed or not, cause i have not seen this or similar done anywhere yet.
"High" is not a Condition, it is a keyword used by various conditions, so "No", I don't think that would work.

Quote:
I'll acknowledge that these pages could certainly still be improved, but filling them with lots of complex examples is not the way to do that, I think. These are meant to be syntax specifications and explanations, with some examples just as illustrations. Look to the actual scripting content for more complex examples.

Quote:
For example Sum... But there is no complicated use of it or how its used in other code
There are actual uses of it to refer to as examples, in default/scripting/empire_statistics/MILITARY_STRENGTH.focs.txt, PP_OUTPUT.focs.txt, and RP_OUTPUT.focs.txt

The way all our scripting is broken into little files now does make it more difficult to locate such examples. grep is a great command line tool for doing so (I suppose windows explorer can do content searches also, but I find it to be slow). In MacOsX or in Linux you can run grep from any command line, in Windows I think it is not part of the normal command set but you can use it from a Git Bash command line. The line I used to find the above examples (with the "default" directory as my current directory) was
Code:
grep -Rin "sum value" scripting
and the results were
Code:
scripting/empire_statistics/MILITARY_STRENGTH.focs.txt:2:    Statistic Sum value = (LocalCandidate.Attack * (LocalCandidate.Structure + 2 * LocalCandidate.MaxShield))
scripting/empire_statistics/PP_OUTPUT.focs.txt:2:    Statistic Sum value = LocalCandidate.Industry condition = And [
scripting/empire_statistics/RP_OUTPUT.focs.txt:2:    Statistic Sum value = LocalCandidate.Research condition = And [


Quote:
So is "If value = (Sum...) condition = high = <some number>" valid code or not.
Examples are not the way to know if some new script like this could work, because no set of examples can be fully complete. You have to think more about the specifications, and at least for this particular example the help pages are pretty clear that it would not work.

Quote:
The most frequent parser error i get is "]" expected to close the scope, which tells me basicly not enough.
What editor are you using to work on these files? Not all editors will automatically highlight matching parentheses and brackets, you'll want one that does. On Windows, Notepad++ (not the plain Notepad that comes with Windows) is probably your best choice. That will help you see where your bracket clauses are terminated (or not).

_________________
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group