XML and Unit Gifting?

Avahz Darkwood

Emperor
Joined
Oct 26, 2001
Messages
1,220
Location
Behind You!!!!
Is there a way to allow one civ to gift a unit (to another civ) using the XML spell mechanics? Been working on a modular Mod and was wondering if this is possible? I know Kael took out the usual gifting function for balance reason, but this would only be for one civ at most. I want to keep it modular that is unless its already set up in the python files and I can use an XML function to call it up.

Also is the inactive Gifting function a part of the SDK, I could only find a portion of it in the python code.
 
I don't believe that an xml-only is capable of mimicking the disabled gifting mechanic. It just wouldn't be possible to determine which civ the unit would go to that way. However, a gift unit spell using a little python should be fairly easy to write.

edit: I don't have time to test it, but I think this spell would work:
Code:
in CIV4SpellInfos.xml:

        <SpellInfo>
            <Type>SPELL_GIFT_UNIT</Type>
            <Description>TXT_KEY_SPELL_GIFT_UNIT</Description>
            <Civilopedia>TXT_KEY_SPELL_PLACEHOLDER_PEDIA</Civilopedia>
            <Help>TXT_KEY_SPELL_GIFT_UNIT_HELP</Help>
            <bAbility>1</bAbility>
            <PyResult>spellGiftUnit(pCaster)</PyResult>
            <PyRequirement>reqGiftUnit(pCaster)</PyRequirement>
            <Effect>EFFECT_SPELL1</Effect>
            <Sound>AS3D_SPELL_CHARM_PERSON</Sound>
            <Button>Art/Interface/Buttons/Spells/Arena Battle.dds</Button>
        </SpellInfo>


-----------------
in CvSpellInterface.py:



def reqGiftUnit(caster):
	pPlot = caster.plot()
	if not pPlot.isOwned():
		return false
	if pPlot.getOwner() == caster.getOwner():
		return false
	if CyGame().isUnitClassMaxedOut(caster.getUnitClassType(), 0):
		return false
	eTeam = gc.getTeam(gc.getPlayer(caster.getOwner()).getTeam())
	i2Team = gc.getPlayer(pPlot.getOwner()).getTeam()
	if eTeam.isAtWar(i2Team):
		return false
	return true

