Xeno Research Facility v1
1984
ID:
158
Family ID:
Author:
Palandu
Rarity:
unique
Element:
iron
Attack Type:
Physical
Attack Range:
1200
Attack CD:
1.8
Damage:
1812-1812
Status:
Approved

Description:

Empowers you against the alien menace. Model credits: SirCoqaLot plus mOck and MasterCassim.
Sample Collection
Has a 25% chance to collect a tissue sample from a damaged creep. Once researched, it will provide a 5% bonus vs the race of that creep, through the Xeno Vulnerability Research aura. Maximum bonus per race is 25%. Whenever a different race is attacked, half of the research bonuses against all other races are lost.

Level Bonus:
+1% chance to collect sample
+1% maximum bonus per race
Xeno Vulnerability Research - Aura
Improves damage vs various creep races for all towers in 280 range. Improvement amount depends on the Sample Collection. Research results are published every 6 seconds and whenever a different race is attacked. Stops working in the Bonus Level.

Note: For this tower, research overrides any and all other race modifications. So the race bonuses of this tower reflect the bonuses given by this aura.
Download

Toggle Triggers

Header

    globals
        BuffType xeno_dummyAura
        BuffType xeno_undead
        BuffType xeno_magic
        BuffType xeno_nature
        BuffType xeno_orc
        BuffType xeno_humanoid
        
        hashtable xeno_raceBonusTable = InitHashtable()
    endglobals
    
    //halving and setting of all modifiers on base tower
    function xeno_ManageBonuses takes Tower tower, boolean isTypeChange, integer uid, integer currentCategory, integer currentBonus returns nothing
        local real currentRaceBonus
        local real idealBonus
        if isTypeChange then
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_ORC, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_ORC)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID)/2)
            //now restore the correct one :P
            call SaveInteger(xeno_raceBonusTable, uid, currentCategory, currentBonus)
        endif
        
        //now set the correct race bonuses for this tower
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_UNDEAD)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_UNDEAD, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_MAGIC)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_MAGIC, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_NATURE)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_NATURE, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_ORC))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_ORC)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_ORC, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_HUMANOID)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_HUMANOID, idealBonus - currentRaceBonus) //add the delta
        endif
    endfunction
    
    //this is where all the magic or rather research happens :P
    function xeno_BuffTowers takes Tower tower, boolean isTypeChange returns nothing
        local BuffType selectedBuff
        local integer powerLevel
        local integer uid = tower.getUID()
        local Iterate towersInAura
        local Unit nextTower
        
        set powerLevel = LoadInteger(xeno_raceBonusTable, uid, tower.userInt)
        set tower.userInt2 = tower.userInt  //save the race type of new buff
        
        if tower.userInt == CATEGORY_UNDEAD then
            set selectedBuff = xeno_undead
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Undead Research Published", tower, 50, 50, 50, 0)
            endif
        elseif tower.userInt == CATEGORY_MAGIC then
            set selectedBuff = xeno_magic
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Magic Research Published", tower, 0, 155, 0, 0)
            endif
        elseif tower.userInt == CATEGORY_NATURE then
            set selectedBuff = xeno_nature
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Nature Research Published", tower, 0, 155, 0, 0)
            endif
        elseif tower.userInt == CATEGORY_ORC then
            set selectedBuff = xeno_orc
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Orc Research Published", tower, 155, 0, 155, 0)
            endif
        elseif tower.userInt == CATEGORY_HUMANOID then
            set selectedBuff = xeno_humanoid
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Humanoid Research Published", tower, 0, 155, 155, 0)
            endif
        else
            //Probs a champ wave. Exit early.
            return
        endif
        
        set tower.userReal3 = -101           //reset the message display flag
        
        call xeno_ManageBonuses(tower, isTypeChange, uid, tower.userInt, powerLevel)
        
        //re-apply buffs / refresh aura
        if powerLevel > 0 then
            set towersInAura = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TOWERS, 315.0) //larger AoE needed as aura centre seems to be diff + collision problems
            loop
                set nextTower = towersInAura.next()
                exitwhen nextTower == 0
                if nextTower.getBuffOfType(xeno_dummyAura) != 0 and nextTower.getUID() != uid then //do not buff self
                    call selectedBuff.applyAdvanced(tower, nextTower, powerLevel, powerLevel, (6.5 / tower.getProp_BuffDuration())) //always 8.5 secs
                endif
            endloop
        endif
    endfunction
        
    //Do not remove or rename this function!
    //Put your initialization tasks here, this function will be called on map init
    private function init takes nothing returns nothing
        local Modifier m
        
        set xeno_undead = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_UNDEAD, 0.0, 0.001)
        call xeno_undead.setBuffModifier(m)
        
        set xeno_magic = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_MAGIC, 0.0, 0.001)
        call xeno_magic.setBuffModifier(m)
        
        set xeno_nature = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_NATURE, 0.0, 0.001)
        call xeno_nature.setBuffModifier(m)
        
        set xeno_orc = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_ORC, 0.0, 0.001)
        call xeno_orc.setBuffModifier(m)
        
        set xeno_humanoid = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_HUMANOID, 0.0, 0.001)
        call xeno_humanoid.setBuffModifier(m)
        
        set xeno_dummyAura = BuffType.createAuraEffectType(true)
        call xeno_dummyAura.setBuffIcon('@@0@@')
    endfunction

