1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

[DLL] How are Events defined in the DLL?

Discussion in 'Civ5 - SDK / LUA' started by Drawmeus, Dec 7, 2012.

  1. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    So, the available events exposed to Lua are woefully limited - e.g. no OnBuildingCreated() or similar event.

    Has anyone looked into exactly how those events are defined in the DLL, if at all? What would it take to define a new one?
     
  2. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,468
    Location:
    Near Portsmouth, UK
    Of the three types of event (Events, GameEvents and LuaEvents) you can only add new GameEvents (unless I've missed the code for the others) - but one type is enough.

    The code is relatively simple, and there are numerous examples you can copy, eg

    Code:
    ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();
      if(pkScriptSystem) {
        CvLuaArgsHandle args;
        args->Push(eEvent);
        args->Push(eAIPlayer);
        args->Push(iArg1);
        args->Push(iArg2);
    
        bool bResult;
        LuaSupport::CallHook(pkScriptSystem, "[B][COLOR="red"]UiDiploEvent[/COLOR][/B]", args.get(), bResult);
    }
    
    Calls the new GameEvent "UiDiploEvent" passing it four parameters.

    You can hook it in Lua with

    Code:
    function OnUiDiploEvent(iDiploEvent, iPlayerWith, iButton, iPlayerAgainst)
      -- Do something
    end
    GameEvents.[B][COLOR="Red"]UiDiploEvent[/COLOR][/B].Add(OnUiDiploEvent)
    
    Given that the event name is an arbitary string, you can define as many events as you want, but a) watch out for conflicts with other mods and potentially future new core events and b) make sure the event isn't called too often during a turn, as the mechanism appears to be fairly inefficient (eg adding a "CanMoveInto" event just about cripples the game as it's called thousands (literally) of times during a turn.

    HTH

    W
     
  3. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    Thanks for sharing!
     
  4. mjjepper

    mjjepper Chieftain

    Joined:
    Jan 16, 2012
    Messages:
    29
    Drawmeus, I also am interested in creating onBuildBuilding() and onSellbuilding() game events; however, I am sorely lacking in C++ expertise. If you get a chance would you explain the code or possibly make a tutorial?
     
  5. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    I'll take a crack at it in the next week or so and post my results.
     
  6. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    Adding this code to the CvCity.cpp file inside of CvCity::CreateBuilding(BuildingTypes eBuildingType) function after the line:
    Code:
    m_pCityBuildings->SetNumRealBuilding(eBuildingType, m_pCityBuildings->GetNumRealBuilding(eBuildingType) + 1); 
    fires an event each time a building is created. I'm not sure if there are any edge cases I missed - I don't know what will happen if you grant the building through lua, say - but it should fire on at least purchasing and production.

    The parameters are: City X coordinate, City Y coordinate, Building ID, Player ID, City ID.

    Code:
    	// STRABO - Adding new GameEvent: StraboOnBuildingCreated	
    	ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();
    	if(pkScriptSystem)
    	{
    		CvLuaArgsHandle args;
    		args->Push(this->getX());
    		args->Push(this->getY());
    		args->Push(eBuildingType);
    		args->Push(kPlayer.GetID());
    		args->Push(GetID());
    
    		bool bResult;
    		LuaSupport::CallHook(pkScriptSystem, "StraboOnBuildingCreated", args.get(), bResult);
    	}
    I tested with the following lua code:

    Code:
    function OnBuildingCreated(Xcoord, Ycoord, buildingID, ownerID, cityID)
    	print("OnBuildingCreated");
    
    	local pPlayer = Players[ ownerID ];
    	print("Player: " .. Locale.ConvertTextKey(pPlayer:GetCivilizationShortDescriptionKey()));
    	local pBuilding = GameInfo.Buildings[ buildingID ];
    	print("Building: " .. Locale.ConvertTextKey(GameInfo.Buildings[ buildingID ].Description));
    	local pCity = pPlayer:GetCityByID( cityID );
    	print("City: " .. pCity:GetName() );
    
    end
    GameEvents.StraboOnBuildingCreated.Add(OnBuildingCreated)
    I did not test the X,Y coordinates yet, so I don't know for sure that they're working, but I at least know that all the other parameters work and that the building fires appropriately.
     
  7. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,468
    Location:
    Near Portsmouth, UK
    So as fully tested as the ones added by Firaxis then. Job done. Push it out in the next patch :D

    (In case it's not clear, this is slagging off the Firaxis dev team, not Drawmeus)
     
  8. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    I got it >.>

    One word of warning for anyone using the code I just posted - I would most certainly NOT use a DLL mod if this is the only thing you're doing in it. It will immediately break compatibility with all other mods that modify the DLL, and given that there are modular lua solutions available, that's a very steep cost to pay for little real gain.

    If you need to modify the DLL for your mod anyway, have at it. It does simplify things.
     
  9. Thalassicus

    Thalassicus Bytes and Nibblers

    Joined:
    Nov 9, 2005
    Messages:
    11,057
    Location:
    Texas
    How do I find the functions for existing events? I'd like to see the parameters for some events, such as SerialEventForestRemoved. I got no hits from searching the source code for "ForestRemoved".
     
  10. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,468
    Location:
    Near Portsmouth, UK
    SerialEvents are in the UI DLL and we don't have the source for that
     
  11. Thalassicus

    Thalassicus Bytes and Nibblers

    Joined:
    Nov 9, 2005
    Messages:
    11,057
    Location:
    Texas
    I'd say I hope they add documentation for those events, but... yeah. :lol:
     
  12. Gedemon

    Gedemon Modder Moderator

    Joined:
    Oct 4, 2004
    Messages:
    9,458
    Location:
    France
    Moderator Action: moved trystero49's question about pointers in a new thread
     
  13. Lord Yanaek

    Lord Yanaek Emperor

    Joined:
    Aug 15, 2003
    Messages:
    1,497
    Now, i know this has been discussed several times before, but considering that dll mods will become more and more common (unless Firaxis breaks something again in a future patch), do you, "dll modders" think it would be a good idea, and something possible to release some sort of "community dll mod", using whoward's modular dll approach to include all those small, smart additions. Then modders could use this dll in their own mods.
    It would not guarantee compatibilty between all mods that use this dll, but it would help greatly. I see it this way :
    • The code would be maintained using SVN or some similar tool. This way everyone able to code in C++ could add to the code.
    • One person would be responsible for validating additions and compiling updates once in a while (without some control, an open-source project will fail)
    • The dll would be released as a "stand alone" mod with only some xml/sql to create the options table, with all options disabled.
    • Modders willing to use the dll would make it a prereq for their mod, and selectively enable the features they use. If several people need different features for their mods, since they default to "off" and are set to "on" on a per-mod basis, they wouldn't conflict.
    • The sources for this dll would be available to everyone, so modders who need bigger dll changes (such as adding a complete spell-casting system a la FFH2) could use the base code and add their own features on top, keeping compatibility with smaller mods that use the "community dll". Big mods are not likely to be compatible with each other anyway.
    New events (onBuildingCreated, onUnitCreated ...), new APIs (espionage, more control on religious pressure ...) and "bug fix" (range 3 targetting) are all very useful features, but currently only whoward's dll includes some of them. Rather than hoping/waiting/asking him to include more, it would be nice to have a way to add them while staying compatible with what he, and other poeple might add/already added.
     
  14. Gedemon

    Gedemon Modder Moderator

    Joined:
    Oct 4, 2004
    Messages:
    9,458
    Location:
    France
    see also here for another approach.

    now that the patched code has been released, and after I'll have tested it, I'll create a new thread about GitHub in this section.
     
  15. Lord Yanaek

    Lord Yanaek Emperor

    Joined:
    Aug 15, 2003
    Messages:
    1,497
    Yep. I knew i had seen something about git but it's too short a keyword so i couldn't search for the thread.
    I'm not familiar with git however, and don't know how it's different from SVN or other "team" based source code managment.
    Not sure how it could make dll mods compatible either with the "one dll to rule them all" limitation, the only way for 2 mods that use a moded dll to be compatible with each other would be to use a single dll, that needs to be a separate mod. Or at least it's how i understand it.
    But this is quite off topic so i'll wait for your thread to discuss this
     
  16. Drawmeus

    Drawmeus Emperor

    Joined:
    Jul 25, 2007
    Messages:
    1,213
    I can honestly say that if I had to go through another modder for my DLL mods to work, they wouldn't be happening. I'm looking at months of work to do everything I'm planning to do as is, and anything that adds overhead is kind of a dealbreaker. I'm being extraordinarily careful to // STRABO comment every change I make, so merges would only be sort of nightmarish instead of almost completely impossible, but compatibility simply isn't a high enough priority for me to accept a much slower pace of development for it.
     
  17. Pazyryk

    Pazyryk Deity

    Joined:
    Jun 13, 2008
    Messages:
    3,584
    Has anyone created a GameEvents.OnUnitAttack that preserves unit info for attacker or defender that die? So many mods tie into the attack serial Events, which doesn't allow you to get info on killed units (not to mention that it is dangerous to rely on the graphics Events system, as Spatz can tell you).
     
  18. Gedemon

    Gedemon Modder Moderator

    Joined:
    Oct 4, 2004
    Messages:
    9,458
    Location:
    France
    yes, see RED WWII.
     
  19. Pazyryk

    Pazyryk Deity

    Joined:
    Jun 13, 2008
    Messages:
    3,584
    Ah! Several other fine events there as well...

    Just wondering, if I dropped your CvGameCore_Expansion1.dll into my mod is it likely to work? Or am I going to have paradropping orcs falling out of the sky? Are the changes well annotated? (I'm trying to ease my way into C++ coding ... or more accurately to delay it as long as possible. I used your mod as a Lua scaffold way back when I stared Éa :))
     
  20. Gedemon

    Gedemon Modder Moderator

    Joined:
    Oct 4, 2004
    Messages:
    9,458
    Location:
    France
    I've put much more comments in my Lua than my C++ code I'm afraid. But it's "tagged" ("// RED" or "// RED <<<<< [....] //RED >>>>>"

    And the diff with the base code can be viewed from github : https://github.com/Gedemon/Civ5-DLL/compare/master...RED (click "files changed)

    It should work with any mods and shouldn't change anything unless you set options or use events, but I've lacked time to test full games with just the custom DLL. And RED WWII is based on civ5 vanilla, that means the G+K DLL is released "as it is", but I'm curious to know if there are any problems with it.

    ww2commander has reported *big* slowdown when using it in is mod for G+K, something I didn't noticed in mine for vanilla, or in my quick test in unmodded G+K (except the DLL)

    that also remind me that I must write something about using Git ASAP, but sadly there is still only 24h in a day last time I counted :D
     

Share This Page