Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

obliterator #7

Merged
merged 9 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions wurst/foes/creeps/CreepAggro.wurst
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,18 @@ public function unit.enrage()
this.setVertexColor(225, 125, 125, 225)
this.setMoveSpeed(this.getMoveSpeed() + 75)
this.addBonus(Bonus.ATTACKSPEED, 25)

let eff = this.addEffect(Abilities.bloodLustTarget, AttachmentPoints.chest)

doAfter(1.) ->
eff.destr()

public function unit.addAggro(unit target, real amount)
interface AggroMergeFn<T>
Cokemonkey11 marked this conversation as resolved.
Show resolved Hide resolved
function apply(T curr, T new_) returns T

constant AggroMergeFn<real> ADDING_MERGE_FN = (curr, new_) -> curr + new_
constant AggroMergeFn<real> MAXING_MERGE_FN = (curr, new_) -> max(new_, curr)

public function unit.mergeAggro(unit target, real amount, AggroMergeFn<real> merge_fn)
let source = this
if not aggroMap.has(target)
aggroMap.put(target, new LinkedList<AggroEntry>())
Expand All @@ -56,7 +61,7 @@ public function unit.addAggro(unit target, real amount)
var found = false
for aggro in aggroList
if aggro.source == source
aggro.aggro += amount
aggro.aggro = merge_fn.apply(aggro.aggro, amount)
found = true
else
aggro.aggro *= 0.9
Expand All @@ -67,12 +72,18 @@ public function unit.addAggro(unit target, real amount)
aggroList.add(new AggroEntry(source, amount))

aggroList.sortWith((a, b) -> (b.aggro - a.aggro).toInt())

let lastAttack = lastAttackOrder.get(target)
if first != aggroList.getFirst() and not lastAttackOrder.has(target) or lastAttack < currentTime - 3
target.issueTargetOrderById(OrderIds.attack, source)
lastAttackOrder.put(target, currentTime)

public function unit.addAggro(unit target, real amount)
this.mergeAggro(target, amount, ADDING_MERGE_FN)

public function unit.maxAggro(unit target, real amount)
this.mergeAggro(target, amount, MAXING_MERGE_FN)

init
DamageEvent.addListener() ->
var source = DamageEvent.getSource()
Expand All @@ -91,14 +102,14 @@ init
let lastAttack = lastSuccessfulAttack.get(target)
if lastAttack + SECONDS_TO_RAGE < currentTime
target.enrage()

else if sourceOwner == ENEMY_PLAYER
lastSuccessfulAttack.put(source, currentTime)


onUnitIndex() ->
lastSuccessfulAttack.put(getIndexingUnit(), currentTime)

onUnitDeindex() ->
let u = getIndexingUnit()
lastAttackOrder.remove(u)
Expand Down
1 change: 1 addition & 0 deletions wurst/heroes/heroes/DemonLord/DemonLordHero.wurst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DemonLordIds
..addHeroAbility(HOWL_OF_TERROR_ID)
..addHeroAbility(DEMONIC_POWER_ID)
..addHeroAbility(CATACLYSM_ID)
..addNormalAbility(OBLITERATOR_ID)
..setStartingStrength(28)
..setStrengthPerLevel(3.4)
..setStartingAgility(15)
Expand Down
1 change: 1 addition & 0 deletions wurst/heroes/heroes/DemonLord/DemonLordIds.wurst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ public constant HOWL_OF_TERROR_ID = compiletime(ABIL_ID_GEN.next())
public constant FIRE_STORM_ID = compiletime(ABIL_ID_GEN.next())
public constant DEMONIC_POWER_ID = compiletime(ABIL_ID_GEN.next())
public constant CATACLYSM_ID = compiletime(ABIL_ID_GEN.next())
public constant OBLITERATOR_ID = compiletime(ABIL_ID_GEN.next())
83 changes: 83 additions & 0 deletions wurst/heroes/heroes/DemonLord/Obliterator.wurst
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package Obliterator

import AbilityTooltipGenerator
import Abilities
import BonusHandler
import ClosureForGroups
import CreepAggro
import DemonLordIds
import Icons
import PassiveAbilityPreset
import PresetBuffs

constant effect_description = "grants bonus attack speed, nearby creep aggro, and bonus damage against low HP units"
constant buffTupleBuff = compiletime(
createDummyBuffObject("Obliterator", effect_description, Icons.bTNFireRocks, Abilities.vampiricAura)
)

constant IntLevelClosure BONUS_ATTACK_SPEED = _ -> 50
constant RealLevelClosure CREEP_AGGRO = _ -> 600.
constant RealLevelClosure CREEP_AGGRO_RANGE = _ -> 400.
constant RealLevelClosure BONUS_HEALTH_THRESHOLD = _ -> .35
constant RealLevelClosure SLAY_RATIO = _ -> 0.05
constant RealLevelClosure SLAY_BONUS_DAMAGE_MULTIPLIER = _ -> 10.


