Question - Floating texts on map

Leodim

Warlord
Joined
Nov 25, 2013
Messages
108
Hello,

Not sure where in which subforum of civ 4 modding this should go (a general section for mod makers helping each other), so I post it here.

I just wanted to know if there is an existing mod that include floating text on the main view/map, before I try to do my own.

My goal here is to make a bit like ARPG damages where they appear like floating text, but above the tile any unit died at turn start. For example if 4 units died in the tile show a short floating text saying "-4" there.
Has it been done? I searched in BUGmod and a few other places and didn't find anything.

I'm a decent modder/cpp game developer so, if my goal hasnt been done already, ANY floating text on the map would be a great start for me.
Because while I feel confident to do the logic part and storing the infos, and delaying display etc. it would still save me the trouble (if doable) to create text, then floating text, over civ4 main view from scratch.

Thanks in advance!
 
EDIT : I'm not a civ4 expert though, and if there actually already is something looking like floating text on the map in raw civ4/btw, please let me know. The closer I saw was city names, which is not floating and quite specific.
EDIT2 : Signs (where you can place a signpost on the map) is the only other text on mainscreen I can think about. Looking at the sdk, I only found clearSigns() to be exposed. So far not much luck with texts over map.
 
Last edited:
So far I've found CyEngine().addSign, which works fine python side. But CyEngine doesn't seem to be in the sdk (or am I missing something?).
Also since it is unsourced, no way to modify it like "change color" (it uses the player seeing the sign's color), aspect, relative pos to plot and so on.
Maybe I'm dumb but I couldn't find any c++ source related to Signs/texts on map in the SDK.

EDIT : https://civ4bug.sourceforge.net/PythonAPI/ (forgot about that) confirmed that it is not in the sdk. Also has CyEngine.addLandmark but it seems to just be the same as addSign with black color.
I guess I'll have to keep on looking elsewhere. I could do with horrible Signs that gets destroyed after 1 sec (or could I? really horrible visually) but at least I would need some color to show whose unit it was to the player.
 
Last edited:
Update : it's "horribly working" meaning at turn start it does show a sign per plot with losses per leader. The signs then vanish after 2 seconds.

Example of a sign a given plot:
Isabella : -3
Churchill : -1


But :
  • using sign is horrible in that context. Still couldnt find "simple" text with no background in either python or SDK.
  • having multiple lines (like in the example given) on a single plot makes the text goes out of the sign (sign height doesnt expand with text height)
  • it is not color based, I have to show the leader (or civ) name instead of using its color. Making it ugly and too much to read. Maybe it would be better to just stack all losses not showing where they come from at this point. Example would become simply:
-4
  • it does not float (static sign, doesn't seem to be possible to make its position on fraction of tile)

So all in all, I would say its just a conceptual proof at this stage, nothing more. Too ugly to use :cry:
 
I'm not aware of any function that places text at a specific tile. Nor of one for placing a 2D graphic (a sprite, so to speak); I had looked into that a few years ago when I wanted to put small resource icons on the map (instead of the balloon indicators). There are plenty of functions for placing text and graphics on a menu screen (CyGInterfaceScreen in the API you linked to) – but not directly on the main map, i.e. those functions work with pixels and screen coordinates, not with tiles on the map. The possibilities for placing entities on the (3D) map are quite limited. Units, terrain features and improvements, cities, the little unit flags, yield icons, some special effects. Signs you've already found – none of that seems suitable. We do have the on-screen messages that get shown centered near the top of the screen, but, short of reverse-engineering parts of the EXE, the position of those messages can't be changed. The Civ4 approach, apparently, is to combine those messages with plot indicators (that's what they're called in the code; the balloons that point out a tile). Adding a plot indicator to the "While defending, your Warrior was destroyed by a Bear" message would be easy to do. Or does the game already show one? I think the NULL parameter in this call means that no plot indicator gets shown, would have to pass a (button) graphic instead of NULL. Showing a separate message with a combat summary – "3 Spanish units have been destroyed near London" (the only established convention for describing a location on the map) along with a plot indicator – would also be straightforward (in the DLL).
Edit: All this being said, I also wouldn't have thought some of the changes in the Civ 4 Remaster to be possible, so I don't want to just claim that floating text at a tile is impossible or infeasible.
 
Last edited:
Thanks a lot for your input and all the information f1rpo! That is sad news.

Here are my thoughts after a short think on what you provided:
- plot indicator might be a bit nicer than signs (even though not great) but since I suppose it is "one plot = one image inside", we'll have to build the text in a bitmap first. All in all it seems like redo a whole text engine (with 11 characters, numbers and "-"), I feel like it's too much work for too little.
- terrain feature/improvements: since I don't think we'll be able to give a dynamic orientation to the "billboard" model/square (not a billboard), that would be at best not great. Maybe better? But again, we would need to build the texture of the texts dynamically.
- top screen messages: while I discarded this at first (I knew about those ofc) because that seemed too much off my original goal, it's true it might be the lesser evil at this point. Maybe a summary of losses (without location) per leader each turn. We do have colors. Would need the ability to speed up the showing process, didnt look yet, do you remember if speed/duration is a parameter somehow?
- reverse-engineer exe: While we could in theory easily duplicate the sign function to give it color, no background, and even non-integer position (pretty much all we want), I have little knowledge in this. I sometimes used some decompilers for recreationnal purposes on small programs in other languages; but I have the feeling, unless decompilers made huge progresses in the last decade, that this would be great pain to get the game "bug-free". Also, is it even legal in this case?
EDIT : if it was legal, I suppose someone would have provided the full sources at this point. Right? I admit having little knowledge about that, so I prefer to be cautious.

I'm still sad the original goal seems unattainable due to the lack of simple text on the main map.
Feel free to give your thoughts :)
 
Last edited:
I agree with your assessments. I'm not aware of any effort to decompile the Civ4 binaries, and moderators have pre-emptively warned that CFC would not allow – I paraphrase – serious discussions in that vein. So I guess your best bet would be to set a breakpoint for the Visual Studio debugger somewhere in (GameCore) DLL code that causes a sign to be placed, and then to step into the dissambly of the EXE generated by the debugger. Difficult and painstaking. Some small graphical improvements have been accomplished this way and are currently being discussed in this thread. (Though you wouldn't necessarily need to modify the EXE; identifying a sufficiently flexible function for placing text would suffice.)
- top screen messages: while I discarded this at first (I knew about those ofc) because that seemed to much off my original goal, it's true it might be the lesser evil at this point. Maybe a summary of losses (without location) per leader each turn. We do have colors. Would need the ability to speed up the showing process, didnt look yet, do you remember if speed/duration is a parameter somehow?
There are these variables in GlobalDefines.xml:
Code:
	<Define>
		<DefineName>EVENT_MESSAGE_TIME</DefineName>
		<iDefineIntVal>10</iDefineIntVal>
	</Define>
	<Define>
		<DefineName>EVENT_MESSAGE_TIME_LONG</DefineName>
		<iDefineIntVal>20</iDefineIntVal>
	</Define>
	<Define>
		<DefineName>EVENT_MESSAGE_STAGGER_TIME</DefineName>
		<iDefineIntVal>3</iDefineIntVal>
	</Define>
