BTS Unaltered Gameplay Project

Status
Not open for further replies.
I did indeed mean BtS Events / Quests (just hadn't had quest yet so didn't know if those were logged). Assumed it was implemented as it was available in the options :)

It's not logging wonders BIDL either, but it has never done that so just put that down to feature req list.
 
I wrote up the instructions in this post. Make sure you have the correct URL.

https://civ4bug.svn.sourceforge.net/svnroot/civ4bug/BUG Mod

You should be able to paste that URL into your browser and see the source tree: BUG Documentation, CustomAssets, BUG Mod.ini.

Ket was getting that exact same error, and his problem was that he had a malformed URL. The visible text link above (and in the instructions) is truncated with "..." in the middle by the forum, so make sure to right-click the link and select "Copy Link Location". Or you can go to the SF.net page (see my sig) and grab the URL from there.

Cheers! The link was simply incorrect :)
 
I can't find any events relating to Events and Quests in CvEventManager. They all seem to be custom-coded in CvRandomEventInterface, and hooking into each of the 100+ functions to log them will not be fun. If someone wants to tackle it, make sure you try it out with a few events first. I don't know how you can trigger the events to test the logging, however.

In any case, I removed the option for now and added "Corporations" in its place (below "Religions"). This new option logs the same things as Religions (foundind, spread and remove).

I added a note to log nukes in the future, but I didn't add the option or code yet. Do SGers really want this? I only ask because it's an event in CvEventManager that could be captured easily enough. It would also be good to capture the building of the Manhattan Project under the same option, but then it would be double-logged if you have Buildings Built (includes Projects I think) logging enabled.

It's in SVN. Let me know if you have any problems with it.
 
Triggering events can be done by calling <player>.trigger(). In debug console you can do this by gc.getPlayer(0).trigger(<event#>). Assuming you have default event xml files, #66 is Master Bowyer [ gc.getPlayer(0),trigger(66) ]. When triggering events from debug console, most normal limits do not apply, which means that you can triggger events before the first 20 turns have passed and you can trigger them without having prerequisite technologies, so you can trigger that Master Bowyer event on the first turn already (making it one of the events nice for debugging - there's nothing to prevent the event from happening when triggered).


How do the lines appear to log on screen? They aren't all some kind of information structures (well it's python so objects) containing whatever structured information is available and the log text (or methods to fetch all that)? I had assumed that was the case, as it seems natural to have single interface for log line processing. With that assumption in mind I had thought of asking for option to log "raw" event text lines (all events the user gets that aren't processed by autologger would be logged eg. with RAW prefix), but by your description it seems this simply isn't possible.
 
Hi.

I posted an idea/request for a mod in another thread but I was referred to this thread and told that you were looking for ideas. So, here's the exact same message:

You know how you can rename your units in the game? I was wondering if it was possible to somehow make it so that the units you create are automatically named depending on your civilization. I think this would make the game a lot more fun as your armies and even workers would have a bit of character. Maybe your generals could develop titles as they gained more experience (e.g. "the Mighty" or "<opponentcivname>-Bane")

As you can probably tell, I don't know anything about scripting or even modding really, but I was wondering if somebody could figure out a way to make it possible. I would be more than happy then to provide native names for all the different civs.

Original thread: http://forums.civfanatics.com/showthread.php?t=239285
 
You know how you can rename your units in the game? I was wondering if it was possible to somehow make it so that the units you create are automatically named depending on your civilization. I think this would make the game a lot more fun as your armies and even workers would have a bit of character. Maybe your generals could develop titles as they gained more experience (e.g. "the Mighty" or "<opponentcivname>-Bane")
Thx yenemus ... I am currently working on the unit naming engine. Most of what you have described above is already planned.
 
Triggering events can be done by calling <player>.trigger().

Thanks, that will really help for testing!

How do the lines appear to log on screen?

As far as I can tell, all of the normal messages that the user sees are generated from the C++ code. All of the Python events are "extra hooks" that allow the modder to do something in addition to -- and maybe even instead of -- the normal behavior. All of the hooks in Python (CvEventManager) are empty, however.

The events and quests file CvRandomEventInterface seems to only be support Python code for those events that require more information -- counting or finding applicable plots for example. The Master Bowyer event/quest isn't in the file anywhere, which makes sense since you said it has no requirements.

Finally, all the messages that are displayed to the player go through CyInterface.addMessage(), which I cannot find in the DLL source. It likely lives in the EXE and thus isn't hookable. I'd love to be wrong on that, however.
 
I added coloring of mission costs on the Espionage Screen. Missions that you can perform right now (you have enough EPs) are drawn with a color of your choice (green by default). Missions that you are "close" to being able to perform are drawn with another color (cyan by default).

"Close" is defined using a percent that you choose (5% by default). You are close if your EPs are less than that percent away from the mission's cost.

As there are a lot of options for this screen now, I moved them to a new class (BugEspionageOptions) and -- more importantly for the user -- moved their settings to a new INI section (Better Espionage) and shortened their names. Make sure when you update to grab the new INI file.

If you want to preserve your current INI settings, you can attempt a merge. Remove all of the espionage-related settings from the [Screens] section (all but two options) and then copy the new [Better Espionage] section.
 
Since you opened this can of worms ...

Spoiler full text of post :
, here is what I was going to originally suggest. You may be familiar with how Python (and C) allow you to insert variables into strings: "%d" for a number, "%s" for a string, etc. So for example you would do

Code:
str = "It is %d:%d on %s" %(hour, minute, day)

You could do something similar for the naming. Define codes that are replaced in a string the user types.

  • %u: Unit (Archer)
  • %t: Type (Melee)
  • %d: Domain (Water)
  • %c: City
  • %C: Civilization
  • %l: Leader
  • %n: Unit Number (1)
  • %r: Unit Number - Roman (I)
  • %o: Unit Number - Ordinal (1st)
  • %N: Total Number of Units (4)
  • %R: Total - Roman (IV)
  • %O: Total - Ordinal (4th)
The Roman and Ordinal versions of "Total Number of Units" might not make much sense (1 of 4th? no, 1st of 4). Doing this is actually not very difficult -- no harder than what you're planning -- and is more flexible. It would allow the user to then create a format string like this:

  • %o brave %u of %C from %c
  • %u %r of %R [%c]
  • %C's %o %u
  • %l's %u %n/%N
for

  • 2nd brave Warrior of England from London
  • Archer II of IV [Moscow]
  • America's 4th Marine
  • Isabella's Tank 3/8
Let me know if you're interested in this. If so, I could help out (as much or as little as you'd like) with the code to generate the strings.