public class ObliteratorBuff extends NormalBuff
Cokemonkey11 marked this conversation as resolved.
Show resolved Hide resolved
static constant FOREVER = 9999999.
construct()
super(FOREVER, buffTupleBuff)

override function update()
super.update()
if (this.target.getHP() / this.target.getMaxHP()) > BONUS_HEALTH_THRESHOLD.run(1)
Cokemonkey11 marked this conversation as resolved.
Show resolved Hide resolved
terminate()
if not done
forUnitsInRange(this.target.getPos(), CREEP_AGGRO_RANGE.run(1)) fog ->
if fog.isEnemyOf(this.target)
this.target.maxAggro(fog, CREEP_AGGRO.run(1))

override function onApply()
this.target.addBonus(Bonus.ATTACKSPEED, BONUS_ATTACK_SPEED.run(1).toReal())

override function onEnd()
if this.target != null
this.target.addBonus(Bonus.ATTACKSPEED, -BONUS_ATTACK_SPEED.run(1).toReal())


function unit.hpRatio() returns real
return this.getHP() / this.getMaxHP()


init
DamageEvent.addListener(1) ->
Overkane marked this conversation as resolved.
Show resolved Hide resolved
let target = DamageEvent.getTarget()
let source = DamageEvent.getSource()
if target.getTypeId() == DEMON_LORD_ID and target.hpRatio() < BONUS_HEALTH_THRESHOLD.run(1)
new ObliteratorBuff().apply(target)
else if (
source.getTypeId() == DEMON_LORD_ID
and source.hasBuff(ObliteratorBuff.typeId)
and target.hpRatio() < SLAY_RATIO.run(1)
)
DamageEvent.addAmount(DamageEvent.getAmount() * (SLAY_BONUS_DAMAGE_MULTIPLIER.run(1) - 1.))

@compiletime function genAbility()
let tooltip = new AbilityTooltipGenerator(
Targettype.PASSIVE,
"Passively " + effect_description + " when the Demon Lord has low HP."
)
new PassiveAbilityPreset(OBLITERATOR_ID, 1, tooltip)
..presetTargetsAllowed(_ -> "none")
Cokemonkey11 marked this conversation as resolved.
Show resolved Hide resolved
..presetButtonPosNormal(1, 1)
..presetButtonPosResearch(1, 0)
..setIconNormal(Icons.pASBTNFireRocks)
..tooltipStartListen()
..addTooltipProperty("Bonus Attack Speed", BONUS_ATTACK_SPEED)
..addTooltipProperty("Creep Aggro", CREEP_AGGRO)
..addTooltipProperty("Creep Aggro Range", CREEP_AGGRO_RANGE)
..addTooltipProperty("Health Threshold", BONUS_HEALTH_THRESHOLD)
..addTooltipProperty("Bonus Damage HP Threshold", SLAY_RATIO)
..addTooltipProperty("Bonus Damage Multiplier", SLAY_BONUS_DAMAGE_MULTIPLIER)
..setName("Obliterator")
..tooltipStopListen()
9 changes: 8 additions & 1 deletion wurst/players/PlayerData.wurst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import initlater WaveRewards
public constant ARENA_POINTS_THRESHOLD = 500

public constant pData = new IterableMap<player, PlayerData>
public constant pDataFromHeroType = new IterableMap<int, PlayerData>

public function player.getData() returns PlayerData
return pData.get(this)
Expand All @@ -26,6 +27,11 @@ public function maybe_hero.ifPresent(MaybeHeroIfPresent ifPresent)
return
ifPresent.if_present(this.hero)

public function maybeHeroFromHeroType(int type_id) returns maybe_hero
if pDataFromHeroType.has(type_id)
return pDataFromHeroType.get(type_id).getHero()
return maybe_hero(false, null)

public class PlayerData
private player p
private maybe_hero maybeHero
Expand All @@ -48,6 +54,7 @@ public class PlayerData

function setHero(Hero h)
this.maybeHero = maybe_hero(true, h)
pDataFromHeroType.put(h.actor.getTypeId(), this)

function getHero() returns maybe_hero
return this.maybeHero
Expand Down Expand Up @@ -138,7 +145,7 @@ public function initPlayers()
if honorShop.getOwner() == p
destroy honorShop.getEntity()
break

printTimed(p.getNameColored() + " has left the game", 15.)
printTimed("All players get " + expCompensationOnPlayerLeave.toString().color(COLOR_GOLD) + " experience and "
+ goldCompensationOnPlayerLeave.toString().color(COLOR_GOLD) + " gold as compensation.", 15.)
Expand Down