On Attack

ONATTACK_chance: 1.0 ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
    local Creep enemy

    if tower.userReal < 0 then
        return
    endif
    
    set enemy = Event.getTarget()
    
    if enemy.getSpawnLevel() > Game.getMaxLevel() then
        set tower.userReal = -101 //off switch
        set tower.userInt3 = 0
    endif

    set tower.userInt = enemy.getCategory()    //setting the last attacked type
    
    if tower.userInt != tower.userInt2 then    //last attacked is diff from the prev. last attacked, halve bonuses and change buffs
        call xeno_BuffTowers(tower, true)
    endif
endfunction

On Damage

ONDAMAGE_chance: 0.25 ONDAMAGE_chanceLevelAdd: 0.01
function onDamage takes Tower tower returns nothing
    local Creep enemy
    local integer i
    local integer index
    local integer uid
    
    if tower.userReal < 0 then
        return
    endif

    if not Event.isMainTarget() or Event.isSpellDamage() then
        return
    endif
    
    set uid = tower.getUID()
    set enemy = Event.getTarget()
    
    set index = enemy.getCategory()     //can technically use the onattack userInt....

    set i = LoadInteger(xeno_raceBonusTable, uid, index)
    
    if i < tower.userInt3 then
        call tower.getOwner().displaySmallFloatingText("Sample Collected", enemy, 200, 200, 200, 40.0)
        set i = IMinBJ(tower.userInt3, i + 50)
        call SaveInteger(xeno_raceBonusTable, uid, index, i)
        set tower.userReal3 = 101                        //flag to show the research message
    endif
endfunction

On Level Up

function onLevelUp takes Tower tower returns nothing
    set tower.userInt3 = 250 + tower.getLevel()*10   //bonus limit
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    local integer uid = tower.getUID()
    set tower.userInt = CATEGORY_OTHERS               //which creep type i attacked - that's the type i'll buff next
    set tower.userInt2 = CATEGORY_OTHERS              //memory of prev. attacked creep type
    set tower.userInt3 = 250                          //bonus limit
    set tower.userReal = 101                          //on-off switch. Tower should not work in bonus level. +ve = tower is on
    set tower.userReal3 = -101                        //flag to show the research message. +ve = message is on.
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD, 0)  //undead
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC, 0)  //magic
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE, 0)  //nature
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_ORC, 0)  //orc
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID, 0)  //humanoid
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_OTHERS, 0) //just to prevent a hashkey error
endfunction

On Tower Destruction

function onDestruct takes Tower tower returns nothing
    call FlushChildHashtable(xeno_raceBonusTable, tower.getUID())
endfunction

Periodic

PERIODIC_period: 6
function periodic takes Tower tower returns nothing
    if tower.userReal > 0 then
        call xeno_BuffTowers(tower, tower.userInt != tower.userInt2)
    endif
endfunction

Tower Aura

AURA_auraEffect: xeno_dummyAura AURA_power: 1 AURA_level: 1 AURA_auraRange: 280.0 AURA_targetType: TARGET_TYPE_TOWERS AURA_levelAdd: 1 AURA_powerAdd: 1 AURA_targetSelf: true