You already will need code to generate the individual pieces. The only difference is that instead of checking for options, you're using string.replace() a bunch of times. For example:

Code:
name = BugOpt.getNameFormat()
name = name.replace("%u", gc.getUnitInfo(unit.getUnitType()).getDescription())
name = name.replace("%d", gc.getDomainInfo(unit.getDomainType()).getDescription())
...
Naming Engine Update. I've been thinking about this and subsequent posts and I think that we can collapse ALL of our proposed naming conventions down into something similar to EF's code above.

  • %ct: City
  • %cv: Civilization
  • %cu[n]: count units (increments based on unit)
  • %cc[n]: count combat type (increments based on combat type)
  • %cd[n]: count domain (increments based on domain)
  • %TT[n][x:y]: total where the total is a random number between x and y (number)
  • %TC[n][x]: total count (starts at x, incremented by 1 each time %TT is reset to 1)
  • %R: random name
  • %RCv: random civ related name
  • %U: unit (eg Archer)
  • %t: combat type (Melee)
  • %d: domain (Water)
  • %CL: Civilization
  • %LD: Leader

where [n] can be either 's', 'a', 'p', 'g', 'n', 'o' or 'r' for silent (not shown), alpha (A, B, C, D, ...), phonetic (alpha, bravo, charlie, delta, echo, ...), greek (alpha, beta, ?, delta, epsilon, ...), number, ordinal or roman.

'Silent' would enable you to have names like this ...

Attack Squad Alpha, 101st Division
Attack Squad Bravo, 101st Division
Attack Squad Charlie, 101st Division
Attack Squad Delta, 101st Division
Attack Squad Alpha, 102nd Division
Attack Squad Bravo, 102nd Division
Attack Squad Charlie, 102nd Division
Attack Squad Delta, 102nd Division

by using a naming convention of "Attach Squad %cc[p]%TT[4:4], %TC[o][101] Division"

If we use this set up, then there is only 1 huge naming engine that just has to be able to parse the user defined string that drives the unit name.

Examples

"%U %cu[a] %ct Garrison" ==> "Archer C Moscow Garrison"
"%cu[n] of %TT[n][6:10], unimatrix %CT" ===> "4 of 8, unimatrix 4"
"%cc[o] %CL %u" ==> "3rd Persian Sword", "4th Persian Axe", etc
 
