And yet another Tower Defense — File Browser
AndyetanotherTowerDefensev1.0 / AndyetanotherTowerDefensev1.0 / tower / tower.mrc
tower.mrc — 109.64 KB — Download this file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; ## # # ## _____________________________
; # \/ \/ \/ # | ugliest ascii drawing ever |
; \_________/ ~~~~ / ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; | | |**| /
; | |¯| | \/
; | | | | /||\
; | ¯ | / || \
; | | /\
; | | / \
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
;
; And yet another tower defense game
;
;
; by visionz (charlotmartine at hotmail.com)
;
; type //tower to start, or use menu
;
;
; Copyright :
;
; This game, and all its original content is free
; to use for whatever you feel like. Rip it, modify
; it, claim it yours, change the credits; the only
; thing I ask is that you have fun doing it! If you
; would like to make a donation to support me, then
; you must be pretty stupid :)
;
; Thank you and have fun!
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; History
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 28 july 2009 : First public release
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Todo list
;
; - Implement "Score" system
; - Sort popups by zorder, change active popup zorder to highest
; - Implement save/continue
; - Add "Choose difficulty" somewhere (but where?)
;
; Known bugs
;
; - When selecting with mouse, if you go outside the window too fast while
; selecting, it will cause a drawrect error (doesnt cause any problem thought)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
menu menubar,status {
And yet another Tower defense
.Play : tower
.-
.Uninstall
..Unload it yourself, lazy ass : noop $time
}
alias tower {
; force game to quit if already running
if ($1 == -f) { td.unload }
if ($td.initGameEngine()) {
td.start
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc : init various parameters for the game engine
alias -l td.initGameEngine {
; already running?
if (!$hget(tower)) {
hmake tower 1000
hadd tower ticks 0
; clear the cache
drawpic -c
; fps handling stuff
hadd tower fps.last $td.ticks
hadd tower fps.fps n/a
hadd tower fps.count 0
; 1 = very easy
td.setDifficulty 1
hadd tower score 0
; various options
hadd tower show.health 1
hadd tower show.msg 1
hadd tower show.region 0
hadd tower show.zone 0
hadd tower show.tidzone 0
hadd tower show.range 1
hadd tower show.tlink 0
hadd tower opt.cleartool 0
hadd tower opt.playsounds 1
hadd tower debug 0
td.setZoneSize 108 129
td.setFont "courier new"
td.setWhite $rgb(235,250,255)
window -Bdfkop +fnt @tower 0 0 640 640
window -hpf @tbuf 0 0 640 640
window -hpf @toolset 0 0 400 400
return 1
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: unload all the stuff, close windows
alias -l td.unload {
unset %zone.w
unset %zone.h
unset %td.font
unset %td.white
unset %td.map_path
unset %td.timerId
.timerSpawnCreep off
.timerTower off
if ($hget(tower)) {
hfree tower
}
window -c @tower
window -c @tbuf
window -c @toolset
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: initialise zones
; parm : width, height
alias td.setZoneSize {
set %zone.w $1
set %zone.h $2
; min width/height is 20
if (%zone.w < 20) set %zone.w 20
if (%zone.h < 20) set %zone.h 20
; compute reachable zones for each tower
var %tid = $obj.getFirst(Tid)
while (%tid) {
td.computeRangeSections %tid
%tid = $obj.getNext(tid)
}
; update zone for creeps
var %cid = $obj.getFirst(cid)
while (%cid) {
td.updateCidZone %cid
%cid = $obj.getNext(cid)
}
}
alias -l td.setFont set %td.font $1-
alias -l td.setWhite set %td.white $1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: initialise stuff to start the level
; parm : level
alias -l td.initLevel {
td.setPause 0
td.setGameOver 0
hadd tower game.level $1
td.clearBuffer
var %i = 1, %count = 0
var %toolset = $replace($obj.getprop(map,$td.map).toolset,$chr(32),$null)
while ($gettok(%toolset,%i,44)) {
var %tool = $v1
var %file = $obj.getProp(tower,%tool).img
if ($isfile(%file)) {
drawpic -c @toolset $calc(%count * 48) 0 0 0 48 48 %file
}
else {
drawrect -rf @toolset $rgb(32,0,0) 1 $calc(%count * 48) 0 48 48
drawtext -r @toolset %td.white %td.font 12 $calc(%count * 48 + 2) 2 No Img
}
obj.new tool %tool
obj.setProp tool %tool pos %count
inc %count
inc %i
}
hadd tower toolset.count %count
; loaddebug
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
; parms: win x y text
alias td.drawText {
var %font = %td.font
var %fontsize = 12
var %color = %td.white
var %bold = 0
var %underline = 0
var %parms
var %func, %id, %ctrl
var %tok
var %x = $2, %y = $3, %text = $replace($+($4-,{end}),$chr(32),$chr(160)), %chunk
var %i = 1, %t = $numtok(%text,123)
var %fx = 0, %fxid
var %offx = 0, %offy = 0
while (%i <= %t) {
%tok = $gettok(%text,%i,123)
%ctrl = $gettok(%tok,1,125)
%func = $gettok(%ctrl,1,58)
%id = $gettok(%ctrl,2,58)
if (%func == f) %font = $qt($replace(%id,$chr(160),$chr(32)))
elseif (%func == s) %fontsize = %id
elseif (%func == rgb) %color = $td.parseColor(%id)
elseif (%func == fx) { %fx = $abs($calc(%fx - 1)) | %fxid = %id }
elseif (%func == b) { %bold = $abs($calc(%bold - 1)) }
elseif (%func == u) { %underline = $abs($calc(%underline - 1)) }
%chunk = $gettok(%tok,2,125)
if (%chunk) {
if (%fx) {
if (%fxid == 1) %offx = $calc(1 - $r(0,2))
elseif (%fxid == 2) %offy = $calc(1 - $r(0,2))
}
else {
%offx = 0
%offy = 0
}
if (%bold) %parms = -nor
else %parms = -nr
drawtext %parms $1 %color %font %fontsize $calc(%x + %offx) $calc(%y + %offy) %chunk
var %w = $width(%chunk,$noqt(%font),%fontsize,%bold)
if (%underline) {
var %h = $height(%chunk,$noqt(%font),%fontsize)
drawline -nr $1 %color 1 $calc(%x + %offx) $calc(%y + %offy + %h) $calc(%x + %offx + %w) $calc(%y + %offy + %h)
}
inc %x %w
}
inc %i
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: r, g, b
alias -l td.parseColor {
tokenize 44 $+($1-,$chr(44),0,$chr(44),0)
return $rgb($1,$2,$3)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.start {
window -a @tower
td.jumpToScene main
.timerTower 0 0 td.loop
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_id
; desc: select the tool used for building
alias -l td.selTool {
hadd tower tool.sel $1
hadd tower tool.w $obj.getProp(tower,$1).width
hadd tower tool.h $obj.getProp(tower,$1).height
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: scene
alias td.jumpToScene {
; when we change scene, close all popups
var %pop = $obj.getFirst(popup)
while (%pop) {
td.closePopup %pop
%pop = $obj.getNext(popup)
}
; initializes the scene
td.initScene $1
hadd tower scene $1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: scene
alias td.initScene {
if ($1 == main) {
hdel tower mdownl
hdel tower mdown
td.initcredits
if ($td.showPopup(menu,Menu,190,200,265,300,0)) {
td.addPopupButton menu newgame 40 40 160 40 $td.gfx(newgame.bmp) Start a new game
td.addPopupButton menu continue 40 85 160 40 $td.gfx(continue.bmp) Continue a previous game
td.addPopupButton menu options 40 130 160 40 $td.gfx(options.bmp) Options
td.addPopupButton menu quit 40 175 160 40 $td.gfx(quit.bmp) Quit
}
}
elseif ($1 == pause) {
if ($td.showPopup(pmenu,Pause menu,190,240,265,250,0)) {
td.addPopupButton pmenu resume 40 40 160 40 $td.gfx(resume.bmp) Resume your game
td.addPopupButton pmenu options 40 85 160 40 $td.gfx(options.bmp) Options
td.addPopupButton pmenu return 40 130 160 40 $td.gfx(quit.bmp) Return to main menu
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.loop {
var %f = $ticks
if ($td.onMouseClick(1) || $td.onMouseUClick) {
if ($td.hookPopup) {
hadd tower mouse.sclick 0
hadd tower mouse.uclick 0
}
}
; render the scene
td.render $hget(tower, scene)
var %popuphook = $hget(tower,hook_popup)
if (%popuphook) {
var %x = $calc($mouse.x - $hget(tower,hook_offx)))
var %y = $calc($mouse.y - $hget(tower,hook_offy)))
if (%x > 600) %x = 600
if (%y > 600) %y = 600
if (%x < -100) %x = -100
if (%y < -100) %y = -100
obj.setProp popup %popuphook x %x
obj.setProp popup %popuphook y %y
}
if ($td.onMouseUClick) hdel tower clickOn
hadd tower mouse.sclick 0
hadd tower mouse.uclick 0
; fps stuff
hinc tower fps.count
if ($calc($td.ticks - $hget(Tower,fps.last)) >= 2000) {
hadd tower fps.fps $calc($hget(tower,fps.count) / 2)
hadd tower fps.count 0
hadd tower fps.last $td.ticks
}
if (!$hget(tower,pause)) {
var %d = $calc($ticks - %f)
if (%d <= 0) %d = 12.4
hinc tower ticks $calc(%d + 3)
}
if ($hget(tower,scene) == end) td.unload
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.update {
var %gain = $hget(tower,self.gain)
if (%gain > 0) {
%cash = 1
if (%gain >= 25) {
%cash = $round($calc(%gain * 0.04),0)
}
hinc tower self.cash %cash
hdec tower self.gain %cash
}
; check if there's any creeps to spawn
if ($hget(tower, spawnCreep.n) > 0) {
; it is time to spawn a new creep?
if ($calc($td.ticks - $hget(tower, spawnCreep.last)) >= $obj.getProp(map,$td.map).SpawnInterval) {
td.spawnCid $hget(tower,spawnCreep.objId) $hget(tower,spawncreep.rid)
hdec tower spawnCreep.n
hadd tower spawnCreep.last $td.ticks
}
}
if (!$obj.count(cid) && !$hget(tower,spawnCreep.n)) {
var %next = $td.getTimeBeforeNextLevel()
if (%next <= 0) {
td.nextLevel
}
}
; update towers being build
var %tid = $obj.getFirst(buildingTid)
while (%tid) {
td.updateBuildProgress %tid
%tid = $obj.getNext(buildingTid)
}
; check for towers attack
var %tid = $obj.getFirst(readytid)
while (%tid) {
; check if it's time to attack
var %lastAttack = $calc($td.ticks - $obj.tid(%tid).lastAttack)
if (%lastAttack >= $calc($obj.tid(%tid).speed + $obj.tid(%tid).spe_mod)) {
if ($td.checkForTarget(%tid) > 0) {
obj.setProp tid %tid lastAttack $td.ticks
}
else {
; if the tower didnt attack for 2 seconds, put it to sleep
if (%lastAttack > 2000) {
td.goToSleep %tid
}
}
}
if ($hget(tower,debug)) {
; draw green rect around tower to show that it is awake
drawrect -nr @tower $rgb(0,255,0) 1 $obj.tid(%tid).screenX $obj.tid(%tid).screenY $obj.tid(%tid).screenW $obj.tid(%tid).screenH
}
%tid = $obj.getNext(readytid)
}
var %tid = $obj.getFirst(seltid)
while (%tid) {
if ($obj.tid(%tid).selected) {
td.drawTowerSelection %tid
if ($hget(tower,show.tlink)) {
td.renderTowerLinks %tid
}
}
%tid = $obj.getNext(seltid)
}
; unselect tool when right-clicking
if ($mouse.key & 16) hdel tower tool.sel
if ($td.onMouseClick(1)) {
; check if we're in build zone
if ($td.inBuildZone()) {
var %tool = $hget(tower,tool.sel)
if (%tool) {
var %tid = $td.buildTower($hget(tower,tool.sel), $toTile($mouse.x), $toTile($mouse.y))
if (%tid) {
td.updateTowerBuffer
if ($hget(tower,opt.cleartool)) {
; keep the tool selected if we hold ctrl while building
if (!$and($mouse.key,2)) {
hdel tower tool.sel
}
}
}
}
else {
if (!$and($mouse.key,2)) td.clearSelection
var %id = $td.getIdByCoords(tid,$mouse.x,$mouse.y)
if (%id) {
if ($obj.tid(%id).selected) {
if ($and($mouse.key,2)) {
td.unselectTower %id
td.populateComboList
}
}
else {
td.selectTower %id
td.populateComboList
}
if ($obj.count(seltid) > 0) {
td.showPopupSelTid
}
}
else {
hadd tower sel.active 1
hadd tower sel.rect.x $mouse.x
hadd tower sel.rect.y $mouse.y
}
}
}
}
elseif ($td.onMouseUClick) {
if ($hget(tower,sel.active)) {
td.selectAllTowersInMouseRect
hadd tower sel.active 0
}
}
if ($hget(tower,sel.active)) {
var %x1 = $td.min($hget(tower,sel.rect.x),$mouse.x), %y1 = $td.min($hget(tower,sel.rect.y),$mouse.y)
var %x2 = $td.max($hget(tower,sel.rect.x),$mouse.x), %y2 = $td.max($hget(tower,sel.rect.y),$mouse.y)
drawrect -nfir @tower $rgb(255,0,0) 1 %x1 %y1 $calc(%x2 - %x1) $calc(%y2 - %y1)
drawrect -nr @tower $rgb(0,0,0) 1 %x1 %y1 $calc(%x2 - %x1) $calc(%y2 - %y1)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.selectAllTowersInMouseRect {
var %x1 = $td.min($hget(tower,sel.rect.x),$mouse.x)
var %y1 = $td.min($hget(tower,sel.rect.y),$mouse.y)
var %x2 = $td.max($hget(tower,sel.rect.x),$mouse.x)
var %y2 = $td.max($hget(tower,sel.rect.y),$mouse.y)
var %tid = $obj.getFirst(Tid)
while (%tid) {
var %tidx = $obj.tid(%tid).centerX
var %tidy = $obj.tid(%tid).centerY
if ($inrect(%tidx,%tidy,%x1,%y1,$calc(%x2 - %x1),$calc(%y2 - %y1))) {
td.selectTower %tid
}
%tid = $obj.getNext(tid)
}
if ($obj.count(seltid) > 0) {
td.populateComboList
td.showPopupSelTid
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.min {
if ($1 < $2) return $1
return $2
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.max {
if ($1 > $2) return $1
return $2
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias -l td.renderTowerLinks {
var %link = $td.getLink($1)
var %x1 = $obj.tid($1).centerX
var %y1 = $obj.tid($1).centerY
var %tid = $obj.getFirst(%link)
while (%tid) {
var %x2 = $obj.tid(%tid).centerX
var %y2 = $obj.tid(%tid).centerY
drawline -rn @tower $rgb(0,255,255) 1 %x1 %y1 %x2 %y2
%tid = $obj.getNext(%link)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: popup_id callback_type callback_alias
alias -l td.setPopupCallback {
obj.setProp popup $1 $+(callback_,$2) $3
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
; desc:
alias -l td.selectTower {
; if not already selected
if (!$obj.tid($1).selected) {
obj.new seltid $1
obj.setProp tid $1 selected 1
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
; desc:
alias -l td.unselectTower {
; if selected
if ($obj.tid($1).selected) {
obj.delete seltid $1
obj.setProp tid $1 selected 0
if (!$obj.count(seltid)) {
td.closePopup seltid
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: unselect all selected towers
alias -l td.clearSelection {
var %id = $obj.getFirst(seltid)
while (%id) {
obj.setProp tid %id selected 0
%id = $obj.getNext(seltid)
}
obj.clear seltid
td.closePopup seltid
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.hookPopup {
; unhook the popup
if ($hget(tower,hook_popup)) {
if ($td.onMouseUClick) {
hadd tower hook_popup 0
}
}
var %id = $obj.getFirst(popup)
while (%id) {
var %x = $obj.getProp(popup,%id).x
var %y = $obj.getProp(popup,%id).y
var %w = $obj.getProp(popup,%id).w
var %h = $obj.getProp(popup,%id).h
if ($inrect($mouse.x,$mouse.y,%x,%y,%w,%h)) {
td.handlePopupMouse %id %x %y %w %h
return 1
}
%id = $obj.getNext(popup)
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.handlePopupMouse {
var %pop = $1
var %x = $2, %y = $3, %w = $4, %h = $5
var %type = $+(pctrl.,%pop)
var %ctrl = $obj.getFirst(%type)
while (%ctrl) {
var %rx = $calc($obj.getProp(%type,%ctrl).x + %x + 8)
var %ry = $calc($obj.getProp(%type,%ctrl).y + %y + 25)
var %rw = $obj.getProp(%type,%ctrl).w
var %rh = $obj.getProp(%type,%ctrl).h
if ($inrect($mouse.x,$mouse.y,%rx,%ry,%rw,%rh)) {
if ($td.onMouseClick(1)) hadd tower clickOn $+(%pop,.,%ctrl)
elseif ($td.onMouseUClick) {
if ($hget(tower,clickOn) == $+(%pop,.,%ctrl)) {
if (%ctrl == xclose) {
td.closePopup %pop
hadd tower hook_popup 0
hdel tower clickOn
return
}
else {
var %ctype = $obj.getProp(%type,%ctrl).type
if (%ctype == checkbox) {
td.switchValue %ctrl
}
elseif (%ctype == checklist) {
var %i = 0
var %itemx = $calc(%rx + 4)
var %items = $obj.getProp(%type,%ctrl).items
var %id = $obj.getFirst(%items)
while (%id) {
var %itemy = $calc(%ry + %i * 13 + 20)
if ($inrect($mouse.x,$mouse.y,%itemx,%itemy,$calc(%w - 20),12)) {
obj.setProp %type %ctrl selected %id
%id = 0
}
else {
%id = $obj.getNext(%items)
}
inc %i
}
}
else {
td.popupMouseClick %pop %ctrl
}
}
}
}
%ctrl = 0
}
else {
%ctrl = $obj.getNext(%type)
}
}
if ($td.onMouseUClick) hdel tower clickOn
if ($td.onMouseClick(1)) {
if (!$hget(tower,clickOn)) {
; in title?
if ($inrect($mouse.x,$mouse.y,%x,%y,%w,22)) {
hadd tower hook_popup %pop
hadd tower hook_offx $calc($mouse.x - %x)
hadd tower hook_offy $calc($mouse.y - %y)
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.popupMouseClick {
if ($1 == seltid) td.onMouseClickSelTid $2
elseif ($1 == menu) td.onMouseClickMenu $2
elseif ($1 == pmenu) td.onMouseClickPause $2
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.onMouseClickPause {
if ($1 == resume) {
td.setPause 0
}
elseif ($1 == options) {
td.showOptionsMenu
}
elseif ($1 == return) {
td.jumpToScene main
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.onMouseClickMenu {
; click on New game
if ($1 == newgame) {
if ($td.loadmap(test)) {
td.initLevel 0
td.jumpToScene game
}
}
; click on Continue
if ($1 == continue) {
echo -a continue
}
; click on Options
if ($1 == options) {
td.showOptionsMenu
}
; click on Quit
if ($1 == quit) {
td.jumpToScene end
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.onMouseClickSelTid {
; click on sell
if ($1 == sell) {
var %id = $obj.getFirst(seltid)
while (%id) {
td.sellTower %id
%id = $obj.getNext(seltid)
}
hadd tower hook_popup 0
}
; awake tower
if ($1 == Awake) {
var %id = $obj.getFirst(seltid)
while (%id) {
td.awakeTower %id
%id = $obj.getnext(seltid)
}
}
; click on upgrade
if ($1 == upgrade) {
if ($obj.count(seltid) > 1) {
var %combosel = $obj.getProp(pctrl.seltid,combos).selected
if (%combosel) {
if ($td.upgradeSelTidToCombo(%combosel)) {
td.clearSelection
hadd tower hook_popup 0
}
}
}
else {
var %id = $obj.getFirst(seltid)
if (%id) {
if ($td.upgradeTid(%id)) {
td.clearSelection
hadd tower hook_popup 0
}
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid, cid
alias -l td.attackCreep {
var %tid = $1
var %cid = $2
var %cx = $obj.cid(%cid).CenterX
var %cy = $obj.cid(%cid).CenterY
var %BeamSize = $calc($obj.tid(%tid).level + 1)
drawline -rn @tower %td.white %BeamSize $obj.tid(%tid).centerX $obj.tid(%tid).centerY %cx %cy
var %att_min = $obj.tid(%tid).att_min
var %att_max = $obj.tid(%tid).att_max
var %att = $calc($r(%att_min, %att_max) + $obj.tid(%tid).att_mod)
var %hp_left = $td.damageCreep(%tid,%cid,%att)
if (%hp_left > 0) {
; if the creep is not dead, check to see if we need to apply an effect
var %on_hit = $obj.tid(%tid).on_hit
if (%on_hit) {
if ($td.addEffectOnCid(%tid,%on_hit,%cid)) {
td.showFloatingText -fs %cx $calc(%cy - 16) 500 0 $obj.getProp(effect,%on_hit).name
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid cid att
alias td.damageCreep {
var %tid = $1
var %cid = $2
var %att = $calc($3)
if (%att != 0) {
var %hp = $obj.cid(%cid).hp
dec %hp %att
if (%hp < 0) %hp = 0
obj.setProp cid %cid hp %hp
if (%hp <= 0) {
var %cx = $obj.cid(%cid).CenterX
var %cy = $obj.cid(%cid).CenterY
if ($td.triggerEvent(onCreepKill,%cid,%tid)) {
var %wav = $obj.cid(%cid).sfxdie
if (%wav) td.playSound $td.path(%wav)
; the creep is dead! long live the tower!
var %gold = $td.addDiffBonus($obj.cid(%cid).gold)
if (%gold > 0) {
td.addGain %gold
}
; update the kill count for the tower
obj.incProp tid %tid killCount 1
if ($istok(15 40 70 115 150 250,$obj.tid(%tid).killcount,32)) {
td.addVeteranLevel %tid
td.showFloatingText -f $obj.tid(%tid).screenX $obj.tid(%tid).screenY 1500 0 Level up!
}
td.showFloatingText -fs %cx %cy 500 0 $td.goldToText(%Gold)
td.removeCreep %cid
}
}
return %hp
}
return 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms : gold
alias -l td.addDiffBonus {
var %per = $calc(($hget(tower,game.diff) - 2.5) / 2)
return $ceil($calc($1 + $1 * %per))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms : 1-6 (1 is very easy, 6 is impossible)
alias -l td.setDifficulty {
; very easy = 2.2
; easy = 2.4
; medium = 2.6
; hard = 2.8
; very hard = 3
; impossible = 3.5
var %diff = $calc($gettok(2.2 2.4 2.6 2.8 3 3.5,$1,32))
if (%diff == 0) %diff = 2.2
hadd tower game.diff %diff
hadd tower game.dlvl $1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
alias -l td.addVeteranLevel {
obj.incProp tid $1 Level 1
var %lvl = $obj.tid($1).level
; add level up bonuses
obj.incProp tid $1 att_mod $calc(%lvl * 5)
obj.incProp tid $1 spe_mod $calc(%lvl * -2)
; check if we're at the last level
if (%lvl == 6) {
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid, effectid, cid
alias -l td.addEffectOnCid {
var %tid = $1
var %effect = $2
var %cid = $3
if (!$obj.cid(%cid).on_effect) {
var %duration = $calc($obj.getProp(effect,%effect).duration)
if (%duration > 0) {
obj.incProp cid %cid damage_per_second $calc($obj.getProp(effect,%effect).damage_per_second)
obj.incProp cid %cid spe_mod $calc($obj.getProp(effect,%effect).on_hit_speed_mod)
obj.setProp cid %cid on_effect %tid
inc %td.timerId
.timerCidEff $+ %td.timerid -m 1 %duration td.removeEffectOnCid %tid %effect %cid
return 1
}
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid, effectid, cid
alias -l td.removeEffectOnCid {
var %tid = $1
var %effect = $2
var %cid = $3
if ($obj.cid(%cid).exists) {
obj.decProp cid %cid spe_mod %spe_mod $obj.getProp(effect,%effect).on_hit_speed_mod
obj.decProp cid %cid damage_per_second $obj.getProp(effect,%effect).damage_per_second
obj.setProp cid %cid on_effect 0
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: cid
; desc: remove the specified creep of the field
alias -l td.removeCreep {
; remove the creep from the region
obj.delete $obj.cid($1).zone $1
; free up memory
obj.delete cid $1
; if there is no more creeps, set the timer for the next level
if (!$obj.count(cid) && !$hget(tower, spawnCreep.n)) {
td.goToNextLevel
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.goToNextLevel {
; next level will start in x seconds
hadd tower game.nextlevel $calc($td.ticks + $obj.getProp(map,$td.map).timeBetweenLevel)
; at the end of the round, put all towers to sleep
var %tid = $obj.getFirst(tid)
while (%tid) {
if ($obj.tid(%tid).complete) {
td.goToSleep %tid
}
%tid = $obj.getNext(tid)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
; desc: Remove a tower
alias -l td.removeTid {
; remove links to other towers
var %tid = $obj.getFirst(tid)
while (%tid) {
td.unlinkTower $1 %tid
%tid = $obj.getNext(tid)
}
td.unselectTower $1
; update collision buffer
td.setTileState $obj.tid($1).x $obj.tid($1).y $obj.tid($1).w $obj.tid($1).h 0
; remove the tower from the ready list
obj.delete readytid $1
; remove the tower from the building list
obj.delete buildingtid $1
; remove the tower from the sleeplist of the zones
var %i = 1
var %zonelist = $obj.tid($1).zonelist
while ($gettok(%zonelist,%i,32)) {
obj.delete $+($v1,.sleep) $1
inc %i
}
; free memory
obj.delete tid $1
td.updateTowerBuffer
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
; desc: Sell the specified tower
alias -l td.sellTower {
var %refund = $td.getRefundAmount($1)
if (%refund > 0) {
td.addGain %refund
}
td.showFloatingText -fs $calc($obj.tid($1).screenX + $obj.tid($1).screenW / 2)) $obj.tid($1).screenY 500 0 $td.goldToText(%refund)
td.removeTid $1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias -l td.getRefundAmount {
var %sell = $obj.tid($1).sell
var %value = $obj.tid($1).value
return $int($calc(%value * %sell))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type x y
; desc: return id of a specified object type by screen coordinates
alias -l td.getIdByCoords {
var %id = $obj.getFirst($1)
while (%id) {
if ($inrect($2,$3,$obj.getProp($1,%id).ScreenX,$obj.getProp($1,%id).ScreenY,$obj.getProp($1,%id).ScreenW,$obj.getProp($1,%id).ScreenH)) {
return %id
}
%id = $obj.getNext($1)
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.playSound {
if ($1-) {
if ($hget(tower,opt.playsounds)) {
splay -w $1-
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_id region
; desc: order a creep to walk to a specified region
alias td.WalkCreepTo {
var %curreg = $obj.cid($1).walkTo
var %dx = $calc($obj.getProp(region,$2).CenterX - $obj.cid($1).CenterX)
var %dy = $calc($obj.getProp(region,$2).CenterY - $obj.cid($1).CenterY)
obj.setProp cid $1 imgdx $calc((1 + %dx / $abs(%dx)) * $obj.cid($1).imgnb)
if ($abs(%dy) < $obj.cid($1).h) obj.setProp cid $1 imgdy 1
else obj.setProp cid $1 imgdy $calc(1 + %dy / $abs(%dy))
obj.setProp cid $1 walkTo $2
obj.setProp cid $1 lastWalk $td.ticks
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
; desc: check if it needs to attack target
alias -l td.checkForTarget {
var %tid = $1
var %count = 0
if ($obj.count(cid) > 0) {
if ($obj.tid(%tid).sleeping == 0) {
var %i = 1
var %zonelist = $obj.tid(%tid).zonelist
var %target = $obj.tid(%tid).maxTarget
var %att_type = $obj.tid(%tid).target
while ($gettok(%zonelist,%i,32)) {
var %zone = $v1
var %cid = $obj.getFirst(%zone)
while (%cid) {
var %type = $obj.cid(%cid).type
if ($pos(%att_type,$+(:,%type,:)) > 0) {
if ($td.isInRange(%cid,%tid)) {
td.attackCreep %tid %cid
inc %count
dec %target
}
if (%target <= 0) {
return %count
}
}
else {
; tower can't attack that kind of creep (cant attack air, or ground...), so remove it from the list, and
; remove don't put it in sleeplist of any zone, since it will never be able to attack any creep for this level
td.gotoSleep %tid 0
return 0
}
%cid = $obj.getNext(%zone)
}
inc %i
}
}
}
return %count
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: cid, tid
; desc: return 1 if cid is in tower range of tid
alias -l td.isInRange {
var %range = $calc($obj.tid($2).range + $obj.tid($2).ran_mod)
return $inellipse($obj.cid($1).centerX,$obj.cid($1).centerY, $calc($obj.tid($2).centerX - %range), $calc($obj.tid($2).centerY - %range), $calc(%range * 2), $calc(%range * 2))
}
alias -l cid.getCenterX return $calc($obj.cid($1).x + ($obj.cid($1).w / 2))
alias -l cid.getCenterY return $calc($obj.cid($1).y + ($obj.cid($1).h / 2))
alias -l tid.getCenterX return $calc($obj.tid($1).screenX + ($obj.tid($1).screenW / 2))
alias -l tid.getCenterY return $calc($obj.tid($1).screenY + ($obj.tid($1).screenH / 2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: (0 or 1)
alias -l td.setPause {
if ($1) {
if (!$2) {
hadd tower oldscene $hget(tower,scene)
td.jumpToScene pause
}
td.pauseCidEffTimer pause
hadd tower pause 1
hadd tower blockBuilding 1
}
else {
if (!$2) {
var %oldscene = $hget(tower,oldscene)
if (%oldscene) {
td.jumpToScene $hget(tower,oldscene)
}
}
td.pauseCidEffTimer resume
hadd tower pause 0
hadd tower blockBuilding 0
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: pause or resume
alias -l td.pauseCidEffTimer {
var %switch = -p
if ($1 == resume) %switch = -r
var %i = $timer(0)
while (%i) {
var %name = $timer(%i)
if ($left(%name,6) == cideff) {
.timer $+ %name %switch
}
dec %i
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: (0 or 1)
alias -l td.setGameOver {
if ($1) {
hadd tower gameOver 1
td.setPause 1 x
td.jumptoScene gameover
}
else {
hadd tower gameOver 0
td.setPause 0 x
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.isGameOver {
return $hget(tower, gameOver)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: scene
alias -l td.render {
; clear window
drawrect -nrf @tower 0 1 0 0 640 640
if ($1 == main) td.renderMain
elseif ($1 == game) td.renderGame
elseif ($1 == pause) td.renderPause
elseif ($1 == gameover) td.renderGameOver
elseif ($1 == win) td.renderWin
var %tooltip = $hget(tower,tooltip)
if (%tooltip) {
td.showTooltip %tooltip
hdel tower tooltip
}
; refresh!
drawdot @tower
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderMain {
if ($calc($ticks - $hget(Tower,mdownl)) >= 25) {
hinc tower mdown
hadd tower mdownl $ticks
}
var %i = 1, %r
var %t = $hget(tower,mdown), %f = %t
if (%t > 53) %t = 53
var %cx = 466
var %cy = 70
var %x1 = $calc(%cx + ($cos(0) * 147))
var %y1 = $calc(%cy + ($sin(0) * 35))
while (%i <= %t) {
%r = $calc(%i / 40 * (3 * $pi))
var %x2 = $calc(%cx + $cos(%r) * (147 + %i / 2))
var %y2 = $calc(%cy + $sin(%r) * (35 + %i))
drawline -rn @tower %td.white 1 %x1 %y1 %x2 %y2
%x1 = %x2
%y1 = %y2
inc %i
}
td.renderPopups
td.drawtext @tower 30 40 {rgb:255,255,255}{f:courier new}{s:30}And yet another {rgb:196}{s:38}Tower Defense
var %id = $obj.getFirst(cred)
while (%id) {
if (%f >= $obj.getProp(cred,%id).go_at) {
var %vel = $obj.getProp(cred,%id).vel
inc %vel
if (%vel > 14) %vel = 14
var %y = $obj.getProp(cred,%id).y
inc %y %vel
if (%y >= $calc(640 - 25)) {
%y = $calc(640 - 25)
%vel = $calc(0 - %vel / 1.1)
if ($abs(%vel) < 1) {
%vel = 0
%y = $calc(640 - 25)
}
}
obj.setProp cred %id vel %vel
obj.setProp cred %id y %y
var %r = $abs($calc(255 * $sin($calc((%f + %id) / 12))))
var %x = $obj.getProp(cred,%id).x
drawtext -nr @tower $rgb(255,$calc(255 - %r),$calc(255 - %r)) %td.font 22 %x %y $obj.getProp(cred,%id).val
if ($inrect($mouse.x,$mouse.y,%x,$calc(%y - 2),14,24)) {
obj.setProp cred %id vel -20
}
}
%id = $obj.getNext(cred)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: shows options menu
alias td.showOptionsMenu {
if ($td.showPopup(options,Options,420,510,200,100,1)) {
td.addPopupCheckbox options show.health 0 0 200 12 Show creeps health bar
td.addPopupCheckbox options show.msg 0 13 200 12 Show floating messages
td.addPopupCheckbox options show.range 0 26 200 12 Show range
td.addPopupCheckbox options opt.cleartool 0 39 200 12 Clear tool after build
td.addPopupCheckbox options opt.playsounds 0 52 200 12 Play sounds
; td.addPopupCheckbox options show.region 0 26 200 12 Show regions
; td.addPopupCheckbox options show.zone 0 39 200 12 Show zones
; td.addPopupCheckbox options show.tidzone 0 52 200 12 Show tower's zone
; td.addPopupCheckbox options show.tlink 0 91 200 12 Show tower's link
}
}
alias -l td.renderWin {
drawtext -nor @tower %td.white %td.font 48 55 100 You are teh winner!
drawtext -nor @tower $rgb(255,180,0) webdings 256 175 240 %
if ($inrect($mouse.x,$mouse.y,585,615,100,20)) {
drawtext -nor @tower 255 %td.font 16 585 615 Menu
if ($td.onmouseclick(1)) {
td.jumptoScene main
}
}
else {
drawtext -nor @tower %td.white %td.font 16 585 615 Menu
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.switchValue hadd tower $1 $abs($calc($hget(tower,$1) - 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
alias td.initCredits {
var %me = $replace(created.by.visionz,.,$chr(160))
var %i = 1, %t = $len(%me)
while (%i <= %t) {
obj.new cred %i
obj.setprop cred %i val $mid(%me,%i,1)
obj.setProp cred %i vel 0
obj.setProp cred %i x $calc(440 + %i * 10)
obj.setProp cred %i y -10
obj.setProp cred %i go_at $calc(80 + %i * 4)
inc %i
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
; parms: id title x y w h showclose
alias td.showPopup {
if ($obj.exists(popup,$1)) {
td.closePopup $1
}
obj.clear $+(pctrl.,$1)
obj.new popup $1
; check if a previous position was saved
var %x = $hget(tower,$+(__save.,$1,.x))
var %y = $hget(tower,$+(__save.,$1,.y))
if (!%x) %x = $3
if (!%y) %y = $4
obj.setProp popup $1 title $2
obj.setProp popup $1 x %x
obj.setProp popup $1 y %y
obj.setProp popup $1 w $5
obj.setProp popup $1 h $6
if ($7) {
td.addPopupButton $1 xclose $calc($5 - 26) -21 14 14 $td.gfx(closepopup.bmp) Close
}
return 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
alias td.closePopup {
if ($obj.exists(popup,$1)) {
hadd tower $+(__save.,$1,.x) $obj.getProp(popup,$1).x
hadd tower $+(__save.,$1,.y) $obj.getProp(popup,$1).y
obj.delete popup $1
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderGame {
drawcopy -nr @tbuf 0 0 640 640 @tower 0 0
if ($hget(tower,show.region)) td.drawRegions $1
if ($hget(tower,show.zone)) td.renderZones
if ($hget(tower,show.tidzone)) td.renderTidZone
td.update
td.renderCreeps
td.drawMenus
td.drawMouse
td.renderFloatingText
td.renderConsole
td.renderPopups
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderZones {
var %topy = $td.build.y, %topx = $td.build.x
var %x = %topx, %w = $calc(%topx + $td.Build.W), %h = $calc(%topy + $td.Build.H)
while (%x <= %w) {
var %y = %topy
while (%y <= %h) {
var %zw = %zone.w
var %zh = %zone.h
if ($calc(%x + %zw) > %w) %zw = $calc(%w - %x)
if ($calc(%y + %zh) > %h) %zh = $calc(%h - %y)
drawrect -nr @tower $rgb(128,128,128) 1 %x %y $calc(%zw + 1) $calc(%zh + 1)
var %zone = $td.getZoneKey(%x,%y)
var %sleeplist = $+(%zone,.sleep)
drawtext -nr @tower $rgb(166,166,166) %td.font 12 $calc(%x + 2) $calc(%y + 2) %zone
drawtext -npr @tower $rgb(166,166,166) %td.font 12 $calc(%x + 2) $calc(%y + 14) Sleeplist: $obj.count(%sleeplist)
inc %y %zone.h
}
inc %x %zone.w
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderTidZone {
var %tid = $td.getIdByCoords(tid,$mouse.x,$mouse.y)
if (%tid) {
var %topy = $td.build.y
var %maxh = $td.build.h
var %zonelist = $obj.tid(%tid).zonelist
var %i = 1
while ($gettok(%zonelist,%i,32)) {
var %zone = $v1
var %n = $abs($calc($sin($calc($ticks / 170)) * 4))
var %x = $calc($td.build.x + $gettok(%zone,2,46) * %zone.w)
var %y = $calc($td.build.y + $gettok(%zone,3,46) * %zone.h)
var %w = %zone.w
var %h = %zone.h
if ($calc(%y + %h) > $calc(%topy + %maxh)) %h = $calc(%topy + %maxh - %y)
drawrect -nifr @tower $rgb(0,255,255) 1 %x %y $calc(%w + 1) $calc(%h + 1)
inc %i
}
drawrect -nrf @tower %td.white 1 10 5 500 25
drawrect -nr @tower $rgb(0,0,0) 1 10 5 500 25
drawtext -nr @tower $rgb(0,0,0) %td.font 12 14 9 > $replace(%zonelist,$chr(32),$chr(44) $+ $chr(160))
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderPopups {
var %id = $obj.getLast(popup)
while (%id) {
td.renderPopupWindow %id
%id = $obj.getPrev(popup)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderPopupWindow {
var %id = $1
var %x = $obj.getProp(popup,%id).x
var %y = $obj.getProp(popup,%id).y
var %w = $obj.getProp(popup,%id).w
var %h = $obj.getProp(popup,%id).h
var %title = $obj.getProp(popup,%id).title
if (!%title) %title = Popup
drawrect -nrf @tower %td.white 1 %x %y %w %h
drawrect -nr @tower $rgb(0,0,0) 1 %x %y %w %h
drawrect -nr @tower $rgb(0,0,0) 1 %x %y %w 22
drawtext -nor @tower $rgb(0,0,0) %td.font 16 $calc(%x + 6) $calc(%y + 3) %title
var %callback = $obj.getProp(popup,%id).callback_render
if (%callback) {
%callback $calc(%x + 8) $calc(%y + 25) $calc(%w - 14) $calc(%h - 30)
}
var %type = $+(pctrl.,%id)
var %ctrl = $obj.getFirst(%type)
while (%ctrl) {
td.renderPopupCtrl %id $calc(%x + 8) $calc(%y + 25) %type %ctrl
%ctrl = $obj.getNext(%type)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: abs_x abs_y type ctrl
alias -l td.renderPopupCtrl {
var %pop = $1, %ax = $2, %ay = $3, %type = $4, %ctrl = $5
var %ct = $obj.getProp(%type,%ctrl).type
var %x = $calc($obj.getProp(%type,%ctrl).x + %ax)
var %y = $calc($obj.getProp(%type,%ctrl).y + %ay)
var %w = $obj.getProp(%type,%ctrl).w
var %h = $obj.getProp(%type,%ctrl).h
var %clicked = 0
if (%ct == Button) {
if ($td.MouseDown(1)) {
if ($inrect($mouse.x,$mouse.y,%x,%y,%w,%h)) {
if ($hget(tower,clickOn) == $+(%pop,.,%ctrl)) {
%clicked = 1
}
}
}
if (%clicked) {
drawrect -nr @tower 0 1 $calc(%x + 1) $calc(%y + 1) $calc(%w - 1) $calc(%h - 1)
drawpic -cn @tower $calc(%x + 2) $calc(%y + 2) 0 0 $calc(%w - 2) $calc(%h - 2) $obj.getProp(%type,%ctrl).gfx
}
else {
drawpic -cn @tower %x %y $obj.getProp(%type,%ctrl).gfx
}
drawrect -nr @tower 0 1 %x %y %w %h
if ($inrect($mouse.x,$mouse.y,%x,%y,%w,%h)) {
drawrect -nr @tower 0 2 %x %y %w %h
hadd tower tooltip $obj.getProp(%type,%ctrl).tooltip
}
}
elseif (%ct == Checkbox) {
drawrect -nr @tower 0 1 %x %y 12 12
if ($hget(tower,%ctrl)) {
drawrect -nfr @tower 0 1 $calc(%x + 2) $calc(%y + 2) 8 8
}
; if ($inrect($mouse.x,$mouse.y,$calc(%x + 16),$calc(%y - 2),$calc(%w - 16),$calc(%h - 2))) {
; drawtext -nr @tower $rgb(255,0,0) %td.font 12 $calc(%x + 16) $calc(%y - 2) $obj.getProp(%type,%ctrl).text
; }
; else {
drawtext -nr @tower 0 %td.font 12 $calc(%x + 16) $calc(%y - 2) $obj.getProp(%type,%ctrl).text
; }
}
elseif (%ct == checklist) {
var %selid = $obj.getprop(%type,%ctrl).selected
drawrect -nr @tower 0 1 %x %y %w 17
drawtext -nr @tower $rgb(0,0,0) %td.font 12 $calc(%x + 4) %y $obj.getProp(%type,%ctrl).title
drawrect -nr @tower 0 1 %x $calc(%y + 16) %w $calc(%h - 16)
var %itemx = $calc(%x + 4)
var %i = 0
var %items = $obj.getProp(%type,%ctrl).items
var %id = $obj.getFirst(%items)
while (%id) {
var %itemy = $calc(%y + %i * 13 + 20)
drawrect -nr @tower 0 1 %itemx %itemy 12 12
drawtext -nr @tower 0 %td.font 12 $calc(%itemx + 16) $calc(%itemy - 2) $obj.getProp(%items,%id).desc
if (%id == %selid) {
drawrect -nfr @tower 0 1 $calc(%itemx + 2) $calc(%itemy + 2) 8 8
}
inc %i
%id = $obj.getNext(%items)
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.ShowPopupSelTid {
if ($td.showPopup(seltid,Tower info,10,100,192,186,1)) {
td.setPopupCallback seltid render td.renderTidSelection
var %selcount = $obj.count(seltid)
if (%selcount == 1) {
var %tid = $obj.getFirst(seltid)
if (%tid) {
var %tower = $obj.tid(%tid).upgrade
if ($obj.exists(tower,%tower)) {
td.addPopupButton seltid Upgrade 0 120 32 32 $td.gfx(upgrade.bmp) Upgrade to $obj.getProp(tower,%tower).name for $td.goldToText($obj.getProp(tower,%tower).cost)
}
td.addPopupButton seltid Awake 36 120 32 32 $td.gfx(awake.bmp) Click here to awake the tower manually
if ($obj.tid(%tid).canSell) {
td.addPopupButton seltid Sell 146 120 32 32 $td.gfx(sell.bmp) Sell tower for $td.goldToText($td.getRefundAmount(%tid))
}
}
}
else {
td.addPopupChecklist seltid combos 0 19 178 95 Available combos ( $+ $obj.count(combo_list) $+ )
var %combo = $obj.getFirst(combo_list)
while (%combo) {
var %tower = $obj.getProp(combo,%combo).tower
var %cost = $obj.getProp(tower,%tower).cost
td.addPopupChecklistItem seltid combos %combo $obj.getProp(combo,%combo).name ( $+ $td.goldtoText(%cost) $+ )
%combo = $obj.getNext(combo_list)
}
td.addPopupButton seltid Upgrade 0 120 32 32 $td.gfx(upgrade.bmp) Combine %selcount towers
td.addPopupButton seltid Awake 36 120 32 32 $td.gfx(awake.bmp) Click here to awake the towers manually
td.addPopupButton seltid Sell 146 120 32 32 $td.gfx(sell.bmp) Sell %selcount towers
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: popup checklist item desc
alias -l td.addPopupChecklistItem {
var %type = $+(pctrl.,$1)
var %ctrl = $2
var %items = $obj.getProp(%type,%ctrl).items
obj.new %items $3
obj.setProp %items $3 desc $4-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.addPopupChecklist {
var %type = $+(pctrl.,$1)
var %items = $+($1,.,$2,.it)
obj.clear %items
td.addPopupCtrl $1 $2 $3 $4 $5 $6
obj.setProp %type $2 type checklist
obj.setProp %type $2 items %items
obj.setProp %type $2 title $7-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.addPopupRadio {
var %type = $+(pctrl.,$1)
td.addPopupCtrl $1 $2 $3 $4 $5 $6
obj.setProp %type $2 type Checkbox
obj.setProp %type $2 text $7-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.addPopupCheckbox {
var %type = $+(pctrl.,$1)
td.addPopupCtrl $1 $2 $3 $4 $5 $6
obj.setProp %type $2 type Checkbox
obj.setProp %type $2 text $7-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.addPopupButton {
var %type = $+(pctrl.,$1)
td.addPopupCtrl $1 $2 $3 $4 $5 $6
obj.setProp %type $2 type Button
obj.setProp %type $2 gfx $7
obj.setProp %type $2 tooltip $8-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.addPopupCtrl {
var %type = $+(pctrl.,$1)
obj.new %type $2
obj.setProp %type $2 x $3
obj.setProp %type $2 y $4
obj.setProp %type $2 w $5
obj.setProp %type $2 h $6
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: x y w h
alias -l td.renderTidSelection {
var %x = $1
var %y = $2
var %w = $3
var %h = $4
var %count = $obj.count(seltid)
if (%count > 1) {
var %tidw = 32
var %tidh = 32
drawtext -nr @tower $rgb(0,0,0) %td.font 12 %x %y %count towers selected
if (%showTowerInfo) {
td.showTowerInfo %showTowerInfo $calc($mouse.x + 11) $calc($mouse.y + 21)
}
}
else {
var %seltid = $obj.getFirst(seltid)
if (%seltid) {
var %tidw = $obj.tid(%seltid).ScreenW
var %tidh = $obj.tid(%seltid).ScreenH
var %name = $obj.tid(%seltid).name
if ($hget(tower,debug)) %name = %name $+($chr(40),%seltid,$chr(41))
if (!%name) %name = No name
td.drawTid @tower %seltid %x %y
drawtext -nor @tower $rgb(0,0,0) %td.font 14 $calc(%x + %tidw + 8) %y %name
var %texty = $calc(%y + $obj.tid(%seltid).ScreenH + 2)
drawtext -nor @tower 0 %td.font 12 $calc(%x + 63) $calc(%y + 20) Stats
drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 0) Attack : $obj.tid(%seltid).att_text
drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 15) Range : $obj.tid(%seltid).range
drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 30) Speed : $obj.tid(%seltid).speed
var %att_mod = $obj.tid(%seltid).att_mod
var %ran_mod = $obj.tid(%seltid).ran_mod
var %spe_mod = $obj.tid(%seltid).spe_mod
if (%att_mod || %ran_mod || %spe_mod) {
drawtext -nor @tower 0 %td.font 12 $calc(%x + 120) $calc(%y + 20) Bonus
drawtext -nr @tower $rgb(0,0,0) %td.font 12 $calc(%x + 120) $calc(%texty + 0) $td.pad(%att_mod,5,$chr(160))
drawtext -nr @tower $rgb(0,0,0) %td.font 12 $calc(%x + 120) $calc(%texty + 15) $td.pad(%ran_mod,5,$chr(160))
drawtext -nr @tower $rgb(0,0,0) %td.font 12 $calc(%x + 120) $calc(%texty + 30) $td.pad(%spe_mod,5,$chr(160))
}
drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 45) Target : $replace($obj.tid(%seltid).target ,:,$chr(32))
; drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 60) Kills : $obj.tid(%seltid).killcount
drawtext -npr @tower $rgb(0,0,0) %td.font 12 %x $calc(%texty + 60) Level : $obj.tid(%seltid).level ( $+ $obj.tid(%seltid).killcount kills)
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: text,n,char
alias -l td.pad return $+($str($3,$calc($2 - $len($1))),$1)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: combo
; desc: upgrade selected tid to combo
alias -l td.upgradeSelTidToCombo {
var %combo = $1
var %tower = $obj.getProp(combo,%combo).tower
var %id = $obj.getFirst(seltid)
if (%id) {
var %oldx = $obj.tid(%id).x
var %oldy = $obj.tid(%id).y
var %kills = 0
var %value = 0
var %lowlevel = Undefined
; check if we have enough cash
if ($hget(tower,self.cash) >= $obj.getProp(tower,%tower).cost) {
while (%id) {
inc %kills $obj.tid(%id).killcount
inc %value $obj.tid(%id).value
if ($obj.tid(%id).level < %lowlevel) %lowlevel = $v1
td.removeTid %id
%id = $obj.getNext(seltid)
}
%id = $td.buildTower(%tower,%oldx,%oldy)
if (%id) {
obj.setProp tid %id killcount %kills
obj.incProp tid %id value %value
if (%lowlevel != Undefined) {
; var %i = 1
; while (%i <= %lowlevel) {
; td.addVeteranLevel %id
; inc %i
; }
}
return %id
}
}
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: msg
alias -l td.showTooltip {
var %msg = $1-
if (%msg) {
var %maxw = 200
var %textw = $width(%msg,$noqt(%td.font),12)
var %chunk
var %i = 1, %t = $wrap(%msg,$noqt(%td.font),12,%maxw,1,0)
var %rectx = $calc($mouse.x + 11)
var %recty = $calc($mouse.y + 21)
var %rectw = $calc(%textw + 10)
var %recth = $calc(%t * 12 + 8)
if (%rectw > %maxw) %rectw = %maxw
; keep the rect on screen
if ($calc(%rectx + %rectw) > 640) %rectx = $calc(640 - %rectw)
if ($calc(%recty + %recth) > 640) %recty = $calc(640 - %recth)
var %textx = $calc(%rectx + 4)
var %texty = $calc(%recty + 2)
drawrect -nrf @tower %td.white 1 %rectx %recty %rectw %recth
drawrect -nr @tower 0 1 %rectx %recty %rectw %recth
while (%i <= %t) {
%chunk = $wrap(%msg,$noqt(%td.font),12,%maxw,1,%i)
if (%chunk) {
drawtext -nr @tower $rgb(0,0,0) %td.font 12 %textx %texty %chunk
}
inc %texty 12
inc %i
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
alias td.drawTowerSelection {
var %id = $1
var %n = $abs($calc($sin($calc($ticks / 170)) * 4))
var %x = $calc($obj.tid(%id).ScreenX - %n)
var %y = $calc($obj.tid(%id).ScreenY - %n)
var %w = $calc($obj.tid(%id).ScreenW + %n * 2)
var %h = $calc($obj.tid(%id).ScreenH + %n * 2)
drawrect -nr @tower %td.white 2 %x %y %w %h
drawrect -nr @tower $rgb(0,0,0) 1 %x %y %w %h
if ($hget(tower,show.range)) {
var %range = $obj.tid(%id).range
drawrect -rne @tower $rgb(0,0,0) 1 $calc($obj.tid(%id).centerX - %range) $calc($obj.tid(%id).centerY - %range) $calc(2 * %range) $calc(2 * %range)
var %ran_mod = $obj.tid(%id).ran_mod
if (%ran_mod != 0) {
var %range = $calc(%range + %ran_mod)
drawrect -rne @tower $rgb(255,255,255) 1 $calc($obj.tid(%id).centerX - %range) $calc($obj.tid(%id).centerY - %range) $calc(2 * %range) $calc(2 * %range)
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderGameOver {
td.drawText @tower 150 70 {rgb:255,255,255}{s:64}Game {fx:2}{rgb:255}o{rgb:255,255,255}{fx:2}ver
drawtext -nr @tower %td.white %td.font 256 115 150 \
drawtext -nr @tower %td.white wingdings 256 215 150 L
drawtext -nr @tower %td.white %td.font 256 375 150 /
drawline -nr @tower %td.white 11 323 380 323 460
drawline -nr @tower %td.white 11 234 380 323 460
drawline -nr @tower %td.white 11 408 380 323 460
drawline -nr @tower $rgb(255,0,0) 11 0 460 700 460
td.drawtext @tower 440 400 {rgb:255,255,255}<<< this is you, {fx:2}hahaha{fx:2}
; drawText -nr @tower %td.white %td.font 24 145 500 Total points : $base($hget(tower,score),10,10,10)
if ($inrect($mouse.x,$mouse.y,$calc(640 - 75),$calc(640 - 32),75,32)) {
drawtext -nr @tower $rgb(255,0,0) %td.font 32 $calc(640 - 80) $calc(640 - 32) Menu
if ($td.mousedown(1)) {
td.jumpToScene main
}
}
else {
drawtext -nr @tower %td.white %td.font 32 $calc(640 - 80) $calc(640 - 32) Menu
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderPause {
td.drawtext @tower 100 100 {s:64}{rgb:255,255,255}G{fx:2}{rgb:255}a{rgb:255,255,255}{fx:2}me paused
td.renderPopups
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderCreeps {
var %cid = $obj.getLast(cid)
while (%cid) {
td.renderSingleCreep %cid
%cid = $obj.getPrev(cid)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderSingleCreep {
var %cid = $1
var %x = $obj.cid(%cid).x
var %y = $obj.cid(%cid).y
var %w = $obj.cid(%cid).w
var %h = $obj.cid(%cid).h
var %img = $obj.cid(%cid).img
var %pos = $obj.cid(%cid).imgpos
var %type = $obj.cid(%cid).type
var %speed = $calc($obj.cid(%cid).Speed + $obj.cid(%cid).spe_mod)
var %updateframe = $calc((8 - %speed) * 40)
if (%updateframe <= 70) %updateframe = 70
; it is time to update the animation ?
if ($calc($td.ticks - $obj.cid(%cid).imglu) > %updateframe) {
%pos = $calc((%pos + 1) % $obj.cid(%cid).imgnb)
obj.setProp cid %cid imgpos %pos
obj.setProp cid %cid imglu $td.ticks
}
var %WalkInterval = 50
var %lastWalk = $calc($td.ticks - $obj.cid(%cid).lastWalk)
; it is time to walk?
if (%lastWalk >= %WalkInterval) {
var %region = $obj.cid(%cid).walkTo
if (%region) {
; debug
if (!$hget(tower,stopCreep)) {
; compensate for laggy machine
; var %ratio = $calc((%lastWalk / %WalkInterval) * ($obj.cid(%cid).Speed + $obj.cid(%cid).spe_mod))
var %ratio = %speed
var %tmpX = $calc($obj.getProp(region,%region).CenterX - $obj.cid(%cid).centerX)
var %tmpY = $calc($obj.getProp(region,%region).CenterY - $obj.cid(%cid).centerY)
var %tot = $calc($abs(%tmpX) + $abs(%tmpY))
var %fx = $calc(%x + %tmpX / %tot * %ratio)
var %fy = $calc(%y + %tmpY / %tot * %ratio)
; if (!$td.creepCollide(%fx,%fy,%cid)) {
td.moveCreep %cid %fx %fy
; }
}
obj.setProp cid %cid lastWalk $td.ticks
}
}
if (%type == air) {
; drop shadow
var %h2 = $calc(%h / 5)
var %w2 = $calc(%w / 5)
drawrect -nref @tower $rgb(32,32,32) 1 $calc(%x + %w2) $calc(%y + %h2) $calc(%w - %w2 * 2) $calc(%h - %h2 * 2)
dec %y 20
}
var %imgdx = $calc(($obj.cid(%cid).imgdx + %pos) * %w)
var %imgdy = $calc($obj.cid(%cid).imgdy * %h)
; drawpic -ctn @tower $rgb(255,0,255) %x %y $calc(%w * %pos) 0 %w %h %img
drawpic -ctn @tower $rgb(255,0,255) %x %y %imgdx %imgdy %w %h %img
if ($hget(tower,show.health)) {
td.showCidHealthBar %cid %x $calc(%y - 5) %w 4
}
; check on which region the creep is standing
var %reg = $td.getRegionIdByCoords($obj.cid(%cid).CenterX, $obj.cid(%cid).centerY)
if (%reg) {
if ($obj.cid(%cid).onRegion != %reg) {
obj.setProp cid %cid onRegion %reg
; is the creep on the region it was suppose to go?
if (%reg == $obj.cid(%cid).walkTo) {
if ($td.triggerEvent(onCreepReachRegion,%cid,%reg)) {
var %next = $td.getNextRegionInPath(%reg)
if (%next) {
; order the creep to move to the next region in the path
td.WalkCreepTo %cid %next
}
else {
; there is no more region in the path, so it means that the creep has reached the exit!
td.substLives $obj.cid(%cid).lifeCost
td.removeCreep %cid
}
}
}
}
}
else obj.setProp cid %cid onRegion
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: number_of_lives
alias -l td.substLives {
var %lives = $1
if (%lives > 0) {
td.playSound $td.path($obj.getProp(map,$td.map).sfxLoseLife)
hdec tower self.lives %lives
if ($hget(tower,self.lives) <= 0) {
hadd tower self.lives 0
; if not already game over
if (!$td.isGameOver) {
.timer 1 2 td.setGameOver 1
}
}
else {
td.showFloatingText -n 200 50 1000 0 Carefull, you've just lost %lives $iif(%lives > 1,lives,life) $+ !
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.getNextRegionInPath {
return $obj.getProp(walkPath,$1).next
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: cid, x, y, w, h
alias -l td.showCidHealthBar {
var %hp = $obj.cid($1).hp
var %maxhp = $obj.cid($1).maxhp
var %pbar = $calc(%hp / %maxhp * $4)
drawrect -nrf @tower $rgb(0,255,0) 1 $2 $calc($3 - 5) %pbar $5
drawrect -nr @tower $rgb(0,0,0) 1 $2 $calc($3 - 5) $4 $5
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.renderConsole {
if ($hget(tower,__console.show)) {
var %x = $calc($td.build.x + 10)
var %y = $calc($td.build.y + $td.build.h - 20)
var %w = $calc($td.build.w - 20)
var %h = 20
drawrect -nfr @tower %td.white 1 %x %y %w %h
drawrect -nr @tower $rgb(0,0,0) 1 %x %y %w %h
var %text = $hget(tower,__console.text)
if ($len(%text) > 0) {
drawtext -nr @tower $rgb(0,0,0) %td.font 12 $calc(%x + 4) $calc(%y + 2) %text
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: map_name
alias -l td.loadmap {
var %map = $1
set %td.map_path $shortfn($+($scriptdirmaps\,%map,\))
var %path = $shortfn($+(%td.map_path,%map,.txt))
var %in = 0
var %name, %type, %n
var %ok
; file exists?
%ok = $isfile(%path)
if (%ok) {
obj.clear
var %size = $file(%path).size
; set the current map
hadd tower __currentmap $1
if ($fopen(Tdmap)) .fclose tdmap
.fopen tdmap %path
; read the whole file
while (!$feof(tdmap) && %ok) {
var %line = $fread(tdmap)
if ($numtok(%line,32) > 0) {
tokenize 32 %line
; don't consider comments line (starts with ;)
if ($mid($1,1,1) != $chr(59)) {
if (%in) {
; check for end brackets "}"
if ($1 == $chr(125)) {
if (%type == event) {
; set the number of lines that the event contains
obj.setProp %type %name count %n
}
%in = 0
}
else {
if (%type == event) {
; replace Tabs by spaces
var %text = $replace($1-,$chr(9),$chr(32))
if ($len($remove(%text,$chr(32))) > 0) {
obj.setProp %type %name %n %text
inc %n
}
}
else {
; get all the text after the "="
obj.setProp %type %name $1 $($gettok($3-,1,59),2)
}
}
}
else {
%type = $1
%name = $2
%n = 1
; filter objects type, to be sure that its valid
var %valid_objects = :map:creep:region:tower:event:combo:effect:
if ($pos(%valid_objects,$+(:,%type,:)) > 0) {
%in = 1
obj.new %type %name
if ($3 == : && $4 == use) {
; copy $5 properties in %name
td.copyObjectProperties %type %name $5
}
}
else {
td.showError Invalid object's type : %type
%ok = 0
}
}
}
}
}
.fclose tdmap
if (%ok) {
if ($td.isLoadedMapValid(%map)) {
; precompute stuff for towers
var %tower = $obj.getFirst(tower)
while (%tower) {
td.initTower %tower
%tower = $obj.getNext(Tower)
}
; update collision buffer with regions
var %name = $obj.getFirst(region)
while (%name) {
if (!$obj.getProp(region,%name).build) {
var %x = $obj.getProp(region,%name).x
var %y = $obj.getProp(region,%name).y
var %w = $obj.getProp(region,%name).width
var %h = $obj.getProp(region,%name).height
obj.setProp region %name CenterX $calc($topix(%x) + $topix(%w) / 2)
obj.setProp region %name CenterY $calc($topix(%y) + $topix(%h) / 2)
td.setTileState %x %y %w %h 1 %name
}
%name = $obj.getNext(region)
}
; clear, or else cash keeps stacking if you quit and start a new game
hadd tower self.cash 0
hadd tower self.gain 0
td.addGain $obj.getProp(map,%map).cash
hadd tower self.lives $obj.getProp(map,%map).lives
; set the walking path
var %reglist = $remove($obj.getProp(map,%map).WalkPath,$chr(32))
var %i = 1, %region
while ($gettok(%reglist,%i,44)) {
%region = $v1
obj.new walkPath %region
obj.setProp walkPath %region next $gettok(%reglist,$calc(%i + 1),44)
inc %i
}
; set the timer for next level
hadd tower game.nextLevel $calc($td.ticks + $obj.getProp(map,$td.map).timeBetweenLevel)
}
else {
%ok = 0
}
}
}
if (%ok) {
if (!$td.triggerEvent(onInit)) {
%ok = 0
}
}
return %ok
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tower
alias -l td.initTower {
var %id = $1
var %img = $obj.getProp(tower,%id).img
if (%img) obj.setProp tower %id img $td.path(%img)
; calc size in pixel
obj.setProp tower %id ScreenW $topix($obj.getProp(tower,%id).width)
obj.setProp tower %id ScreenH $topix($obj.getProp(tower,%id).height)
var %list = :
; check for combo possibilities
var %com = $obj.getFirst(combo)
while (%com) {
var %require = $remove($obj.getProp(combo,%com).require,$chr(32))
if ($istok(%require,%id,44)) {
%list = $+(%list,%com,:)
}
%com = $obj.getNext(%com)
}
obj.setProp tower %id combo_list %list
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: map_id
; desc: check if the loaded map is valid
alias -l td.isLoadedMapValid {
var %map = $1
var %ok = 1
; validate creeps
if ($obj.count(creep) > 0) {
var %id = $obj.getFirst(creep)
while (%id) {
; if there is an image, check if it exists
var %img = $obj.getProp(creep,%id).img
if (%img) {
if (!$isfile($td.path(%img))) {
td.showError Invalid creep image for $+(',%id,'.) Img: $+(',$obj.getProp(creep,%id).img,')
%ok = 0
}
}
%id = $obj.getNext(creep)
}
}
else {
td.showError You need at least 1 creep type
%ok = 0
}
; validate towers
if ($obj.count(Tower) > 0) {
var %id = $obj.getFirst(tower)
while (%id) {
var %w = $calc($obj.getProp(tower,%id).width)
var %h = $calc($obj.getProp(tower,%id).height)
if (%w < 1 || %w > 2 || %h < 1 || %h > 2) {
td.showError Invalid tower size for $+(',%id,'.) Width = %w Height = %h
%ok = 0
}
; if there is an image, check if it exists
var %img = $obj.getProp(tower,%id).img
if (%img) {
if (!$isfile($td.path(%img))) {
td.showError Invalid tower image for $+(',%id,'.) Img: $+(',%img,')
%ok = 0
}
}
; if there is an upgrade, check if it exists
var %upgr = $obj.getProp(tower,%id).upgrade
if (%upgr) {
if (!$obj.exists(tower,%upgr)) {
td.showError Invalid upgrade tower for $+(',%id,'.) Upgrade: $+(',%upgr,')
%ok = 0
}
}
var %range = $obj.getProp(tower,%id).range
if (!%range) {
td.showError Invalid tower range for $+(',%id,'.) Range: $(',%range,')
%ok = 0
}
%id = $obj.getNext(tower)
}
}
else {
td.showError You need at least 1 tower type
%ok = 0
}
; A valid map needs at least 2 regions
if ($obj.count(region) < 2) {
td.showError You need at least 2 regions
%ok = 0
}
; check to see if every regions in walkpath really exists
var %reglist = $remove($obj.getProp(map,%map).WalkPath,$chr(32))
var %i = 1, %region
while ($gettok(%reglist,%i,44)) {
%region = $v1
if (!$obj.exists(region,%region)) {
td.showError Undefined region $+(',%region,') in WalkPath
%ok = 0
}
inc %i
}
var %combo = $obj.getFirst(combo)
while (%combo) {
var %tower = $obj.getProp(combo,%combo).tower
if (!$obj.exists(tower,%tower)) {
td.showError Tower $+(',%tower,') doesn't exists for combo $(',%combo,')
%ok = 0
}
%combo = $obj.getNext(combo)
}
return %ok
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: trigger_name
; desc: trigger an event using user defined event in the map definition
alias -l td.triggerEvent {
; find the user defined event name
var %name = $($+($,obj.getProp(map,$td.map).,$1),2)
var %ret = 1
if (%name) %ret = $td.runEvent(%name,$2-)
return %ret
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: event_id
; desc: run an user defined event
alias -l td.runEvent {
var %name = $1
var %retval = 1
if ($td.initParser(%name)) {
var %i = 1, %comm
var %n = $obj.getProp(event, %name).count
tokenize 32 $2-
while (%i <= %n) {
%comm = $hget(tower,$+(obj.event.,%name,.,%i))
if ($len(%comm) > 0) {
; do we have to execute this command?
if ($td.evalExec(%comm,$1-)) {
if (%comm == return) {
; break the execution of the script
%i = %n
%retval = $gettok(%comm,2,32)
}
else {
$(%comm,2)
}
}
}
inc %i
}
td.unloadParser
}
return %retval
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.initParser {
set %parser.skip 0
set %parser.lvl 0
set %parser.slv 0
return 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.unloadParser {
unset %parser.skip
unset %parser.lvl
unset %parser.slv
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: command, parameters
; desc: check is a command line has to be executed
alias -l td.evalExec {
var %comm = $1
var %f = $gettok(%comm,1,32)
var %r = 0
tokenize 32 $2-
if (%f == if) {
inc %parser.lvl
if (!%parser.skip) {
if (!$td.checkCondition(%comm, $1-)) {
inc %parser.skip
%parser.slv = %parser.lvl
}
}
}
elseif (%f == else) {
if (%parser.skip > 0) {
if (%parser.lvl <= %parser.slv) {
dec %parser.skip
}
}
else {
inc %parser.skip
}
}
elseif (%f == endif) {
if (%parser.lvl <= %parser.slv) {
if (%parser.skip > 0) {
dec %parser.skip
}
}
dec %parser.lvl
}
else {
if (%parser.skip == 0) {
%r = 1
}
}
return %r
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: crappy condition checker
alias -l td.checkCondition {
var %cond = $1
tokenize 32 $2-
var %a = $remove(%cond,if $chr(40), $chr(41) then)
var %a = $replace(%a,$chr(40),$+($chr(40),$chr(32)),$chr(41),$+($chr(32),$chr(41)))
var %r = $ $+ iif( %a ,1,0)
return $eval(%r,2)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: event_name
; desc: run an event, used to call events in maps event
alias -l td.callEvent {
td.runEvent $1-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: type, dest, src
alias -l td.copyObjectProperties {
; copy src object's properties into destination
var %type = $1
var %dest = $2
var %src = $3
var %wild = $+(obj.,%type,.,%src,.*)
var %i = 1, %t = $hfind(tower,%wild,0,w)
while (%i <= %t) {
var %key = $hfind(tower,%wild,%i,w)
var %val = $hget(tower,%key)
obj.setProp %type %dest $gettok(%key,4,$asc(.)) %val
inc %i
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: return a random object id
alias -l obj.randomId {
return $r(1,$calc(2^32))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: type
alias -l obj.getNextId {
var %id = $calc($hget(tower,$+(obj.,$1,.nextid)) + 1)
hinc tower $+(obj.,$1,.nextid)
return %id
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l obj.clear {
if ($1) {
hdel -w tower $+(obj.,$1,.*)
}
else {
hdel -w tower $+(obj.,*)
hdel -w tower $+(map.,*)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: type, name
; desc: create a new object
alias -l obj.new2 {
if (!$hget(tower,$+(obj.,$1,.,$2,.exists))) {
hadd tower $+(obj.,$1,.,$2,.exists) 1
if (!$hget(tower,$+(obj.,$1,.first))) {
hadd tower $+(obj.,$1,.first) $2
}
var %last = $hget(tower,$+(obj.,$1,.last))
if (%last) {
hadd tower $+(obj.,$1,.,%last,.onext) $2
hadd tower $+(obj.,$1,.,$2,.oprev) %last
}
hadd tower $+(obj.,$1,.last) $2
hinc tower $+(obj.,$1,.count)
return 1
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: type, name
alias -l obj.delete2 {
var %prev = $hget(tower,$+(obj.,$1,.,$2,.oprev))
var %next = $hget(tower,$+(obj.,$1,.,$2,.onext))
; if we flush first object, we need to set the new 'first object'
if ($hget(tower,$+(obj.,$1,.first)) == $2) {
hadd tower $+(obj.,$1,.first) %next
}
; if we flush last object, we need to set the new 'last object'
if ($hget(tower,$+(obj.,$1,.last)) == $2) {
hadd tower $+(obj.,$1,.last) %prev
}
; fix link between previous and next object
if (%prev) hadd tower $+(obj.,$1,.,%prev,.onext) %next
if (%next) hadd tower $+(obj.,$1,.,%next,.oprev) %prev
; fix cursor for obj.getNext()
hadd tower $+(obj.,$1,.readnext) %next
; flush the old object data
hdel -w tower $+(obj.,$1,.,$2,.*)
hdec tower $+(obj.,$1,.count) 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the first id of the specified object type
alias obj.getFirst2 {
var %first = $hget(tower,$+(obj.,$1,.first))
hadd tower $+(obj.,$1,.readnext) $hget(tower,$+(obj.,$1,.,%first,.onext))
return %first
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the next id of the specified object type (after reading with $obj.getFirst())
alias -l obj.getNext2 {
var %cur = $hget(tower,$+(obj.,$1,.readnext))
if ($hget(tower,$+(obj.,$1,.last)) == %cur) {
hdel tower $+(obj.,$1,.readnext)
}
else {
hadd tower $+(obj.,$1,.readnext) $hget(tower,$+(obj.,$1,.,%cur,.onext))
}
return %cur
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: type, name
; desc: create a new object
alias -l obj.new {
if (!$hget(tower,$+(obj.,$1,.,$2,.exists))) {
hadd tower $+(obj.,$1,.,$2,.exists) 1
hadd tower $+(obj.,$1,.elem) $+($hget(tower,$+(obj.,$1,.elem)),:,$2)
hinc tower $+(obj.,$1,.count)
return 1
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: type, id
alias obj.delete {
if ($hget(tower,$+(obj.,$1,.,$2,.exists))) {
hadd tower $+(obj.,$1,.elem) $remtok($hget(tower,$+(obj.,$1,.elem)),$2,1,58)
; fix cursor for obj.getNext()
hdec tower $+(obj.,$1,.next)
; flush the old object data
hdel -w tower $+(obj.,$1,.,$2,.*)
hdec tower $+(obj.,$1,.count) 1
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the first id of the specified object type
alias obj.getFirst {
hadd tower $+(obj.,$1,.next) 2
return $gettok($hget(tower,$+(obj.,$1,.elem)),1,58)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the next id of the specified object type (after reading with $obj.getFirst())
alias -l obj.getNext {
var %next = $hget(tower,$+(obj.,$1,.next))
hinc tower $+(obj.,$1,.next)
return $gettok($hget(tower,$+(obj.,$1,.elem)),%next,58)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the last id of the specified object type
alias obj.getLast {
var %count = $obj.count($1)
hadd tower $+(obj.,$1,.prev) $calc(%count - 1)
return $gettok($hget(tower,$+(obj.,$1,.elem)),-1,58)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_type
; desc: return the previous id of the specified object type (after reading with obj.getLast)
alias obj.getPrev {
var %prev = $hget(tower,$+(obj.,$1,.prev))
if (%prev > 0) {
hdec tower $+(obj.,$1,.prev)
return $gettok($hget(tower,$+(obj.,$1,.elem)),%prev,58)
}
}
; the $calc is there for a reason : if the element doesnt exists, i want to return 0, not an empty string
alias obj.count return $calc($hget(tower,$+(obj.,$1,.count)))
alias obj.cid return $hget(tower,$+(obj.cid,.,$1,.,$prop))
alias obj.tid return $hget(tower,$+(obj.tid,.,$1,.,$prop))
alias obj.getProp return $hget(tower,$+(obj.,$1,.,$2,.,$prop))
alias obj.setProp hadd tower $+(obj.,$1,.,$2,.,$3) $4-
alias obj.exists return $hget(tower,$+(obj.,$1,.,$2,.exists))
alias obj.incProp hinc tower $+(obj.,$1,.,$2,.,$3) $4-
alias obj.decProp hdec tower $+(obj.,$1,.,$2,.,$3) $4-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias td.upgradeTid {
var %tower = $obj.tid($1).upgrade
; check if the tower can upgrade
if ($obj.exists(tower,%tower)) {
; check if we have enough cash
if ($hget(tower,self.cash) >= $obj.getProp(tower,%tower).cost) {
var %killcount = $obj.tid($1).killcount
var %level = $obj.tid($1).level
var %value = $obj.tid($1).value
var %x = $obj.tid($1).x
var %y = $obj.tid($1).y
td.removeTid $1
var %tid = $td.buildTower(%tower,%x,%y)
if (%tid) {
; we want to keep Level, Killcount, and value for the upgraded tower
obj.setProp tid %tid killcount %killcount
obj.incProp tid %tid value %value
var %i = 1
while (%i <= %level) {
td.addVeteranLevel %tid
inc %i
}
return %tid
}
}
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj, x, y
; desc: build a tower at the specified tile's position
alias -l td.buildTower {
var %x = $2
var %y = $3
var %w = $obj.getProp(tower,$1).width
var %h = $obj.getProp(tower,$1).height
if ($td.canBuildTower($1,%x,%y,%w,%h)) {
if ($td.triggerEvent(onBuildStart,$1,$topix(%x),$topix(%y),$topix(%w),$topix(%h))) {
var %id = $obj.getNextId(tid)
obj.new tid %id
; keep the tower type
obj.setProp tid %id obj $1
obj.setProp tid %id name $obj.getProp(tower,$1).name
obj.setProp tid %id desc $obj.getProp(tower,$1).desc
; coords in tile
obj.setProp tid %id x %x
obj.setProp tid %id y %y
obj.setProp tid %id w %w
obj.setProp tid %id h %h
; coords in pixel
obj.setProp tid %id ScreenX $topix(%x)
obj.setProp tid %id ScreenY $topix(%y)
obj.setProp tid %id ScreenW $topix(%w)
obj.setProp tid %id ScreenH $topix(%h)
obj.setProp tid %id centerX $tid.getCenterX(%id)
obj.setProp tid %id centerY $tid.getCenterY(%id)
; stuff for handling "building"
obj.setProp tid %id complete 0
obj.setProp tid %id buildstart $td.ticks
; minimum buildTime is 1
if (!$obj.getProp(tower,$1).buildtime) obj.setProp tid %id buildtime 1
else obj.setProp tid %id buildtime $obj.getProp(tower,$1).buildtime
; minimum maxTarget is 1
if (!$obj.getProp(tower,$1).maxTarget) obj.setProp tid %id maxTarget 1
else obj.setProp tid %id maxTarget $obj.getProp(tower,$1).maxTarget
obj.setProp tid %id target $+(:,$replace($remove($obj.getProp(tower,$1).target,$chr(32)),$chr(44),:),:)
; image
obj.setProp tid %id img $obj.getProp(tower,$1).img
obj.setProp tid %id imgpos 0
obj.setProp tid %id range $obj.getProp(tower,$1).range
obj.setProp tid %id sell $obj.getProp(Tower,$1).sell
obj.setProp tid %id value $obj.getProp(Tower,$1).cost
obj.setProp tid %id upgrade $obj.getProp(tower,$1).upgrade
; attack
var %att = $obj.getProp(tower,$1).attack
var %min = $calc($gettok(%att,1,45))
var %max = $calc($gettok(%att,2,45))
if (%max < %min) %max = %min
obj.setProp tid %id att_min %min
obj.setProp tid %id att_max %max
obj.setProp tid %id att_text $+(%min,-,%max)
; speed
obj.setProp tid %id speed $calc($obj.getProp(tower,$1).speed)
; stats modifiers
obj.setProp tid %id att_mod 0
obj.setProp tid %id spe_mod 0
obj.setProp tid %id ran_mod 0
obj.setProp tid %id on_hit $obj.getProp(Tower,$1).on_hit
; at killcount 15 40 70 115 150, gain a level
obj.setProp tid %id KillCount 0
obj.setProp tid %id Level 0
obj.setProp tid %id Selected 0
obj.setProp tid %id canSell 1
obj.setProp tid %id combo_list $obj.getProp(tower,$1).combo_list
; default value for "Accept modifiers" property is 1
var %accept_mod = $obj.getProp(Tower,$1).accept_modifiers
if ($len(%accept_mod) == 0) %accept_mod = 1
obj.setProp tid %id accept_modifiers %accept_mod
; remove cash
hdec tower self.cash $obj.getProp(tower,$1).cost
; update collision buffer
td.setTileState %x %y %w %h 3
td.computeRangeSections %id
; put tower in the "towers in construction" list
obj.new buildingTid %id
; put tower to sleep, it will be awake once the construction is
; done and when a creep will walk in a region it can attack
td.goToSleep %id
return %id
}
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias -l td.goToSleep {
var %gotoSleepList = 1
if ($2 == 0 ) %gotoSleepList = 0
obj.delete readytid $1
obj.setProp tid $1 sleeping 1
if (%gotoSleepList) {
if ($td.isTowerValidForSleepList($1)) {
var %i = 1
var %zonelist = $obj.tid($1).zonelist
while ($gettok(%zonelist,%i,32)) {
; add the tower in the sleeplist of the zone
obj.new $+($v1,.sleep) $1
inc %i
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias -l td.awakeTower {
obj.new readytid $1
obj.setProp tid $1 sleeping 0
obj.setProp tid $1 lastAttack $td.ticks
var %i = 1
var %zonelist = $obj.tid($1).zonelist
while ($gettok(%zonelist,%i,32)) {
; remove the tower from the sleeplist of the zone
obj.delete $+($v1,.sleep) $1
inc %i
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
; desc: check if we need to put the tower in the sleep list
alias -l td.isTowerValidForSleepList {
if ($obj.tid($1).att_max > 0) {
return 1
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid
alias -l td.computeTowerLink {
var %x1 = $obj.tid($1).centerX
var %y1 = $obj.tid($1).centerY
var %range = $calc($obj.tid($1).range + $obj.tid($1).ran_mod)
var %link = $td.getLink($1)
var %tid = $obj.getFirst(tid)
while (%tid) {
if (%tid != $1) {
var %x2 = $obj.tid(%tid).centerX
var %y2 = $obj.tid(%tid).centerY
var %dist = $sqrt($calc((%x1 - %x2) ^ 2 + (%y1 - %y2) ^ 2))
if (%dist <= %range) {
td.linkTower $1 %tid
}
var %range2 = $calc($obj.tid(%tid).range + $obj.tid(%tid).ran_mod)
if (%dist <= %range2) {
td.linkTower %tid $1
}
}
%tid = $obj.getNext(tid)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid, linkToTid
; desc: tid --> linkToTid
alias -l td.linkTower {
var %tid = $1, %linkTo = $2
obj.new $td.getLink(%tid) %linkTo
; is the tower allowed to accept modifiers?
if ($obj.tid(%linkTo).accept_modifiers) {
var %tower = $obj.tid(%tid).obj
obj.incProp tid %linkTo att_mod $calc($obj.getProp(tower,%tower).attack_mod)
obj.incProp tid %linkTo spe_mod $calc($obj.getProp(tower,%tower).speed_mod)
var %ran_mod = $calc($obj.getProp(tower,%tower).range_mod)
if (%ran_mod != 0) {
obj.incProp tid %linkTo ran_mod %ran_mod
td.computeRangeSections %linkTo
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tid, tid_to_unlink
; desc: unlink a tower from another
alias -l td.unlinkTower {
; remove first link
var %link = $td.getLink($2)
if ($obj.exists(%link,$1)) {
obj.delete %link $1
}
; remove second link
var %link = $td.getLink($1)
if ($obj.exists(%link,$2)) {
var %tower = $obj.tid($1).obj
; check if tower can accept modifiers
if ($obj.tid($2).accept_modifiers) {
; if the tower we're unlinking was giving bonuses, be sure to remove them
obj.decProp tid $2 att_mod $calc($obj.getProp(tower,%tower).attack_mod)
obj.decProp tid $2 spe_mod $calc($obj.getProp(tower,%tower).speed_mod)
var %ran_mod = $calc($obj.getProp(tower,%tower).range_mod)
if (%ran_mod != 0) {
obj.decProp tid $2 ran_mod %ran_mod
td.computeRangeSections $2
}
}
obj.delete %link $2
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.getLink {
return $+(tlink,$1)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
; parms: tower, x, y, w, h
alias -l td.canBuildTower {
; check is building position is free
if ($td.isPositionFree($2,$3,$4,$5)) {
; check if we have enough cash
if ($hget(tower,self.cash) >= $obj.getProp(tower,$1).cost) {
return 1
}
else {
var %msg = Not enough money!
var %x = $td.centerTextX(%msg,$mouse.x,$topix($4))
td.showFloatingText -fs %x $calc($mouse.y - 10) 500 0 %msg
}
}
else {
var %msg = Can't build there!
var %x = $td.centerTextX(%msg,$mouse.x,$topix($4))
td.showFloatingText -fs %x $calc($mouse.y - 10) 500 0 %msg
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc:
; parms: tid
alias -l td.computeRangeSections {
var %id = $1
; this is the section where the tower belongs
var %cx = $obj.tid(%id).centerX
var %cy = $obj.tid(%id).centerY
var %bx = $td.build.x
var %by = $td.build.y
var %bw = $td.build.w
var %bh = $td.build.h
var %zone = $td.getZoneKey(%cx,%cy)
var %zonelist = %zone
var %range = $calc($obj.tid(%id).range + $obj.tid(%id).ran_mod)
var %step = %zone.w
if (%step > %zone.h) %step = %zone.h
var %r = 0, %2pi = 2 * $pi
while (%r < %2pi) {
var %ok = 1
var %len = %step
while (%ok) {
if (%len > %range) {
%len = %range
%ok = 0
}
var %x = $floor($calc(%cx + $cos(%r) * %len)))
var %y = $floor($calc(%cy + $sin(%r) * %len)))
if ($inrect(%x,%y,%bx,%by,%bw,%bh)) {
var %zone = $td.getZoneKey(%x,%y)
if (!$pos(%zonelist, %zone)) {
%zonelist = %zonelist %zone
}
}
inc %len %step
}
inc %r .4
}
obj.setProp tid %id zonelist %zonelist
}
alias loaddebug {
td.buildTower arrow1 6 7
td.buildTower arrow1 8 7
td.buildTower arrow1 10 7
td.buildTower arrow1 12 7
td.buildTower arrow1 14 7
td.buildTower arrow1 16 7
td.buildTower arrow1 22 7
td.buildTower arrow1 24 7
td.buildTower arrow1 26 7
td.buildTower arrow1 28 7
td.buildTower arrow1 30 7
td.buildTower arrow1 30 9
td.buildTower arrow1 28 11
td.buildTower arrow1 26 13
td.buildTower arrow1 24 15
td.buildTower arrow1 22 15
td.buildTower arrow1 16 19
td.buildTower arrow1 14 21
td.buildTower arrow1 12 23
td.buildTower arrow1 10 25
td.buildTower arrow1 8 25
td.buildTower arrow1 6 27
td.buildTower arrow1 6 29
td.buildTower arrow1 8 29
td.buildTower arrow1 10 29
td.buildTower arrow1 12 29
td.buildTower arrow1 14 29
td.buildTower arrow1 16 29
td.buildTower arrow1 22 29
td.buildTower arrow1 24 29
td.buildTower arrow1 26 29
td.buildTower arrow1 28 29
td.buildTower arrow1 30 29
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: x, y
; desc: return the tile state for specified tile
; null: Nothing on the tile
; 1: Tile is in a region
; 2: not used
; 3: There is a building on the tile
alias -l td.getTileState {
return $hget(tower,$+(map.,$1,.,$2))
}
alias -l td.showError {
echo -a *** Error : $1-
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: x, y, w, h
; desc: return 1 if building is possible on that tile
alias -l td.isPositionFree {
var %x = 0
while (%x < $3) {
var %y = 0
while (%y < $4) {
if ($hget(tower,$+(map.,$calc(%x + $1),.,$calc(%y + $2)))) {
return 0
}
inc %y
}
inc %x
}
return 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: x, y, w, h, state
; desc: set the tile state
; State Description
; null: Nothing on the tile
; 1: Tile is in a region
; 2: not used
; 3: There is a building on the tile
alias -l td.setTileState {
var %x = 0
while (%x < $3) {
var %y = 0
while (%y < $4) {
hadd tower $+(map.,$calc(%x + $1),.,$calc(%y + $2)) $5-
inc %y
}
inc %x
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
; desc: return percentage of constructions progression for $1 tower
alias -l td.getBuildProgress {
var %timestart = $obj.tid($1).buildStart
var %buildtime = $obj.tid($1).buildTime
var %done = $calc(($td.ticks - %timestart) / %buildtime)
if (%done > 1) %done = 1
return %done
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: tid
; desc: update the building progress for the tower
alias -l td.updateBuildProgress {
var %done = $td.getBuildProgress($1)
var %oldpos = $obj.tid($1).imgpos
var %newpos = $int($calc(%done * 5))
var %x = $obj.tid($1).screenX
var %y = $obj.tid($1).screenY
; check if tower image has to change
if (%oldpos != %newpos) {
obj.setProp tid $1 imgpos %newpos
; update image in buffer
td.drawTid @tbuf $1 %x %y
}
; construction done?
if (%done >= 1) {
var %obj = $obj.tid($1).obj
var %w = $obj.tid($1).screenW
var %h = $obj.tid($1).screenH
if ($td.triggerEvent(onBuildFinish,%obj,%x,%y,%w,%h)) {
obj.delete buildingTid $1
obj.setProp tid $1 complete 1
td.computeTowerLink $1
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: text, x, width
; desc: return the centered x value for a width
alias -l td.centerTextX {
return $calc($2 + ($3 - $width($1,%td.font,12)) / 2)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: text, y, height
; desc: return the centered y value for an height
alias -l td.centerTextY {
return $calc($2 + ($3 - $height($1,%td.font,12)) / 2)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: return 1 if the mouse cursor is in the building zone
alias -l td.InBuildZone {
return $inrect($mouse.x,$mouse.y,$td.Build.X(),$td.Build.Y(),$td.Build.W(),$td.Build.H())
}
alias -l td.Build.X return 0
alias -l td.Build.Y return 32
alias -l td.Build.W return 640
alias -l td.Build.H return 512
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias -l td.path {
return $shortfn($+(%td.map_path,$1))
}
alias -l td.gfx {
return $shortfn($+($scriptdirgfx\,$1))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: return the currently loaded map
alias -l td.map return $hget(tower,__currentmap)
alias -l td.level return $hget(tower,game.level)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: draw regions defined in map... mostly used for debug
alias -l td.drawRegions {
var %name = $obj.getFirst(region)
while (%name) {
var %x = $obj.getProp(region,%name).x
var %y = $obj.getProp(region,%name).y
var %w = $obj.getProp(region,%name).width
var %h = $obj.getProp(region,%name).height
drawrect -nr @tower $rgb(255,0,0) 1 $topix(%x) $topix(%y) $topix(%w) $topix(%w)
drawtext -nr @tower $rgb(255,0,0) %td.font 10 $calc($topix(%x)+2) $topix(%y) $obj.getprop(region,%name).desc
%name = $obj.getNext(region)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: @window
; desc: render all the floating text
alias -l td.renderFloatingText {
var %id = $obj.getFirst(ftext)
while (%id) {
; check is it's a delayed floating text
var %s = $obj.getProp(ftext,%id).start
if ($td.ticks >= %s) {
var %n = $calc($td.ticks - %s)
var %dur = $obj.getProp(ftext,%id).duration
; text is still visible?
if (%n < %dur) {
; % completed
var %p = $calc(%n / %dur)
if (%p > 1) %p = 1
var %x = $obj.getProp(ftext,%id).x
; small sin effect
if ($obj.getProp(ftext,%id).sin) {
%x = $calc(%x + $sin($calc(%p * 6)) * 5)
}
var %y = $obj.getProp(ftext,%id).y
; move text up
if ($obj.getProp(ftext,%id).flying) {
%y = $calc(%y - %p * 30)
}
var %text = $obj.getProp(ftext,%id).text
drawtext -nor @tower $rgb(0,0,0) %td.font 12 $calc(%x + 1) $calc(%y + 1) %text
drawtext -nor @tower %td.white %td.font 12 %x %y %text
}
else {
; since text is not visible anymore, flush it from memory...
obj.delete ftext %id
}
}
%id = $obj.getNext(ftext)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias td.populateComboList {
hdel tower combosel
obj.clear combo_list
var %n = 0
var %combo = $obj.getFirst(combo)
while (%combo) {
var %require = $remove($obj.getProp(combo,%combo).require,$chr(32))
; for each selected towers
var %tid = $obj.getFirst(seltid)
while (%tid) {
; check if the tower is in the combo requirement
var %tower = $obj.tid(%tid).obj
if ($istok(%require,%tower,44)) {
%require = $remtok(%require,%tower,44)
%tid = $obj.getNext(seltid)
}
else {
%require = invalid_combo
%tid = 0
}
}
if (!%require) {
obj.new combo_list %combo
inc %n
}
%combo = $obj.getNext(combo)
}
return %n
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: switch, x, y, duration, delay, message
; desc: create a floating text at specified position
; switch : -f (flying)
; -s (sin effect)
; -n (nothing)
; -x (ignore option 'show floating msg')
alias -l td.showFloatingText {
if ($hget(tower,show.msg) || $pos($1,x) > 0) {
; generate a random id
var %id = $obj.getNextId(ftext)
obj.new ftext %id
obj.setProp ftext %id x $2
obj.setProp ftext %id y $3
obj.setProp ftext %id duration $4
obj.setProp ftext %id start $calc($td.ticks + $5)
obj.setProp ftext %id text $6-
if ($pos($1,f) > 0) obj.setProp ftext %id flying 1
else obj.setProp ftext %id flying 0
if ($pos($1,s) > 0) obj.setProp ftext %id sin 1
else obj.setProp ftext %id sin 0
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: draw the mouse cursor
alias -l td.drawMouse {
if ($td.inBuildZone()) {
var %tool = $hget(tower,tool.sel)
if (%tool) {
var %toolX = $tool.x
var %toolY = $tool.y
var %toolW = $tool.w
var %toolH = $tool.h
var %canBuild = $td.isPositionFree(%toolX,%toolY,%toolW,%toolH)
if (%canBuild) {
var %range = $obj.getProp(Tower,%tool).range
var %tmpx = $calc($align($mouse.x) + ($topix(%toolw) / 2) - %range)
var %tmpy = $calc($align($mouse.y) + ($topix(%toolh) / 2) - %range)
drawrect -rne @tower $rgb(0,0,0) 1 %tmpx %tmpy $calc(2 * %range) $calc(2 * %range)
drawrect -nr @tower $rgb(0,0,0) 1 $align($mouse.x) $align($mouse.y) $topix(%toolW) $topix(%toolH)
}
else {
; occupied position
var %x = $align($mouse.x)
var %y = $align($mouse.y)
var %w = $topix($tool.w)
var %h = $topix($tool.h)
drawrect -nr @tower $rgb(255,0,0) 1 %x %y %w %h
drawline -nr @tower $rgb(255,0,0) 1 %x %y $calc(%x + %w - 1) $calc(%y + %h - 1)
drawline -nr @tower $rgb(255,0,0) 1 $calc(%x + %w - 1) %y %x $calc(%y + %h - 1)
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: tool's coords
alias -l tool.x return $totile($align($mouse.x))
alias -l tool.y return $totile($align($mouse.y))
alias -l tool.w return $hget(tower,tool.w)
alias -l tool.h return $hget(tower,tool.h)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: redraw all the towers on the buffer
alias -l td.updateTowerBuffer {
td.clearBuffer
var %tid = $obj.getFirst(tid)
while (%tid) {
td.drawTid @tbuf %tid $obj.tid(%tid).ScreenX $obj.tid(%tid).ScreenY
%tid = $obj.getNext(tid)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: clear the buffer
alias -l td.clearBuffer {
drawpic -cnr @tbuf 0 0 $td.path($obj.getProp(map,$td.map()).background)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: @window, tid, x, y
alias -l td.drawTid {
var %img = $obj.tid($2).img
var %x = $3
var %y = $4
var %w = $obj.tid($2).screenW
var %h = $obj.tid($2).screenH
if (%img) {
var %pos = $obj.tid($2).imgpos
drawpic -ctn $1 $rgb(255,0,255) %x %y $calc(48 + %w * %pos) 0 %w %h %img
}
else {
drawrect -rnf $1 $rgb(0,0,0) 1 %x %y %w %h
drawtext -nr $1 %td.white %td.font 12 $calc(%x + 5) $calc(%y + 1) No
drawtext -nr $1 %td.white %td.font 12 $calc(%x + 5) $calc(%y + 13) Img
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: @window, tower, x, y
alias -l td.drawTowerTool {
var %tower = $2
var %x = $3, %y = $4
var %w = $obj.getProp(tower,%tower).ScreenW
var %h = $obj.getProp(tower,%tower).ScreenH
var %img = $obj.getProp(tower,%tower).img
if (%img) {
drawpic -ctn $1 $rgb(255,0,255) %x %y $calc(48 + 5 * %w) 0 %w %h %img
}
else {
drawrect -rnf $1 $rgb(0,0,0) 1 %x %y %w %h
drawtext -nr $1 %td.white %td.font 12 $calc(%x + 5) $calc(%y + 1) No
drawtext -nr $1 %td.white %td.font 12 $calc(%x + 5) $calc(%y + 13) Img
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias -l align return $calc($1 - $1 % 16)
alias -l toTile2 return $calc($align($1) / 16)
alias -l toTile return $int($calc($1 / 16))
alias -l topix return $calc($1 * 16)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.drawMenus {
var %rgb = %td.white
var %gold = $hget(tower,self.cash)
drawtext -nr @tower %rgb %td.font 14 75 6 $td.goldToText(%gold)
drawtext -nr @tower %rgb %td.font 14 375 6 Next: $td.getTimeBeforeNextLevel()
drawtext -nr @tower %rgb %td.font 14 448 6 Round: $td.level()
drawtext -nr @tower %rgb %td.font 14 536 6 Lives: $hget(tower,self.lives)
if ($inrect($mouse.x,$mouse.y,305,580,32,32)) {
if ($td.onMouseClick(1)) {
td.setPause 1
}
}
drawpic -cnt @tower $rgb(255,0,255) 305 580 $td.gfx(pause.bmp)
if ($hget(tower,debug)) {
drawtext -nr @tower %rgb %td.font 12 150 2 fps( $+ $int($hget(tower,fps.fps)) $+ ) cid( $+ $obj.count(cid) $+ ) ftxt( $+ $obj.count(ftext) $+ ) $mouse.x $mouse.y
drawtext -nr @tower %rgb %td.font 12 150 15 rdy( $+ $obj.count(readytid) $+ ) bld( $+ $obj.count(buildingtid) $+ ) tmr( $+ $timer(0) $+ ) hpmod( $+ $td.getLvlHpModifier() $+ )
}
var %toolcount = $hget(tower,toolset.count)
if (%toolcount > 0) {
drawcopy -nt @toolset $rgb(255,0,255) 0 0 $calc(%toolcount * 48) 48 @tower 20 575
var %tool = $hget(tower,tool.sel)
if (%tool) {
var %pos = $obj.getProp(tool,%tool).pos
if ($len(%pos)) {
drawrect -nr @tower %td.white 2 $calc(20 + %pos * 48) 575 48 48
drawrect -nr @tower $rgb(0,0,0) 1 $calc(20 + %pos * 48) 575 48 48
}
}
if ($inrect($mouse.x,$mouse.y,20,575,$calc(%toolcount * 48),48)) {
var %pos = $int($calc(($mouse.x - 20) / 48 + 1))
var %tool = $replace($gettok($obj.getProp(map,$td.map).toolset,%pos,44),$chr(32),$null)
td.showTowerInfo %tool 230 460
if ($td.onMouseClick(1)) {
td.selTool %tool
}
}
}
var %creep = $hget(tower,spawnCreep.objId)
drawtext -nor @tower %td.white %td.font 16 375 574 Round info ( $+ $td.getTextDiffLevel $+ )
drawtext -nr @tower %td.white %td.font 12 375 592 $obj.getProp(creep,%creep).name ( $+ $calc($obj.getProp(creep,%creep).basehp + $td.getLvlHpmodifier()) hp $+ )
drawtext -nr @tower %td.white %td.font 12 375 606 > $obj.getProp(creep,%creep).desc
}
alias -l td.getTextDiffLevel {
var %lvl = $hget(tower,game.dlvl)
if (%lvl == 1) return Very easy
elseif (%lvl == 2) return Easy
elseif (%lvl == 3) return Medium
elseif (%lvl == 4) return Hard
elseif (%lvl == 5) return Very hard
elseif (%lvl == 6) return Impossible
else { return Undefined }
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parms: tower, x, y
alias -l td.showTowerInfo {
var %tool = $1
var %desc = $obj.getProp(tower,%tool).desc
if (!%desc) %desc = No description
var %name = $obj.getProp(tower,%tool).name $chr(91) $td.goldToText($obj.getProp(tower,%tool).cost) $chr(93)
var %texth = $height(X,%td.font,12)
var %maxw = 300
var %linenum = $wrap(%desc,$noqt(%td.font),12,%maxw,1,0)
var %rectx = $2
var %recty = $3
var %rectw = 300
var %recth = $calc(%texth * (5 + %linenum) + 8)
; keep the rect on screen
if ($calc(%rectx + %rectw) > 640) %rectx = $calc(640 - %rectw)
if ($calc(%recty + %recth) > 640) %recty = $calc(640 - %recth)
drawrect -nrf @tower %td.white 1 %rectx %recty %rectw %recth
drawrect -nr @tower 0 1 %rectx %recty %rectw %recth
drawtext -ron @tower $rgb(0,0,0) %td.font 16 $calc(%rectx + 5) $calc(%recty + 2) %name
inc %recty 4
var %chunk
var %texty = $calc(%recty + 16)
var %textx = $calc(%rectx + 5)
var %textw = $width(%desc,$noqt(%td.font),12)
var %i = 1
while (%i <= %linenum) {
%chunk = $wrap(%desc,$noqt(%td.font),12,%maxw,1,%i)
if (%chunk) {
drawtext -nr @tower $rgb(0,0,0) %td.font 12 %textx %texty %chunk
}
inc %texty %texth
inc %i
}
drawtext -npr @tower 0 %td.font 12 %textx $calc(%texty + %texth * 0) Attack: $obj.getProp(tower,%tool).attack
drawtext -npr @tower 0 %td.font 12 %textx $calc(%texty + %texth * 1) Range: $obj.getProp(tower,%tool).range
drawtext -npr @tower 0 %td.font 12 %textx $calc(%texty + %texth * 2) Speed: $obj.getProp(tower,%tool).speed
drawtext -npr @tower 0 %td.font 12 %textx $calc(%texty + %texth * 3) Max target: $obj.getProp(tower,%tool).maxtarget
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.getTimeBeforeNextLevel {
if (!$obj.count(cid)) {
var %t = $ceil($calc(($hget(tower,game.nextlevel) - $td.ticks) / 1000))
if (%t < 0) %t = 0
}
else {
var %t = 0
}
return %t
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: none
; desc: send next level
alias -l td.nextLevel {
if ($td.cacheShortestPath()) {
.timerCidEff* off
set %td.timerId 0
hinc tower game.level
var %level = $hget(tower,game.level)
if (%level <= $obj.getProp(map,$td.map).maxLevel) {
var %list = $obj.getProp(map,$td.map).levels
var %count = $numtok(%list,44)
var %tmplevel = $calc(((%level - 1) % %count) + 1)
var %mylevel = $gettok(%list,%tmplevel,44)
var %num = $calc($gettok(%mylevel,1,32))
var %creep = $remove($gettok(%mylevel,2,32),$chr(32))
td.spawn %num %creep $remove($gettok($obj.getProp(map,$td.map).WalkPath,1,44),$chr(32))
td.triggerEvent onNextLevel %level
; you dont get interest for the first level...
if (%level > 1) {
; do we get any interest?
var %interest = $int($calc($hget(tower,self.cash) * $obj.getProp(map,$td.map).interest_rate))
if (%interest > 0) {
var %last_region = $remove($gettok($obj.getProp(map,$td.map).WalkPath,-1,44),$chr(32))
if (%last_region) {
; show the interest message over the last region
var %cx = $calc($obj.getProp(region,%last_region).CenterX - 30)
var %cy = $calc($obj.getProp(region,%last_region).CenterY - 50)
td.showFloatingText -fs %cx %cy 1500 0 Interest $td.goldToText(%interest)
}
td.addGain %interest
}
}
td.playSound $td.path($obj.getProp(map,$td.map).sfxLevelStart)
}
else {
; you win
td.jumpToScene win
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: cashAmount
alias -l td.addGain {
hinc tower self.gain $1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: nb_of_creeps obj_id region
; desc: spawn the creeps for current level
alias -l td.spawn {
if ($obj.exists(creep,$2)) {
hadd tower spawnCreep.n $1
hadd tower spawnCreep.objId $2
hadd tower spawnCreep.rid $3
}
else {
td.showError Creep type $+(',$2,') doesn't exists
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: obj_id region
alias -l td.spawnCid {
var %obj = $1
if (%obj) {
var %region = $2
var %id = $obj.getNextId(cid)
obj.new cid %id
obj.setProp cid %id obj $1
obj.setProp cid %id name $obj.getProp(creep,%obj).name
obj.setProp cid %id desc $obj.getProp(creep,%obj).desc
obj.setProp cid %id hp $obj.getProp(creep,%obj).hp
obj.setProp cid %id gold $td.getRandIntVal($obj.getProp(creep,%obj).gold)
obj.setProp cid %id speed $obj.getProp(creep,%obj).speed
obj.setProp cid %id armor $obj.getProp(creep,%obj).armor
obj.setProp cid %id spe_mod 0
obj.setProp cid %id x 0
obj.setProp cid %id y 0
obj.setProp cid %id w $obj.getProp(creep,%obj).width
obj.setProp cid %id h $obj.getProp(creep,%obj).height
obj.setProp cid %id centerX $cid.getCenterX(%id)
obj.setProp cid %id centerY $cid.getCenterY(%id)
var %img = $obj.getProp(creep,%obj).img
if (%img) {
%img = $td.path(%img)
obj.setProp cid %id img %img
obj.setProp cid %id imgnb $calc($pic(%img).width / $obj.cid(%id).w / 3)
}
else {
obj.setProp cid %id imgnb 0
}
obj.setProp cid %id imglu $td.ticks
obj.setProp cid %id imgpos 0
var %hp = $calc($obj.getProp(creep,%obj).basehp + $td.getLvlHpModifier())
obj.setProp cid %id hp %hp
obj.setProp cid %id maxhp %hp
obj.setProp cid %id lifeCost $obj.getProp(creep,%obj).lifeCost
obj.setProp cid %id sfxdie $obj.getProp(creep,%obj).sfxDie
obj.setProp cid %id type $obj.getProp(creep,%obj).type
td.WalkCreepTo %id %region
td.moveCreepToRegion %id %region
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.getLvlHPModifier {
return $int($calc(($hget(tower,game.level) + 2) ^ $hget(tower,game.diff)))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: interval values.
; desc: Example: 4-6 will return a number between 4 and 6
alias -l td.getRandIntVal {
tokenize 45 $1
var %min = $1
var %max = $2
if (%max < %min) %max = %min
return $r(%max,%min)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: move creep to specified region
; param: cid, region
alias -l td.moveCreepToRegion {
var %cid = $1
var %region = $2
if ($obj.getProp(region,%region).exists) {
; region coords
var %rx = $topix($obj.getProp(region,%region).x)
var %ry = $topix($obj.getProp(region,%region).y)
var %rw = $topix($obj.getProp(region,%region).width)
var %rh = $topix($obj.getProp(region,%region).height)
; creep size
var %cw = $obj.cid(%cid).w
var %ch = $obj.cid(%cid).h
; center creep in the region
var %x = $calc(%rx + (%rw - %cw) / 2)
var %y = $calc(%ry + (%rh - %ch) / 2)
td.moveCreep %cid %x %y
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; param: cid, x, y
alias -l td.moveCreep {
obj.setProp cid $1 x $2
obj.setProp cid $1 y $3
obj.setProp cid $1 centerX $calc($2 + $obj.cid($1).w / 2)
obj.setProp cid $1 centerY $calc($3 + $obj.cid($1).h / 2)
td.updateCidZone $1
var %on_effect = $obj.cid($1).on_effect
if (%on_effect) {
var %damage_per_second = $calc($obj.cid($1).damage_per_second)
if (%damage_per_second > 0) {
var %lastDamage = $obj.cid($1).last_dmg
if ($calc($td.ticks - %lastDamage) >= 1000) {
td.damageCreep %on_effect $1 %damage_per_second
obj.setProp cid $1 last_dmg $td.ticks
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.updateCidZone {
var %oldzone = $obj.cid($1).zone
var %newzone = $td.getZoneKey($obj.cid($1).CenterX, $obj.cid($1).CenterY)
if (%oldzone != %newzone) {
if (%oldzone) obj.delete %oldzone $1
obj.new %newzone $1
; awake every sleeping tower in the zone
var %sleeplist = $+(%newzone,.sleep)
var %tid = $obj.getFirst(%sleeplist)
while (%tid) {
; only awake tower if it's done building
if ($obj.tid(%tid).complete) {
td.awakeTower %tid
}
%tid = $obj.getNext(%sleeplist)
}
obj.setProp cid $1 zone %newzone
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.getZoneKey {
; $td.build.x $td.build.y
return $+(zone.,$int($calc($1 / %zone.w)),.,$int($calc(($2 - 32) / %zone.h)))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias -l td.cacheShortestPath {
return 1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias -l td.onMouseClick {
if ($hget(tower,mouse.sclick)) {
if ($hget(tower,mouse.key) & $1) {
return 1
}
}
return 0
}
alias -l td.onMouseUclick {
if ($hget(tower,mouse.uclick)) {
return 1
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
menu @tower {
sclick {
hadd tower mouse.sclick $td.ticks
hadd tower mouse.key $mouse.key
}
rclick {
hadd tower mouse.sclick $td.ticks
hadd tower mouse.key $mouse.key
}
uclick {
hadd tower mouse.uclick $td.ticks
hadd tower mouse.key $mouse.key
}
leave {
hadd tower mouse.uclick $td.ticks
hadd tower mouse.key $mouse.key
hdel tower sel.active
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.mouseDown {
var %r = 0
if ($mouse.key & $1) {
if ($inrect($mouse.x,$mouse.y,0,0,640,640)) {
%r = 1
}
}
return %r
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
on *:close:@tower:{
td.unload
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
on *:keydown:@tower:*:{
var %scene = $hget(tower,scene)
if (%scene == game) td.handleKeydownGame
; only trigger event if the console is not visible
if (!$hget(tower,__console.show)) {
td.triggerEvent onKeypress $keychar
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.handleKeydownGame {
if ($keyval == 13) {
; is console already open?
if ($hget(tower,__console.show)) {
td.hideConsole
}
else {
td.showConsole
}
}
else {
if ($hget(tower,__console.show)) {
if ($keyval == 27) td.hideConsole
else td.handleConsoleKeypress
}
else {
if ($keyval == 27 || $keyval == 32) {
hadd tower tool.sel 0
td.clearSelection
}
}
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; parm: gold amount
; desc: format gold to display on screen
alias -l td.goldToText return $+($int($1),$chr(36))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: return 1 if it generates a collision
; param: x, y, cid
alias -l td.creepCollide {
var %w = $obj.cid($3).w
var %h = $obj.cid($3).h
var %x = $calc($1 + (%w / 2))
var %y = $calc($2 + (%h / 2))
if ($td.getTileState($totile(%x),$totile(%y)) == 3) return 1
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; desc: return region where creep is standing
; param: x y
alias -l td.getRegionIdByCoords {
var %state = $td.getTileState($totile($1),$totile($2))
if ($int(%state) == 1) {
return $gettok(%state,2,32)
}
return 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; open the in-game console
alias -l td.showConsole {
hdel tower __console.text
hadd tower __console.show 1
hadd tower __console.cur $calc($hget(tower,__console.count) + 1)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hide the in-game console
alias -l td.hideConsole {
var %text = $hget(tower,__console.text)
if ($len(%text) > 0) {
; send the text to the event
%text = $replace(%text,$chr(160),$chr(32))
hinc tower __console.count
hadd tower $+(__console.,$hget(tower,__console.count)) %text
td.triggerEvent onConsoleInput %text
}
hdel tower __console.text
hadd tower __console.show 0
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
alias -l td.handleConsoleKeypress {
var %text = $hget(tower,__console.text)
; handle backspaces
if ($keyval == 8) {
if ($len(%text) > 0) {
if ($len(%text) == 1) var %text
else %text = $mid(%text,1,$calc($len(%text) - 1))
}
} ; handle keyup
elseif ($keyval == 38) {
var %n = $calc($hget(tower,__console.cur) - 1)
if (%n > 0) {
%text = $hget(tower,$+(__console.,%n))
hadd tower __console.cur %n
}
} ; handle keydown
elseif ($keyval == 40) {
var %n = $calc($hget(tower,__console.cur) + 1)
if (%n <= $hget(tower,__console.count)) {
%text = $hget(tower,$+(__console.,%n))
hadd tower __console.cur %n
}
elseif ($abs($calc(%n - $hget(tower,__console.count))) == 1) {
var %text
hadd tower __console.cur %n
}
}
else {
if ($keychar isalnum || $keyval == 32) {
if ($len(%text) < 55) {
%text = $+(%text,$replace($keychar,$chr(32),$chr(160)))
}
}
}
hadd tower __console.text %text
}
alias -l td.ticks return $hget(tower,ticks)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Omg, you have reach the end of the file. ;
; Thank you for playing this game, I hope ;
; you enjoyed it. Remember kids, this game ;
; is rippable friendly! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;