For the display duration (MESSAGE_TIME), the DLL can set any value when calling CvDLLInterfaceIFaceBase::addMessage. The interface is:
Code:
virtual void addMessage(PlayerTypes ePlayer, bool bForce, int iLength, CvWString szString, LPCTSTR pszSound = NULL,
		InterfaceMessageTypes eType = MESSAGE_TYPE_INFO, LPCSTR pszIcon = NULL, ColorTypes eFlashColor = NO_COLOR,
		int iFlashX = -1, int iFlashY = -1, bool bShowOffScreenArrows = false, bool bShowOnScreenArrows = false) = 0;
Currently, each of the addMessage calls scattered across the DLL explicitly sets iLength to either the value of EVENT_MESSAGE_TIME or of EVENT_MESSAGE_TIME_LONG. I think EVENT_MESSAGE_STAGGER_TIME says how many seconds pass in between two consecutive messages appearing on the screen. That variable isn't accessed by the DLL, so apparently the EXE accesses that one directly.
 
Well again thanks!
I indeed saw your thread when taking a little survey before going in. Congratz on your success btw!
I admit I feel pretty much discouraged to try to modify the exe by looking at dissambly. Really not my cup of tea, and low/no experience on this things.

Maybe I'll make some fast messages but since none of the solutions will give great user-experience results (in my opinion), I'm not too sure.
I'll have to think about it.
Thanks again for the help!
 
Top Bottom