@Ruff - That looks pretty good. I've got a couple comments, but all-in-all it captures the features you wanted from the start.

Minor ones first. You have "Civilization" twice: "%cv" and "%CL". You represent "combat type" as "%t" and "%cc" -- perhaps change the latter to "%ct" for consistency. As well, do you need uppercase for some of them? I had uppercase ones to distinguish when two codes did the same thing at different levels (current and total), but I can't figure out why some are uppercase here.

The big question is are you sacrificing ease-of-use for a corner case? I know you like the Borg naming (and I agree it's cool), but it seems like all the codes become much more complex to handle this one naming scheme. I do see that one of your other examples is enabled by this (the Attack Squads), but I fear that it's a lot of work and difficulty (for you to build and the user to understand) that few will benefit from.

I could be way off because I'm not the target audience (I don't use it). I think I would use it if the numbers grouped units by city or something, but your divisions will be grouped by time, not location or type. So the 108th division won't be armored, it will have infantry, tanks, a battleship, two planes and a worker, and be spread across your empire.

In any case, I'm not trying to dissuade you, so please don't take it as that. It'll be fun to play with what you make. I might just start naming my units.

"EF's mailed fist of death 3rd of 6" :D
 
Minor ones first. You have "Civilization" twice: "%cv" and "%CL". You represent "combat type" as "%t" and "%cc" -- perhaps change the latter to "%ct" for consistency. As well, do you need uppercase for some of them? I had uppercase ones to distinguish when two codes did the same thing at different levels (current and total), but I can't figure out why some are uppercase here.
Good points - I should tidy that up ...

  • %n% - no naming convention, uses standard civ4
  • %ct% - City
  • %v% - Civilization
  • %c[n]% - count across all units (increments based on unit)
  • %cu[n]% - count across same unit (increments based on unit)
  • %cc[n]% - count across same combat type (increments based on combat type)
  • %cd[n]% - count across same domain (increments based on domain)
  • %tt[n][x:y]% - total where the total is a random number between x and y (number)
  • %tc[n][x]% - total count (starts at x, incremented by 1 each time %tt is reset to 1)
  • %r% - random name
  • %rc% - random civ related name
  • %u% - unit (eg Archer)
  • %t% - combat type (Melee)
  • %d% - domain (Water)
  • %l% - leader

Using %n%, %r% or %rc% in your naming conventions results in standard civ4, random or random civ related names being generated and other items being ignored.

The big question is are you sacrificing ease-of-use for a corner case? I know you like the Borg naming (and I agree it's cool), but it seems like all the codes become much more complex to handle this one naming scheme. I do see that one of your other examples is enabled by this (the Attack Squads), but I fear that it's a lot of work and difficulty (for you to build and the user to understand) that few will benefit from.
Maybe. I think that if I put in enough examples, people will get the idea. The coding might be tricky but it will depend on if python has string manipulation commands (instr?, mid?, etc).

I could be way off because I'm not the target audience (I don't use it). I think I would use it if the numbers grouped units by city or something, but your divisions will be grouped by time, not location or type. So the 108th division won't be armored, it will have infantry, tanks, a battleship, two planes and a worker, and be spread across your empire.
Yes, the 108th Division could look like that if you use the same naming convention for your whole empire, but if you have one that is only used across a single unit (ie tanks), then it will be full of tanks. But if you use it across a single combat type (melee), then it will be full of axes, swords, spears, etc.

Oh, one other thing ... the naming engine that I was lifting the code from included the ability to name barbarian and AI units. I am not going to include this as it could be spoiler information. Imagine the situation when you put in an AI naming convention of "%u% %cu[n]%" and come across "Longbow 321". This would tell you that there are 320 other longbows out there that you have to kill.
 
OK, so log doesn't have unified python interface and thus autolog has to hook separatelly to events or event types to be logged as hooks are available. A bit annoying, probably unexpected mod then :)

And regarding triggering BtS events: what you're triggering with that method is Event Trigger (Civ4EventTriggerInfos.xml). You can find the number of any event trigger with getInfoTypeForString (eg. gc.getInfoTypeForString("EVENTTRIGGER_BOWYER") returns 66 with default xml files). These events may specify functions they call (eg. additional checks for triggering event, or additional function for adding event effect), but most of the events are done with just XML - standard event system is quite flexible.

Based on the above, I'd expect events to come to be hookable via single interface from python. One issue may be that event triggers and events may have different hooks, and it might be possible to only hook to a single event with single python call instead of hooking to all. As event triggers (and events separatelly) are likely to be numbered arrays, hooking to event (or event trigger) probably happens by call to a function with event number as parameter. It just might be possible to hook to all events by simply looping through event number range - although I'm not sure how to get list of all event numbers or highest of them... maybe loop until error is returned assuming no more events then :)
 
