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

[MODCOMP] Air Combat Experience

Discussion in 'Civ4 - Mod Components' started by TheLopez, Sep 11, 2010.

  1. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Air Combat Experience v0.2BtS
    By: TheLopez

    Last Updated 09/13/10

    Version: v0.3BtS
    Patch Compatibility: Beyond the Sword v3.19
    MP Compatible: ?
    Download Mod v0.3BtS

    Description:
    This mod enables experience gain for air units through missions. In addition
    routes can now be bombed by air units if there are no improvements on the same
    tile. When bombing cities the experience gain will lessen as the defenses of
    the city are taken down. When attacking units more experience is gained when
    the unit being attacked is killed. A new tag has been added to the route info
    structure that mirrors the functionality of the <iAirBombDefense> tag in the
    improvement info structure.

    Installation Instructions:

    1) Unzip this into the "bts_install_folder\Mods\" folder.
    2) Open the CivilizationIV.ini configuration file
    3) Change the Mod line to read: Mod = Mods\Air Combat Experience
    4) Load the game.
    5) Then play as normal.


    -----Game Play-----

    - Routes (roads and railroads) can now be destroyed by air units

    - Air units gain experience when successfully bombing improvements

    - Air units gain experience when successfully bombing routes

    - Air units gain experience when successfully bombing cities

    - Air units gain experience when successfully attacking units though the
    experience gain is much higher when destroying the unit.

    - No mans land can now be bombed.

    -----Notes to Modmakers-----

    If you want to use the Air Combat Experience in your mod I have tried to make
    things as easy as possible for you. In the XML files modified sections are
    enclosed by:
    <!-- -->
    <!-- Air Combat Experience Start -->
    <!-- -->
    and
    <!-- -->
    <!-- Air Combat Experience End -->
    <!-- -->

    In the SDK files I have added // < Air Combat Experience Start > and
    // < Air Combat Experience End > in all of the places that I have made changes to
    the original files.

    The python included is only used to tweak the configurable values for the mod.
    If this mod is to be included in a mod like BUG, etc. then care should be taken
    to make sure that tweaking the configurable options is ported to host mod.

    As part of the changes to the SDK files I have also exposed several new methods
    to python, they are:
    Code:
    	bool isRouteDestructionThroughAirBombs() const;
    	bool setRouteDestructionThroughAirBombs(bool bNewValue);
    	bool isExperienceGainByDestroyingImprovements() const
    	bool setExperienceGainByDestroyingImprovements(bool bNewValue);
    	bool isExperienceGainByDestroyingRoutes() const;
    	bool setExperienceGainByDestroyingRoutes(bool bNewValue);
    	bool isExperienceGainByAttackingCities() const;
    	bool setExperienceGainByAttackingCities(bool bNewValue);
    	bool isExperienceGainByAttackingUnits() const;
    	bool setExperienceGainByAttackingUnits(bool bNewValue);
    	bool isBombNoMansLand() const;
    	void isBombNoMansLand(bool bNewValue);
    
    -----Version Information-----

    -----v0.3BtS------

    - Added configuration option allowing modders to set if no mans land can be
    bombed. Default value is set to true.

    Spoiler :

    -----v0.2BtS------

    - Added configuration option allowing modders to set if route destruction
    through air bombs is allowed. Default set to true.

    - Added configuration option allowing modders to set if experience gain from
    destroying improvements is allowed. Default set to true.

    - Added configuration option allowing modders to set if experience gain from
    destroying Routes is allowed. Default set to true.

    - Added configuration option allowing modders to set if experience gain from
    bombing cities is allowed. Default set to true.

    - Added configuration option allowing modders to set if experience game from
    attacking units is allowed. Default set to true.

    - Added python configuration infrastructure

    -----v0.1BtS------

    - Setup Air Combat Experience infrastructure

    - Added the <iAirBombDefense> tag to the route info definition. Added sane
    values for roads and rail roads.

    - Added the ability for air units to destroy routes.

    - Added the ability for air units to gain experience through the destruction of
    improvements and routes

    - Added the ability for air units to gain experience through the bombing of
    cities. The more vulnerable a city is the less experience a unit will get.

    - Added the ability for air units to gain experience through attacking units. Air
    units will get more experience if the unit they attack is actually killed off.


    -----===Credits & Thanks===-----

    - Exavier - Composite Mod - readme.txt format

    - PsiCorps - for the idea and testing this mod
     
  2. OrionVeteran

    OrionVeteran Deity

    Joined:
    Dec 25, 2003
    Messages:
    2,443
    Location:
    Newport News VA
  3. The_J

    The_J Say No 2 Net Validations Retired Moderator Supporter

    Joined:
    Oct 22, 2008
    Messages:
    31,141
    Location:
    Germany / Netherlands
    You're having a lot of free time at the moment, right :D?

    -> :goodjob:, nice work again.
     
  4. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Not really... I only get about 3 hours of sleep at night :D
     
  5. keldath

    keldath LivE LonG AnD PrOsPeR

    Joined:
    Dec 20, 2005
    Messages:
    6,520
    Location:
    israel
    3 hours of sleep....probably you dream in that 3 hours what mods youll be doing next :) ( i know i do in my 8 hours of sleep)


    its fun to see veteran modders come back, next thing we will see is sevo coming back to create a new sevopedia....
     
  6. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Updated to v0.3BtS - Allows bombing routes and improvements in no mans land
     
  7. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,424
    Location:
    Britain
    excellent, can't wait to get this merged with the B5 mod.
     
  8. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    I'm on my phone right now but if I remember correctly you asked for a multiple favorite civics mod. I looked into it and it should be fairly straightforward to implement. I'll start on it in a few hours and get you a v0.1 version shortly there after. Then I'll get to work on consumable stackable resources.
     
  9. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,424
    Location:
    Britain
    That's great news, can't wait to see it in action.
     
  10. keldath

    keldath LivE LonG AnD PrOsPeR

    Joined:
    Dec 20, 2005
    Messages:
    6,520
    Location:
    israel
    yeah!!!!!!!!!!!!!
     
  11. Cybah

    Cybah Emperor

    Joined:
    Jun 22, 2007
    Messages:
    1,480
    well, you will have to update civilopedia and sevopedia as well I guess.
     
  12. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Why would I do that? Its fun to leave people guessing :lol:
     
  13. Tripod

    Tripod Chieftain

    Joined:
    Dec 9, 2007
    Messages:
    32
    Location:
    Germany
    Hello
    I would really like to merge this great modcomp into my mod but I have some trouble merging the Phyton files :confused: .
    I also use Better BTS AI 0.84b in it.Does anybody know if its possible to merge them together?
    Thank you for your answer:)
     
  14. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Tripod, you will need to merge both the python and C++ files together which requires a C++ compiler and some know-how on how to do that.
     
  15. Tripod

    Tripod Chieftain

    Joined:
    Dec 9, 2007
    Messages:
    32
    Location:
    Germany
    I know:) But merging the SDK files and compile a new DLL was no problem(ok,I think so because I got no errors...)
    I got in trouble when I try to merge the CvEventInterface and CvCustomEventmanager because they are really different.

    Spoiler :

    from air_combat_experience_v0_3bts :
    # Sid Meier's Civilization 4
    # Copyright Firaxis Games 2005
    #
    # CvEventInterface.py
    #
    # These functions are App Entry Points from C++
    # WARNING: These function names should not be changed
    # WARNING: These functions can not be placed into a class
    #
    # No other modules should import this
    #
    import CvUtil

    from CvPythonExtensions import *

    import CvCustomEventManager

    normalEventManager = CvCustomEventManager.CvCustomEventManager()

    def getEventManager():
    return normalEventManager

    def onEvent(argsList):
    'Called when a game event happens - return 1 if the event was consumed'
    return getEventManager().handleEvent(argsList)

    def applyEvent(argsList):
    context, playerID, netUserData, popupReturn = argsList
    return getEventManager().applyEvent(argsList)

    def beginEvent(context, argsList=-1):
    return getEventManager().beginEvent(context, argsList)


    Spoiler :

    and from my mod :
    # Sid Meier's Civilization 4
    # Copyright Firaxis Games 2005
    #
    # CvEventInterface.py
    #
    # These functions are App Entry Points from C++
    # WARNING: These function names should not be changed
    # WARNING: These functions can not be placed into a class
    #
    # No other modules should import this


    import CvCustomEventManager

    # **********************************
    # GJD modifications start here
    # **********************************

    customEventManager = CvCustomEventManager.CvCustomEventManager()

    def getEventManager():
    return customEventManager

    # **********************************
    # GJD modifications end here
    # **********************************

    def onEvent(argsList):
    """Called when a game event happens - return 1 if the event was consumed."""
    return getEventManager().handleEvent(argsList)

    def applyEvent(argsList):
    context, playerID, netUserData, popupReturn = argsList
    return getEventManager().applyEvent(argsList)

    def beginEvent(context, argsList = -1):
    return getEventManager().beginEvent(context, argsList)



    Spoiler :

    ## Copyright (c) 2005-2006, Gillmer J. Derge.

    ## This file is part of Civilization IV Random Cottage Placement
    ##
    ## Civilization IV Random Cottage Placement is free software; you can redistribute
    ## it and/or modify it under the terms of the GNU General Public
    ## License as published by the Free Software Foundation; either
    ## version 2 of the License, or (at your option) any later version.
    ##
    ## Civilization IV Random Cottage Placement is distributed in the hope that it will
    ## be useful, but WITHOUT ANY WARRANTY; without even the implied
    ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ## See the GNU General Public License for more details.
    ##
    ## You should have received a copy of the GNU General Public License
    ## along with Civilization IV Random Cottage Placement; if not, write to the Free
    ## Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    ## 02110-1301 USA


    import CvEventManager
    import CvAirCombatExperienceEventManager

    class CvCustomEventManager(CvEventManager.CvEventManager, object):

    def __init__(self, *args, **kwargs):
    super(CvCustomEventManager, self).__init__(*args, **kwargs)
    # map the initial EventHandlerMap values into the new data structure
    for eventType, eventHandler in self.EventHandlerMap.iteritems():
    self.setEventHandler(eventType, eventHandler)
    # --> INSERT EVENT HANDLER INITIALIZATION HERE <--
    CvAirCombatExperienceEventManager.CvAirCombatExperienceEventManager(self)

    def addEventHandler(self, eventType, eventHandler):
    """Adds a handler for the given event type.

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class.

    """
    self.EventHandlerMap[eventType].append(eventHandler)

    def removeEventHandler(self, eventType, eventHandler):
    """Removes a handler for the given event type.

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class. It is an error if
    the given handler is not found in the list of installed handlers.

    """
    self.EventHandlerMap[eventType].remove(eventHandler)

    def setEventHandler(self, eventType, eventHandler):
    """Removes all previously installed event handlers for the given
    event type and installs a new handler .

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class. This method is
    primarily useful for overriding, rather than extending, the default
    event handler functionality.

    """
    self.EventHandlerMap[eventType] = [eventHandler]

    def handleEvent(self, argsList):
    """Handles events by calling all installed handlers."""
    self.origArgsList = argsList
    flagsIndex = len(argsList) - 6
    self.bDbg, self.bMultiPlayer, self.bAlt, self.bCtrl, self.bShift, self.bAllowCheats = argsList[flagsIndex:]
    eventType = argsList[0]
    return {
    "kbdEvent": self._handleConsumableEvent,
    "mouseEvent": self._handleConsumableEvent,
    "OnSave": self._handleOnSaveEvent,
    "OnLoad": self._handleOnLoadEvent
    }.get(eventType, self._handleDefaultEvent)(eventType, argsList[1:])

    def _handleDefaultEvent(self, eventType, argsList):
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    eventHandler(argsList[:len(argsList) - 6])

    def _handleConsumableEvent(self, eventType, argsList):
    """Handles events that can be consumed by the handlers, such as
    keyboard or mouse events.

    If a handler returns non-zero, processing is terminated, and no
    subsequent handlers are invoked.

    """
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    result = eventHandler(argsList[:len(argsList) - 6])
    if (result > 0):
    return result
    return 0

    # TODO: this probably needs to be more complex
    def _handleOnSaveEvent(self, eventType, argsList):
    """Handles OnSave events by concatenating the results obtained
    from each handler to form an overall consolidated save string.

    """
    result = ""
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    result = result + eventHandler(argsList[:len(argsList) - 6])
    return result

    # TODO: this probably needs to be more complex
    def _handleOnLoadEvent(self, eventType, argsList):
    """Handles OnLoad events."""
    return self._handleDefaultEvent(eventType, argsList)

    Spoiler :

    ## Copyright (c) 2005-2006, Gillmer J. Derge.

    ## This file is part of Civilization IV Alerts mod.
    ##
    ## Civilization IV Alerts mod is free software; you can redistribute
    ## it and/or modify it under the terms of the GNU General Public
    ## License as published by the Free Software Foundation; either
    ## version 2 of the License, or (at your option) any later version.
    ##
    ## Civilization IV Alerts mod is distributed in the hope that it will
    ## be useful, but WITHOUT ANY WARRANTY; without even the implied
    ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ## See the GNU General Public License for more details.
    ##
    ## You should have received a copy of the GNU General Public License
    ## along with Civilization IV Alerts mod; if not, write to the Free
    ## Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    ## 02110-1301 USA

    __version__ = "$Revision: 1.4 $"
    # $Source: /usr/local/cvsroot/Civ4lerts/src/main/python/CvCustomEventManager.py,v $

    import CvEventManager
    # --------- Better BTS AI mod (1/2) -------------
    import AIAutoPlay
    import ChangePlayer
    import Tester

    class CvCustomEventManager(CvEventManager.CvEventManager, object):

    """Extends the standard event manager by adding support for multiple
    handlers for each event.

    Methods exist for both adding and removing event handlers. A set method
    also exists to override the default handlers. Clients should not depend
    on event handlers being called in a particular order.

    This approach works best with mods that have implemented the design
    pattern suggested on Apolyton by dsplaisted.

    http://apolyton.net/forums/showthread.php?threadid=142916

    The example given in the 8th post in the thread would be handled by adding
    the following lines to the CvCustomEventManager constructor. The RealFort,
    TechConquest, and CulturalDecay classes can remain unmodified.

    self.addEventHandler("unitMove", rf.onUnitMove)
    self.addEventHandler("improvementBuilt", rf.onImprovementBuilt)
    self.addEventHandler("techAcquired", rf.onTechAcquired)
    self.addEventHandler("cityAcquired", tc.onCityAcquired)
    self.addEventHandler("EndGameTurn", cd.onEndGameTurn)

    Note that the naming conventions for the event type strings vary from event
    to event. Some use initial capitalization, some do not; some eliminate the
    "on..." prefix used in the event handler function name, some do not. Look
    at the unmodified CvEventManager.py source code to determine the correct
    name for a particular event.

    Take care with event handlers that also extend CvEventManager. Since
    this event manager handles invocation of the base class handler function,
    additional handlers should not also call the base class function themselves.

    """

    def __init__(self, *args, **kwargs):
    super(CvCustomEventManager, self).__init__(*args, **kwargs)
    # map the initial EventHandlerMap values into the new data structure
    for eventType, eventHandler in self.EventHandlerMap.iteritems():
    self.setEventHandler(eventType, eventHandler)
    # --> INSERT EVENT HANDLER INITIALIZATION HERE <--

    # --------- Better BTS AI (2/2) -------------
    AIAutoPlay.AIAutoPlay(self)
    ChangePlayer.ChangePlayer(self)
    Tester.Tester(self)

    def addEventHandler(self, eventType, eventHandler):
    """Adds a handler for the given event type.

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class.

    Throws LookupError if the eventType is not valid.

    """

    if eventType not in self.EventHandlerMap:
    raise LookupError(eventType)
    if( not eventHandler in self.EventHandlerMap[eventType] ) :
    self.EventHandlerMap[eventType].append(eventHandler)

    def removeEventHandler(self, eventType, eventHandler):
    """Removes a handler for the given event type.

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class. It is an error if
    the given handler is not found in the list of installed handlers.

    Throws LookupError if the eventType is not valid.

    """
    if eventType not in self.EventHandlerMap:
    raise LookupError(eventType)
    self.EventHandlerMap[eventType].remove(eventHandler)

    def setEventHandler(self, eventType, eventHandler):
    """Removes all previously installed event handlers for the given
    event type and installs a new handler.

    A list of supported event types can be found in the initialization
    of EventHandlerMap in the CvEventManager class. This method is
    primarily useful for overriding, rather than extending, the default
    event handler functionality.

    Throws LookupError if the eventType is not valid.

    """
    if eventType not in self.EventHandlerMap:
    raise LookupError(eventType)
    self.EventHandlerMap[eventType] = [eventHandler]

    def setPopupHandler(self, eventType, popupHandler):
    """Removes all previously installed popup handlers for the given
    event type and installs a new handler.

    The eventType should be an integer. It must be unique with respect
    to the integers assigned to built in events. The popupHandler should
    be a list made up of (name, beginFunction, applyFunction). The name
    is used in debugging output. The begin and apply functions are invoked
    by beginEvent and applyEvent, respectively, to manage a popup dialog
    in response to the event.

    """
    self.Events[eventType] = popupHandler

    def handleEvent(self, argsList):
    """Handles events by calling all installed handlers."""
    self.origArgsList = argsList
    flagsIndex = len(argsList) - 6
    self.bDbg, self.bMultiPlayer, self.bAlt, self.bCtrl, self.bShift, self.bAllowCheats = argsList[flagsIndex:]
    eventType = argsList[0]
    return {
    "kbdEvent": self._handleConsumableEvent,
    "mouseEvent": self._handleConsumableEvent,
    "OnSave": self._handleOnSaveEvent,
    "OnLoad": self._handleOnLoadEvent
    }.get(eventType, self._handleDefaultEvent)(eventType, argsList[1:])

    def _handleDefaultEvent(self, eventType, argsList):
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    eventHandler(argsList[:len(argsList) - 6])

    def _handleConsumableEvent(self, eventType, argsList):
    """Handles events that can be consumed by the handlers, such as
    keyboard or mouse events.

    If a handler returns non-zero, processing is terminated, and no
    subsequent handlers are invoked.

    """
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    result = eventHandler(argsList[:len(argsList) - 6])
    if (result > 0):
    return result
    return 0

    # TODO: this probably needs to be more complex
    def _handleOnSaveEvent(self, eventType, argsList):
    """Handles OnSave events by concatenating the results obtained
    from each handler to form an overall consolidated save string.

    """
    result = ""
    if self.EventHandlerMap.has_key(eventType):
    for eventHandler in self.EventHandlerMap[eventType]:
    # the last 6 arguments are for internal use by handleEvent
    result = result + eventHandler(argsList[:len(argsList) - 6])
    return result

    # TODO: this probably needs to be more complex
    def _handleOnLoadEvent(self, eventType, argsList):
    """Handles OnLoad events."""
    return self._handleDefaultEvent(eventType, argsList)


    I tried several times to merge them but I always got the sam result :
    Game starts normal until it checks the Phyton files:( I got a ┬┤Traceback`Error and the log told me that the game can't find module CvEventInterface.Thats why I think its an Phytonproblem!?
     
  16. stolenrays

    stolenrays Deity

    Joined:
    Aug 2, 2009
    Messages:
    2,061
  17. Errants

    Errants Chieftain

    Joined:
    Jul 24, 2013
    Messages:
    5
    Necro'ing and bumping to also ask. I'd love for this, or something similar, to be integrated with BUG/BAT mod. Always struck me as dissonant that air can't earn exp outside of intercepts, and bombers are screwed period.
     
  18. vincentz

    vincentz Programmer

    Joined:
    Feb 4, 2009
    Messages:
    3,553
    Gender:
    Male
    Location:
    Denmark
    Im using it in mine. I can upload sourcecode if wanted. Pm me to remind me ;)
     

Share This Page