Éa III, Sword & Sorcery: Coders' Thread

Pazyryk

Deity
Joined
Jun 13, 2008
Messages
3,584
This thread replaces the the old (pre-release) "Developer's Thread".

Post here only if you are contributing to Éa code (Lua/SQL/C++) or have a desire to do so! For general discussion, suggestions or ideas, please find another thread or start a new one in the mod's subforum.

Current working Game Manual

A current development build for Éa can be assembled from these three parts:
  1. The non-dll project (https://github.com/Pazyryk/Ea_III_Sword_and_Sorcery)
  2. The dll project (https://github.com/Pazyryk/EaDLL)
  3. Éa Media Pack (link in Downloads thread)
Depending on what you intend to do, it may or may not be necessary to be able to work with the GitHub builds (it's a pretty cool thing to learn how to do though).

PHASE 3 UNFINISHED SYSTEMS:
  1. Protector of Éa Victory Condition v7
    • Prophesy of Va and Seal Ahriman's Vault systems v7
    • Renounce Maleficium trade item v7
    • VC scoring and trigger v7
  2. Favored Techs (system working, just need to add for last 1/2 of civs) v7
  3. Civ Enabled Policies (system and UI built, just need policies) --working on this for v8...
  4. Heldeofol as playable race
  5. Slaver city state system
  6. Lycanthropy
  7. Vampirism

ONGOING WORK PROJECTS:
  1. City state and God quests: just need to prohibit bad ones for now
  2. Finish GP actions and spells (mostly listed in manual)
  3. Autoplay observation and AI fixes/adjustments
    • Run lots of autoplay sessions and take good notes on what AI is doing/not doing
    • Flavor system overhaul: Can be done mostly on SQL/Lua side but requires understanding of flavor system in dll
    • Fixes for City, Economic and Military AI Strategies: These all modify flavor weightings to determine what cities build (note: it's totally disconnected from tech/policy choice in the mod)
    • AI Grand Strategies
  4. Civilopedia: Lua coding needed to handle new game items (GP Classes/Subclasses, Action/Spell Modifiers, Spells, Rituals, Prophecies, Epics, Artifacts, etc) and changes in existing pages. See Units page as an example where I've re-coded it to subdivide units by race (although this needs more work with the new Angels, Demons, Undead, etc).
 
If I were to take a crack at scripting the Slaver CSes, would you want their available Slaves to be based on their own actions Mercenary-style or should they just be infinite/hardcoded?
 
The buy/sell system is already there I think. But god it's been a long time since I looked at this so I might be remembering something I imagined rather than did. I want them to sell actual slave units that they build and/or acquire. I know that the slave supply/demand balance (as it currently stands) makes this a pointless system however. So that really makes two separate work items: 1) balancing slave value/supply/demand; 2) slave buy/sell mechanics (which I was sure 1 minute ago existed but I'm less sure now).

So #1 above would be adjusting costs and so forth (all set in SQL files) and testing/balancing to make sure Slavery full civs have a reason to want to buy. #2 (assuming I'm only imagining that I already coded it) is more Lua coding. I wouldn't necessarily recommend following my Mercenaries code for that, since it's a little over-complicated. Really it's just a button that shows for a Slavery civs if the CS has any Slaves; then a follow-on popup asking how many with price; then transfer unit ownership; then a tiny bit of AI code to make full civs do it (all things done many times in the mod).


The other "special feature" of Slaver CSs is that they will, in an opportunistic way, DoW on other CSs or full players to gather slaves (the civilian unit). They have the same promotion that players with Slave Raiders have, so that they generate slaves from kills. There's really nothing good about these CSs for most players, so a good reason for even a peaceful player to raise a small army to conquer. (In v7 I cut warmonger way way down for CS taking.)

I think the "Slave Raid" system might be code-able entirely (or almost entirely) on the Lua side. Basically, each turn:
  1. Move units toward nearby potential targets (unguarded worker/settler or a military unit in isolation from anyone that is not an ally)
  2. Can CS take a unit this turn?
  3. If yes, DoW on player and force attacks.
  4. Peace available in 10 turns; add full-civ AI code to take it.
  5. Relationship returns to where it was
Everything above is pure Lua code. (The dll might object to the CS DoW depending on how it is set, but I'm sure I can bypass any offended dll code.)
 
I'll see what I can do. I've done some tutorials and I'm comfortable enough modding/coding, but this is my first time doing any Civ 5 modding, so don't wait up for me. :p
 
I've had some real life issues this summer which have inhibited my ability to code for Ea in the past month or so, and I apologize for that. I should have said something earlier. I will be able to work on this again in the fall, as I will have more predictable obligations during the university semester.
 
@ls612, No problem at all! Folks are welcome to contribute whenever they can. It's all recreation of course.

Just be sure to sync with Github before you do anything... :)
 
So #1 above would be adjusting costs and so forth (all set in SQL files) and testing/balancing to make sure Slavery full civs have a reason to want to buy.
I hate to do this, but if this is supposed to be read as "there currently exist slave-buying prices in the SQL files" can you point out the specific SQL file? I think I've looked through them all without seeing anything linked to slave-buying price. Sorry for the trouble - I understand that fielding simple code questions isn't the most efficient use of a modder's time, and after this I'll just sink or swim with the rest - but I'm not exactly off to a great start.
 
It's spread all around the Lua code in v6.

For v7, I created a new table called EaSettings. It's going to be a work-in-progress for a while, but so far I've migrated 34 different (previously hard-coded in Lua) values to it. 12 for barb spawning, 2 for animal spawning, 5 Cultural Level settings, 1 for duration of Timber from chops, 4 for mana levels, and so on...

And adjustments for game speed and map size (if needed) are specified right in the table for each variable.

I'll be sure to move slave stuff into the table before v7 release (which I hope is this weekend).


Edit: OK, I moved these values out to the EaSettings table. The first number is the value, the 2nd and 3rd are adjusters for game length & map size. I set these to 1 or -1 to use a "standard" set of adjustments up or down (for example, 1 under map size would increase the value by 1/3 from standard to large map). The last number just indicates whether to round to integer after adjustments.
Code:
--Slaves
('SLAVE_SELL_PRICE',			30,		0,	0,	0	),
('SLAVE_RENDER_PRODUCTION',		20,		0,	0,	0	),
('SLAVE_UPGRD_TO_WARRIOR_COST',		50,		0,	0,	0	),
('SLAVE_BUY_PRICE_FROM_CS',		35,		0,	0,	0	),

The 4th one doesn't do anything yet, of course.

The other relevant numbers are in the Units table. Comparing Slave and Worker:
Code:
		Cost		WorkRate	NoMaintenance
Slave		70		70		true
Worker		100		100		false
Are there any other settings that might be important?
 
That should be plenty, thanks. I'll probably wait until v7 if everything's getting moved around.
 
Alright, I got slave-buying working for human players. I utterly failed to wrap my head around the AI scripting or find any tutorials, so it looks like this is as far as I go. Help yourself if it's of use.

Notes:
-It uses slave promotions to detect owned slaves and I got rid of the testing edits, so it won't work until the "slaver CSes train non-slave workers" thing gets fixed.
-As discussed above, the AI does not know how to buy slaves.
-The lua kept crashing when I tried to refer to EaSettings, so I just gave the settings hard values in DiploPopup.lua. I suggest 45 for neutral (an early worker is actually pretty valuable - at that point in the game it's almost like buying a monument), 30 for friends and 10 for allies (arbitrage isn't necessarily a bad thing so long as the slave supply's limited and you're paying for it some other way)
 

Attachments

  • Slave-Buying.zip
    18.4 KB · Views: 204
Thanks!

I just added it. I'll fix the slave/worker problem and then test it out.

For future reference: UI's are running in different Lua states, so they don't have access to the same globals. EaSettings is a global in the "EaMain" state. The workaround here is that MapModData is a global in all states and is a table. So I put EaSettings in there for access outside of EaMain. So in a UI Lua file, this works:

local SLAVE_BUY_PRICE_FROM_CS = MapModData.EaSettings.SLAVE_BUY_PRICE_FROM_CS --45
local SLAVE_CS_FRIEND_DISCOUNT = MapModData.EaSettings.SLAVE_CS_FRIEND_DISCOUNT --15
local SLAVE_CS_ALLY_DISCOUNT = MapModData.EaSettings.SLAVE_CS_ALLY_DISCOUNT --35

Note: this wouldn't work in most mods because UI files normally load before mod files. However, I flipped that by adding Ea mod files via InGame.xml before UI. (Normally frowned on for mod compatibility, but that's not really an issue for us.)


Edit:

OK, tested and looks good. Just released in version 7c.

I'll make some simple AI for it to add in next version. Basically, any Slavery player that is nearby and is short on slaves or can convert them to production (and has cash) should wan't to buy.
 
Hey Pazyryk, could you please add this code to UnitPanel.lua?
Code:
function OnUnitNameRClicked()
	-- rename this unit
	
	if UI.GetHeadSelectedUnit() then
		local popupInfo = {
				Type = ButtonPopupTypes.BUTTONPOPUP_RENAME_UNIT,
				Data1 = UI.GetHeadSelectedUnit():GetID(),
				Data2 = -1,
				Data3 = -1,
				Option1 = false,
				Option2 = false;
			}
		Events.SerialEventGameMessagePopup(popupInfo);
	end
end
Controls.UnitNameButton:RegisterCallback( Mouse.eRClick, OnUnitNameRClicked );
It allows the player to rename his units at any time by right-clicking on the unit's name in the unit panel. It is my absolute favorite mod and I actually added this code to the base game UnitPanel.lua in order to always have this function... of course you could add something to prevent this with GPs. I used to always add this to every new version, but since you started uploading hotfixes as full mod updates there is a new UnitPanel.lua in each and every one, so it's really too much of a hassle by now.
 
Implemented Haste, Slow and Enchant Weapons spells.

-Targets strongest living unit within tile (guess which spells I copied wholesale?).
-They have SetAIValue functions based off Bless and Curse, but no other AI stuff.
-Possible name for the unnamed +archer range spell: Wind Guide.
-The Transmutation tech doesn't show the new spells in the UI, but learning the tech will enable them.
 

Attachments

  • Transmutation.rar
    62.9 KB · Views: 206
Awesome! I just added these in for the v8 build. The new promotions make these gamesave breakers, unfortunately.

I changed the SustainedPromotionDo just a bit so that dead caster wouldn't cause an error. But it still has your logic to take/remove movement on the turn that the promo goes away.

Also, to "finish" these, the EaAction table has to have something for either AITarget or AICombatRole. (Copying similar spells works here too.) Not surprisingly, that plugs in the right AI for the action. However, I'm also (illogically) using these as proxy for the spell actually being in the game for some functions. So that's what was needed to make them appear in the tech tree.

Going to test now.
 
Calling it 'logic' is a bit charitable, but I'm glad I could be of help.

I expect I could add fiveish other spells if I could figure out how these stupid includes work in Civ 5 (Why does EaSpells crash when I reference COMBATTYPE_ARCHER but not COMBATTYPE_SIEGE? Why can't I reference PROMOTION_UNMOUNTED_ARCHER when it's defined right next to BLESSED, HASTED ETC?) and the work necessary for implementing a new spell (it doesn't quite seem as simple as defining it in EaActions and referencing it in EaSpells), so if you can enlighten me more quickly than you could do it yourself that'd be great.
 
Remember that PROMOTION_UNMOUNTED_ARCHER and similar are just labels to Lua. They have to be defined somewhere. It's a common convention to use all uppercase for constants, so I define all of these sorts of values at the top of the file with lines like:

local PROMOTION_UNMOUNTED_ARCHER = GameInfoTypes.PROMOTION_UNMOUNTED_ARCHER

That's just so I can use a local variable for the value which is much faster than looking up the value in a global table.

GameInfoTypes is just a giant global table defined by Firaxis that has keys/value pairs corresponding to all the Type/IDs in the DB tables that have Type and ID (e.g., UnitPromotions, Buildings, plus any modder added tables with Type and ID). Note that this formatting demands that all Type strings be unique, which they are (the IDs certainly aren't). So the line above declares PROMOTION_UNMOUNTED_ARCHER as a local variable holding some integer constant (the ID for that promotion in the UnitPromotions table). Without that line, PROMOTION_UNMOUNTED_ARCHER would evaluate to nil.

There are a couple gocha's here to watch out for. First, notice I use GameInfoTypes rather than PromotionTypes above. The reason is that GameInfoTypes is updated for modder changes to the DB table. PromotionTypes is not and only reflects the table before modder modification.

However, there are a few things that never get into GameInfoTypes. I think these are cases where you would never find the table in any search of installed xml files. For example, PlotTypes.PLOT_OCEAN has a value, but GameInfoTypes.PLOT_OCEAN does not.

I'm not 100% sure and can't check right now, but I think that GameInfoTypes.COMBATTYPE_ARCHER should work. It's a data table. But I haven't added/deleted anything from that table so UnitCombatTypes.COMBATTYPE_ARCHER should also work.

(There is no need for uncertainty for any of these, however. Just type them in Fire Tuner during game session and verify that they return an integer.)
 
I was handling the includes up top, both GameInfoTypes.PROMOTION_UNMOUNTED_ARCHER and GameInfoTypes.UNITCOMBAT_ARCHER crashing even when I don't use them for anything. On the other hand, GameInfoTypes.UNITCOMBAT_SIEGE I could reference without problems even though it wasn't in EaSpells when I started (at least, if I wasted hours trying to work my away around a typo I'll feel very embarrassed). However, I'll definitely use FireTuner to save time tinkering around in the future.
 
Let's say I wanted to try, in an entirely non-promissory way, to implement werewolves and/or vampires. Do you know how you want them to act, either specifically or vaguely? Should I be writing proposals before I start coding? Just do whatever?
 
Top Bottom