One thing that I had in my cobbled mod on the option screen was a tab full of credits. I think that we should put such a tab in our option screen.
 
One thing that I had in my cobbled mod on the option screen was a tab full of credits. I think that we should put such a tab in our option screen.

100% agreed -- it's on my growing list of TODOs. :)

I've been holding off while trying to think of an easy way to make it extensible. My first thought is to place them in the Options modules so each one can add as many credits as it needs.

Code:
self.addCredit("Dr. Elmer Jiggles", "Civ4lerts")

Then the tab would just gather them all and place on the screen. The key is that I was hoping to categorize the data. In the example above, you can see that the person's name is separate from the thing they built. This allows another options module to do

Code:
self.addCredit("Dr. Elmer Jiggles", "Custom Event Manager")

This would allow the credits tab to group projects by person and show them on a single line. I stopped there but have a gut feeling once I do that I'll want more control, like being able to show where projects have been modified, added-to, or continued by another person.

For example, I don't deserve as much credit for an included mod as the author does if I've merely tinkered with it slightly. Same for someone who has taken stewardship of a modcomp or just ported it to BtS. Does this matter? Am I picking nits?

The other way is to do it as you did: one list of credits where we have total control over how it is written and presented. This possibly makes it harder for other teams to extend but gives them total control.
 
Maybe. I think that if I put in enough examples, people will get the idea. The coding might be tricky but it will depend on if python has string manipulation commands (instr?, mid?, etc).

Probably true. That looks great. Yes, Python has all the string manipulation you'll ever need. Things to make sure you address are detecting when the formats have changed (user changed options) and allowing the user to reset counts (maybe).

Yes, the 108th Division could look like that if you use the same naming convention for your whole empire, but if you have one that is only used across a single unit (ie tanks), then it will be full of tanks. But if you use it across a single combat type (melee), then it will be full of axes, swords, spears, etc.

I forgot about this part, very cool. How will the user set this up?

Oh, one other thing ... the naming engine that I was lifting the code from included the ability to name barbarian and AI units. I am not going to include this as it could be spoiler information.

Yup, good call.
 
@Elandal - Looking at the XML and Python files, here's what I can see.

CIV4EventTriggerInfos.xml can point to four Pythong functions. Some use the first, none use the other three.

  1. PythonCanDo
  2. PythonCanDoCity
  3. PythonCanDoUnit
  4. PythonCallback
Each trigger points to one or more events that it triggers using <Events> and <Event> elements.

CIV4EventTriggerInfos.xml holds the events and quests. Like triggers, they have Python callbacks.

  1. PythonCallback
  2. PythonExpireCheck
  3. PythonCanDo
  4. PythonHelp
All four callbacks seem to be used by various events. A cursory scan reveals that no single event uses all four callbacks, but that's hardly exciting. Most don't have any callbacks.

For example, the mining event has a single trigger and three events it points to -- the three options you can choose from. None of these use any Python; they're all handled by C++ code.

CvRandomEventsInterface is the module that holds the Python callbacks specified in the two XML files.

Finally, CvEventManager has nothing related to events or quests that I can see. When a city is renamed, a war is declared, a unit killed, etc. a function in EvtMgr is called with the information. Nothing like this seems to be done when events or quests are triggered. :(

I searched the C++ DLL code and didn't find anything that would help.
 
Yes, the 108th Division could look like that if you use the same naming convention for your whole empire, but if you have one that is only used across a single unit (ie tanks), then it will be full of tanks. But if you use it across a single combat type (melee), then it will be full of axes, swords, spears, etc.


What I have to say is... I'll like it A LOT! :goodjob:
 
Bah - I give up. I was just trying to guess the design and hope for something anyway :)

Maybe some day I'll look at the code, but not today.
 
@ Cammagno
I uploaded that read-me you wanted.

Oh, good! :goodjob:
I've added a task for both of us about it, I'm happy that you have already done it :) So I only have to translate it, I'll do this morning.
Edit: Done

[
I'm now working on those flavor units, combining work done by modders recently.

Ok, good work, then :)

Today I'm busy, but in a couple of day I'll probably be able to translate at least some of those AcualQuotes (there are a lot of them... and it's such a good work that I really want to translate them the better I'm able to).
 
Status
Not open for further replies.
Back
Top Bottom