def spellGiftUnit(caster):
	pPlot = caster.plot()
	pPlayer = gc.getPlayer()
	newUnit = pPlayer.initUnit(caster.getUnitType(), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
	newUnit.convert(pUnit)

Of course, you may want to put more restrictions on it. It also seems like it might be hard on the processor if every unit in the world could cast it. Limiting it to one civ could help. I'd probably also require it be cast in cities, just to cut down on the number of units that could cast it before calling the python.





The deactivated Gifting Function is in the SDK. All you have to do to activate it is to remove one return false; line in bool CvUnit::canGift(bool bTestVisible, bool bTestTransport)--and then recompile the DLL.
 
I don't believe it is.

It shouldn't really be a problem to copy such a small piece of code into CvSpellInterface.py though. You can add as many python spells there as you want as in that file and if they are never called by the xml they won't effect anything (so long as they don't contain errors that stop the fie from loading).
 
If you are really desperate to keep it modular, there might be a way.

Place the new python spells in a new file, let's call it darkwoodmod.py:
Code:
import CvPythonExtensions
gc = CvPythonExtensions.CyGlobalContext()

def reqGiftUnit(caster):
    pPlot = caster.plot()
    if not pPlot.isOwned():
        return False
    if pPlot.getOwner() == caster.getOwner():
        return False
    if CyGame().isUnitClassMaxedOut(caster.getUnitClassType(), 0):
        return False
    eTeam = gc.getTeam(gc.getPlayer(caster.getOwner()).getTeam())
    i2Team = gc.getPlayer(pPlot.getOwner()).getTeam()
    if eTeam.isAtWar(i2Team):
        return False
    return True

def spellGiftUnit(caster):
    pPlot = caster.plot()
    pPlayer = gc.getPlayer()
    newUnit = pPlayer.initUnit(caster.getUnitType(), caster.getX(), caster.getY(), CvPythonExtensions.UnitAITypes.NO_UNITAI, CvPythonExtensions.DirectionTypes.DIRECTION_SOUTH)
    newUnit.convert(pUnit)
I tried making sure all needed imports are there.

Technically this file can be placed anywhere, but then you'll have to modify the import path later. For now, just place it in the same directory as 'CvSpellInterface.py'. So long as nothing imports it, all it does is take up a few kb on your drive. And only your modular mod will know to import it.

Code:
in CIV4SpellInfos.xml:

        <SpellInfo>
            <Type>SPELL_GIFT_UNIT</Type>
            <Description>TXT_KEY_SPELL_GIFT_UNIT</Description>
            <Civilopedia>TXT_KEY_SPELL_PLACEHOLDER_PEDIA</Civilopedia>
            <Help>TXT_KEY_SPELL_GIFT_UNIT_HELP</Help>
            <bAbility>1</bAbility>
            <PyResult>import darkwoodmod;darkwoodmod.spellGiftUnit(pCaster)</PyResult>
            <PyRequirement>import darkwoodmod;darkwoodmod.reqGiftUnit(pCaster)</PyRequirement>
            <Effect>EFFECT_SPELL1</Effect>
            <Sound>AS3D_SPELL_CHARM_PERSON</Sound>
            <Button>Art/Interface/Buttons/Spells/Arena Battle.dds</Button>
        </SpellInfo>

I think you could actually remove 'import darkwoodmod;' from PyResult. PyRequirement will always be run first right?
 
Humm It would be nice if that would work. I really wanted something like this for my Hippus Mercs mod. Once Ice comes out I will surely give it a shot. I am only somewhat able to work with python. What I usually do is figure out how something works in game and try and clone it in some way. For example I have it were the Desert Shrine actually turns the city square for the Malikim(?) into a single tile of desert. Doing this gives them a racial bonus to defend their cities. I havent put this in a mod cause I use it myself and I would have to update it with each patch...
 
Heck if you all want to use it here is the code. All I did was modify Mulcarns Temples's code.

Code:
if iBuildingType == gc.getInfoTypeForString('BUILDING_DESERT_SHRINE'):
			iDesert = gc.getInfoTypeForString('TERRAIN_DESERT')
			iFlames = gc.getInfoTypeForString('FEATURE_FLAMES')
			iFloodPlains = gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS')
			iForest = gc.getInfoTypeForString('FEATURE_FOREST')
			iJungle = gc.getInfoTypeForString('FEATURE_JUNGLE')
			iScrub = gc.getInfoTypeForString('FEATURE_SCRUB')
			iSmoke = gc.getInfoTypeForString('IMPROVEMENT_SMOKE')
			iX = pCity.getX()
			iY = pCity.getY()
			for iiX in range(iX-0, iX+1, 1):
				for iiY in range(iY-0, iY+1, 1):
					pLoopPlot = CyMap().plot(iiX,iiY)
					if not pLoopPlot.isWater():
						pLoopPlot.setTerrainType(iDesert, True, True)
						if pLoopPlot.getImprovementType() == iSmoke:
							pLoopPlot.setImprovementType(-1)
						iFeature = pLoopPlot.getFeatureType()
						if iFeature == iForest:
							pLoopPlot.setFeatureType(iForest, 2)
						if iFeature == iJungle:
							pLoopPlot.setFeatureType(iForest, 2)
						if iFeature == iFlames:
							pLoopPlot.setFeatureType(-1, -1)
						if iFeature == iFloodPlains:
							pLoopPlot.setFeatureType(-1, -1)
						if iFeature == iScrub:
							pLoopPlot.setFeatureType(-1, -1)
			CyEngine().triggerEffect(gc.getInfoTypeForString('EFFECT_SCORCH'),pPlot.getPoint())

This would go into the CvEventManager.py file (this has only been used in FFA 2 Ver. 034
 
Top Bottom