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

Problem with recreation of Warlords event for Vanilla

Discussion in 'Civ4 - Creation & Customization' started by Jean Elcard, Jul 3, 2007.

  1. Jean Elcard

    Jean Elcard The Flavournator

    Joined:
    Feb 26, 2006
    Messages:
    1,008
    Location:
    Leipzig, Germany
    Hi peeps,

    I'm totally lost with something that should be a simple task. All I want to do is copying a mechanism from Warlords to Vanilla. Means, I want to recreate the Python event function onImprovementDestroyed for Vanilla Civ.

    I added this to the file CvEventManager.py (my changes are bold):

    Code:
    ## EVENTLIST
    self.EventHandlerMap = {
        ...
        [B]'improvementDestroyed'	: self.onImprovementDestroyed,[/B]
        ...
    }
    ...
    	[B]def onImprovementDestroyed(self, argsList):
    		'Improvement Destroyed'
    		iImprovement, iOwner, iX, iY = argsList
    		if (not self.__LOG_IMPROVEMENT):
    			return
    		CvUtil.pyPrint('Improvement %s was Destroyed at %d, %d'
    			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))[/B]
    ...
    This to CvDLLEventReporterIFaceBase.h:
    Code:
            ...
    	virtual void improvementBuilt(int iImprovementType, int iX, int iY) = 0;	
    	[B]virtual void improvementDestroyed(int iImprovementType, int iPlayer, int iX, int iY) = 0;[/B]	
    	virtual void routeBuilt(int RouteType, int iX, int iY) = 0;
            ...
    And this to CvPlot.cpp:

    Code:
    ...
    void CvPlot::setImprovementType(ImprovementTypes eNewValue)
    {
    	int iI;
    	[B]ImprovementTypes eTempType;
    	eTempType = getImprovementType();[/B]
    
    	...
    
    		if (getImprovementType() != NO_IMPROVEMENT)
    		{
    			gDLL->getEventReporterIFace()->improvementBuilt(getImprovementType(), getX_INLINE(), getY_INLINE());
    		}
    
    		[B]if (getImprovementType() == NO_IMPROVEMENT)
    		{
    			gDLL->getEventReporterIFace()->improvementDestroyed(eTempType, getOwnerINLINE(), getX_INLINE(), getY_INLINE());
    		}[/B]
    	}
    }
    ...
    After compiling successfully the dll and copying it to the right place as well as the Python Civ4 loads but crashes back to windows when I try to start a game.

    I have no idea what I'm doing wrong. I hope you can help me. Maybe I missed something totally obvious? Please tell me if you need mor information.

    Greetings, Elgor.
     
  2. Mexico

    Mexico TR senior programmer

    Joined:
    Dec 2, 2005
    Messages:
    578
    Location:
    Slovakia, Kosice
    because getEventReporterIFace is hard-coded in exe, not in DLL, so you can't add new event (in your case, you are trying to call non-existing method, which lead to crash)
     
  3. Jean Elcard

    Jean Elcard The Flavournator

    Joined:
    Feb 26, 2006
    Messages:
    1,008
    Location:
    Leipzig, Germany
    Not the news I had hoped for, but thx anyway, Mexico. It isn't that easy then.

    Although in danger to ask something somebody else has surely posted before: Is there another way to report new events to Python? If not, I have to code it directly in the SDK I suppose.

    Thx for any hints in advance.
     
  4. Mexico

    Mexico TR senior programmer

    Joined:
    Dec 2, 2005
    Messages:
    578
    Location:
    Slovakia, Kosice
    yes, you can use generic event reporter
    as example is used my own modification to unitSetXY event to report also old plot
    Code:
    [B]SDK part :[/B]
        CyArgsList argsList;
        CyUnit* pyUnit = new CyUnit(this);
        CyPlot* pyNewPlot = new CyPlot(pNewPlot);
        CyPlot* pyOldPlot = new CyPlot(pOldPlot);
        argsList.add(gDLL->getPythonIFace()->makePythonObject(pyNewPlot));
        argsList.add(gDLL->getPythonIFace()->makePythonObject(pyOldPlot));
        argsList.add(gDLL->getPythonIFace()->makePythonObject(pyUnit));
        gDLL->getEventReporterIFace()->genericEvent("unitSetXY", argsList.makeFunctionArgs());
        delete pyUnit;
        delete pyNewPlot;
        delete pyOldPlot;
    
    
    [B]python part:[/B]
    in event manager (or custom even manager):
    registered onUnitSetXY method for event unitSetXY,
    
        def onUnitSetXY(self, argsList):
           'units xy coords set manually'
    [B]       genericList = argsList[0][0][/B] - at first, extract list of parameters from generic event
    [B]       pNewPlot,pOldPlot,pUnit = genericList[/B] - now extract parameters 
           ...here you can use this parameters...
    
     
  5. EmperorFool

    EmperorFool Deity

    Joined:
    Mar 2, 2007
    Messages:
    9,633
    Location:
    Mountain View, California
    What Mexico posted looks pretty easy to do and will definitely suit your needs (any new events needs, actually). However, here's what I was going to suggest anyway.

    Use the improvementBuilt event, passing NO_IMPROVEMENT (-1) as the improvement type. You can get the owner from the plot.
     
  6. Jean Elcard

    Jean Elcard The Flavournator

    Joined:
    Feb 26, 2006
    Messages:
    1,008
    Location:
    Leipzig, Germany
    Thx again Mexico. That looks really good and I'm going to use this code in the future for sure. Meanwhile I dived into the SDK and it's really fun playing around with it. Made me almost forget my old Python event problem. ;)

    And thx EmperorFool, too. This NO_IMPROVEMENT idea is very appealing.
     

Share This Page