[Moeng-cvs] CaveAdventure/data/scripts AdvAIRandom.lua,NONE,1.1 BloodSplat.lua,NONE,1.1 CameraTarget
Status: Alpha
Brought to you by:
b_lindeijer
Update of /cvsroot/moeng/CaveAdventure/data/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv27411 Modified Files: AIController.lua Character.lua Added Files: AdvAIRandom.lua BloodSplat.lua CameraTarget.lua Canvas.lua Crocodile.lua Log Message: Scripts stuff, we'll get there. --- NEW FILE: AdvAIRandom.lua --- -- An controller which makes its Pawn walk around randomly, scared, aggressive, neutral or moody... -- -- Bodged by Hedde Bosman import("Controller.lua") SCARED = 1 NEUTRAL = 2 AGGRESSIVE = 3 MOODY = 4 AdvAIRandom = Controller:subclass { name = "AdvAIRandom"; init = function(self) self.waitTime = math.random(100) + 10 end; -- == depending on this nature choose a target (to be scared of) ==- setTargetWithNature = function(self, nature, target) if ((nature == NEUTRAL) or (nature == AGGRESSIVE)) then self.target = target; self.scaring = nil; elseif (nature == SCARED) then self.target = nil; self.scaring = target; elseif (nature == MOODY) then self:setTargetWithNature(self.nature_tmp, target) else self:log("What am i? Who am i? How did i get here? What's that i'm hearing? Hmmm lets call it wind...") end; end; -- == -- == notifiers == -- == -- -- notifyBumpInto = function(self, obj) -- Pause for some time and choose another direction if (self.pawn.bAttacking == false) then self.waitTime = math.random(100) + 10 end end; notifyWalkFinished = function(self) if (self.distanceToWalk <= 0 and self.pawn.bAttacking == false) then -- Reached his goal, pause and choose new goal. if (self.target or self.scaring) then -- korte wachttijd, anders staat ie na elke tile even (te lang) stil self.waitTime = math.random(4) + 1 else self.waitTime = math.random(100) + 2 end; else -- Walking to goal, keep walking. self.distanceToWalk = self.distanceToWalk - 1 self.pawn:walk(self.pawn.dir) end; end; -- == do shizzle depending on nature, and possibly mood == -- notifyHearNoise = function(self, loudness, noiseMaker) if (self.pawn:distanceTo(noiseMaker) < 8) then self.pawn.tick_time = 1; end; if (self.pawn:distanceTo(noiseMaker) >= 8) then self.pawn.tick_time = 150; end; if (noiseMaker and noiseMaker:instanceOf(Player)) then if (self.pawn.nature ~= NEUTRAL) then self:setTargetWithNature(self.pawn.nature, noiseMaker) end; end; end; notifyTakeDamage = function(self, damage, instigator, damageType, momentum, location) if (instigator and instigator:instanceOf(Player)) then self:setTargetWithNature(self.pawn.nature, instigator); end; end; -- check if we can go in 'dir'-ection ... if not, choose any other, but not 'notdir' goingDirection = function(self, dir, notdir) local dirs = self.pawn:freeTilesAround() for v in dirs do if (v == dir) then return dir end; end; for v in dirs do if (v ~= notdir) then return v; end; end; return dir end; -- timebom tick = function(self) if (self.pawn.bDead) then return end if (self.pawn.charging > 0) then self.pawn.charging = self.pawn.charging - 1 end if (self.waitTime > 0) then self.waitTime = self.waitTime - 1; if (self.pawn.nature == MOODY) then -- this one is shifting moods... do new mood, and state how long it has that mood self.moodTime = self.moodTime -1 if (self.moodTime <= 0) then self.target = nil self.scaring = nil self.moodTime = 500 + math.random(1000) self.nature_tmp = math.random(3) end; end; if (self.waitTime <= 0 and self.pawn.bAttacking == false) then -- Check for targets and their distances if (self.target) then playerDist = self.pawn:distanceTo(self.target) elseif (self.scaring) then -- bangmakerij playerDist = self.pawn:distanceTo(self.scaring) else playerDist = 100 end; if (playerDist == 1 and self.target) then self.pawn.dir = self.pawn:directionTo(self.target) self.pawn:attack() self.waitTime = self.pawn.attackTime + self.pawn.chargeTime + 10 else if (self.target or self.scaring) then -- direct loopafstand bij vijand of bangmaker self.distanceToWalk = 0 else -- anders random loopafstand self.distanceToWalk = -1 + math.random(3) end; if (self.target and playerDist < 5) then -- hot persuit mode self.pawn.dir = self:goingDirection(self.pawn:directionTo(self.target), nil); elseif (self.scaring and playerDist < 15) then -- scared; will run in opposit direction local tmpdir = self.pawn:directionTo(self.scaring) self.pawn.dir = self:goingDirection(self:reverseDirection(tmpdir), tmpdir); else -- walk around self.scaring = nil; self.target = nil; self.pawn.dir = self.pawn:randomFreeTileAround() end; self.pawn:walk(self.pawn.dir) end; end end; end; defaultproperties = { tick_time = 0, waitTime = 20, distanceToWalk = 0, nature = NEUTRAL, nature_tmp = NEUTRAL, moodTime = 500, target = nil, scaring = nil, }; } --- NEW FILE: BloodSplat.lua --- -- -- Some bloody splats -- BloodSplat = Actor:subclass { name = "BloodSplat"; init = function(self) self:playAnim(LinearAnimation(self.animSeq)) end; animEnd = function(self) self:destroy() end; defaultproperties = { animSeq = extr_array(m_get_bitmap("blood_splat.bmp"), 16, 16), tick_time = 7, bCenterBitmap = true, } } BloodSplatGreen = BloodSplat:subclass { name = "BloodSplatGreen"; defaultproperties = { animSeq = extr_array(m_get_bitmap("blood_splat_green.bmp"), 16, 16), } } BloodSplatYellow = BloodSplat:subclass { name = "BloodSplatGreen"; defaultproperties = { animSeq = extr_array(m_get_bitmap("blood_splat_yellow.bmp"), 16, 16), } } --- NEW FILE: CameraTarget.lua --- import("Object.lua") CameraTarget = Object:subclass { name = "CameraTarget"; setTarget = function(self, target, tween) if (tween == nil) then tween = true end if (not self.target or self.target.map ~= target.map or not tween) then self.fromX = target.x self.fromY = target.y self.x = target.x self.y = target.y self.progress = 100 else self.fromX = self.x self.fromY = self.y end self.target = target self.map = self.target.map self.progress = 0 end; tick = function(self) if (self.progress < 100) then self.progress = self.progress + 2 end end; preRender = function(self) self.map = self.target.map if (self.progress < 100) then local p = math.sin((self.progress / 100) * 0.5 * math.pi) self.x = self.fromX + (self.target.x - self.fromX) * p self.y = self.fromY + (self.target.y - self.fromY) * p else self.x = self.target.x self.y = self.target.y end end; defaultproperties = { x = 0, y = 0, map = nil, target = nil, travel = 1, tweenAction = nil, progress = 0, }; } --- NEW FILE: Canvas.lua --- -- -- A helper class to draw the HUD on. -- import("Object.lua") Canvas = Object:subclass { name = "Canvas"; drawBitmap = function(self, bitmap, dest_w, dest_h, src_x, src_y, src_w, src_h) m_draw_bitmap(bitmap, dest_w, dest_h, src_x, src_y, src_w, src_h) end; drawPattern = function(self, bitmap, dest_w, dest_h, org_x, org_y, scale) if (scale) then local cur_x, cur_y = m_get_cursor() m_draw_bitmap(bitmap, dest_w, dest_h, (cur_x - org_x) / scale, (cur_y - org_y) / scale, dest_w / scale, dest_h / scale) elseif (org_x and org_y) then local cur_x, cur_y = m_get_cursor() m_draw_bitmap(bitmap, dest_w, dest_h, cur_x - org_x, cur_y - org_y, dest_w, dest_h) else m_draw_bitmap(bitmap, dest_w, dest_h, 0, 0, dest_w, dest_h) end end; drawIcon = function(self, bitmap, scale) local bitmap_w, bitmap_h = m_bitmap_size(bitmap) if (not scale or scale == 1) then m_draw_bitmap(bitmap, bitmap_w, bitmap_h, 0, 0, bitmap_w, bitmap_h) else m_draw_bitmap(bitmap, bitmap_w * scale, bitmap_h * scale, 0, 0, bitmap_w, bitmap_h) end end; drawRect = function(self, bitmap, rect_x, rect_y) local bitmap_w, bitmap_h = m_bitmap_size(bitmap) m_draw_bitmap(bitmap, rect_x, rect_y, 0, 0, bitmap_w, bitmap_h) end; moveCursor = function(self, dx, dy) local x, y = self:getCursor() self:setCursor(x + dx, y + dy) end; setCursor = function(self, x, y) m_set_cursor(x, y) end; getCursor = function(self) return m_get_cursor() end; setAlpha = function(self, alpha) return m_set_alpha(alpha) end; setDrawMode = function(self, drawMode) m_set_drawmode(drawMode) end; } --- NEW FILE: Crocodile.lua --- -- -- A Crocodile. -- -- Temporarily blindly copied from Hedde Bosman's rat by Georg Muntingh! import("Player.lua") import("AdvAIRandom.lua") import("Enemy.lua") Crocodile = Enemy:subclass { name = "Crocodile"; bPlaceable = true; defaultproperties = { attackMinDam = 3, attackMaxDam = 5, maxHealth = 40, speed = 3, experience = 25, offset_y = 6, draw_mode = DM_MASKED, charAnim = extr_char_anim(m_get_bitmap("croc.bmp"), 24, 24), deathBitmap = m_get_bitmap("croc_dead.bmp"), nature = AGGRESSIVE, controllerClass = AdvAIRandom, hitEffectHeight = 0, }; } Index: AIController.lua =================================================================== RCS file: /cvsroot/moeng/CaveAdventure/data/scripts/AIController.lua,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AIController.lua 1 Jun 2003 17:27:24 -0000 1.1 --- AIController.lua 13 Jan 2004 19:15:29 -0000 1.2 *************** *** 1,5 **** -- ! -- Controls the behaviour of a Pawn ! -- By Bjørn Lindeijer import("Controller.lua") --- 1,5 ---- -- ! -- Controls the behaviour of an enemy Pawn ! -- By Bjorn Lindeijer import("Controller.lua") *************** *** 11,40 **** tick = function(self) ! if (self.pawn.charge > 0) then self.pawn.charge = self.pawn.charge - 1 end ! -- Switch to ready from walking ! if (self.pawn.state == AI_WALKING and self.pawn.walking == 0) then ! self.pawn:setState(AI_READY) end ! -- When an AI is ready, it's waiting for something to happen to take action ! if (self.pawn.state == AI_READY) then ! -- Check if player is drawing near ! local playerDist = playerDistance(self.pawn) ! local player = m_get_player() ! if (playerDist < 5 and player.state ~= CHR_DEAD) then -- Chase or attack? ! if (playerDist <= self.pawn.attack_range) then -- Attack on charged ! if (self.pawn.charge == 0 and self.pawn.walking == 0) then ! self.pawn.dir = playerDirection(self.pawn) self.pawn:attack() end else ! self.pawn:walk(playerDirection(self.pawn)) end end end end; } --- 11,58 ---- tick = function(self) ! if (self.pawn.charging > 0) then self.pawn.charging = self.pawn.charging - 1 end ! if (self.target and (self.target.map ~= self.pawn.map or self.target.bDead)) then ! -- Abort target ! self.target = nil end ! -- When my pawn is ready, it's waiting for something to happen to take action ! if (self.pawn.bAttacking == false and self.target) then ! -- Check if target is drawing near ! local targetDist = self.pawn:distanceTo(self.target) ! local targetDir = self.pawn:directionTo(self.target) ! if (targetDist < 5) then -- Chase or attack? ! if (targetDist == 1) then -- Attack on charged ! if (self.pawn.charging == 0 and self.pawn.walking == 0) then ! self.pawn.dir = targetDir self.pawn:attack() end else ! -- TODO: Enhance walking to target algorithm ! if (self.pawn.walking == 0) then ! self.pawn:walk(targetDir) ! end end + elseif (targetDist > 15) then + -- Abort target + self.target = nil end end end; + + notifyHearNoise = function(self, loudness, noiseMaker) + if (noiseMaker:instanceOf(Player) and (not self.target or self.pawn:distanceTo(self.target) > self.pawn:distanceTo(noiseMaker))) then + self.target = noiseMaker + end + end; + + notifyTakeDamage = function(self, damage, instigator, damageType, momentum, location) + if (instigator) then + self.target = instigator + end + end; } Index: Character.lua =================================================================== RCS file: /cvsroot/moeng/CaveAdventure/data/scripts/Character.lua,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Character.lua 1 Jun 2003 17:27:24 -0000 1.4 --- Character.lua 13 Jan 2004 19:15:29 -0000 1.5 *************** *** 1,57 **** ! -- ! -- A character is a pawn with a specific animation scheme ! -- By Bjørn Lindeijer ! ! import("Pawn.lua") ! ! ! Character = Pawn:subclass ! { ! name = "Character"; ! ! init = function(self, char) ! Pawn.init(self) ! self:updateBitmap() ! end; ! ! updateBitmap = function(self) ! local ani = self.charAnim ! if (ani) then ! if (self.attacking == 1) then ! self.bitmap = ani[self.dir + 1 + 3 * 4] ! else ! if (self.walking == 0 or self.walking < 50) then ! self.bitmap = ani[self.dir + 1] ! else ! self.bitmap = ani[self.dir + 1 + (self.leg_used + 1) * 4] ! end ! end ! end ! end; ! ! event_walk_start = function(self) ! self.leg_used = 1 - self.leg_used ! end; ! ! event_walk_finished = function(self) ! self:updateBitmap() ! end; ! ! event_dir_change = function(self) ! self:updateBitmap() ! end; ! ! tick = function(self) ! Pawn.tick(self) ! self:updateBitmap() ! end; ! ! ! defaultproperties = { ! leg_used = 0, ! tick_time = 1, ! walking = 0, ! charAnim = nil, ! }; ! } ! --- 1,187 ---- ! -- ! -- A character is a pawn with a specific animation scheme ! -- By Bjorn Lindeijer ! ! import("Pawn.lua") ! import("Shadow.lua") ! ! ! Character = Pawn:subclass ! { ! name = "Character"; ! ! init = function(self, char) ! self.inventory = {} ! ! self:updateBitmap() ! ! Pawn.init(self) ! end; ! ! beginPlay = function(self) ! Actor.beginPlay(self) ! ! if (self.shadowClass) then ! self.shadow = self:spawn(self.shadowClass, self.x, self.y) ! end ! end; ! ! updateBitmap = function(self) ! local ani = self.charAnim ! if (ani) then ! if (self.bAttacking) then ! self.bitmap = ani[self.dir + 1 + 3 * 4] ! -- Begin hack for the BBRpg ! elseif (self.bWalkieTalkie) then ! self.bitmap = self.talkieBitmap ! -- End hack for the BBRpg ! else ! if (self.walking == 0 or self.walking < 50) then ! self:setBitmap(ani[self.dir + 1]) ! else ! self:setBitmap(ani[self.dir + 1 + (self.leg_used + 1) * 4]) ! end ! end ! end ! end; ! ! ! event_walk_start = function(self) ! self.leg_used = 1 - self.leg_used ! end; ! ! event_walk_finished = function(self) ! Pawn.event_walk_finished(self) ! self:updateBitmap() ! ! -- Check for snow tiles ! local tile = m_get_tile_at(self.map, self.x - 0.5, self.y - 0.5) ! for k,v in pairs(self.snowTiles) do ! if (v == tile) then ! local snowFeet = self:spawn(SnowFeet) ! snowFeet:setDirection(self.dir) ! break ! end ! end ! end; ! ! event_dir_change = function(self) ! self:updateBitmap() ! end; ! ! tick = function(self) ! Pawn.tick(self) ! if (self.bSleeping and self.health < self.maxHealth) then ! self.health = math.min(self.health + 0.0001 * self.maxHealth, self.maxHealth) ! end ! self:updateBitmap() ! end; ! ! died = function(self, killer, damageType, location) ! Pawn.died(self, killer, damageType, location) ! self.charAnim = nil ! self:setBitmap(self.deathBitmap) ! ! -- There is no shadow after death ! if (self.shadow) then ! self.shadow:destroy() ! self.shadow = nil ! end ! end; ! ! destroyed = function(self) ! -- Set bDead to prevent AI's from chasing destroyed characters ! self.bDead = true ! ! Pawn.destroyed(self) ! ! if (self.shadow) then ! self.shadow:destroy() ! self.shadow = nil ! end ! end; ! ! setMap = function(self, map) ! Pawn.setMap(self, map) ! if (self.shadow) then ! self.shadow:setMap(map) ! end ! end; ! ! addToInventory = function(self, obj) ! -- To be implemented?: Check if there is place in the inventory. ! ! table.insert(self.inventory, obj) ! ! -- Make the object irrelevant on the map (not perfect) ! obj.bitmap = nil ! obj.obstacle = 0 ! obj.bCanActivate = false ! obj.bCarried = true ! end; ! ! -- The loop should probably stop when he finds such an object. ! removeFromInventory = function(self, obj) ! for i,v in ipairs(self.inventory) do ! if (v == obj) then ! table.remove(self.inventory, i) ! end ! end ! end; ! ! hasObject = function(self, obj) ! for k,v in pairs(self.inventory) do ! if (v == obj) then return true end ! end ! end; ! ! hasObjectType = function(self, class) ! for k,v in pairs(self.inventory) do ! if (v:instanceOf(class)) then return true end ! end ! end; ! ! ! defaultproperties = { ! snowTiles = { ! --"tiles_subcity.000", ! "tiles_subcity.001", ! --"tiles_subcity.002", ! "tiles_subcity.012", ! --"tiles_subcity.013", ! --"tiles_subcity.014", ! "tiles_subcity.016", ! "tiles_subcity.017", ! "tiles_subcity.018", ! "tiles_subcity.021", ! --"tiles_subcity.028", ! "tiles_subcity.029", ! "tiles_subcity.030", ! --"tiles_subcity.032", ! "tiles_subcity.033", ! --"tiles_subcity.034", ! "tiles_subcity.037", ! --"tiles_subcity.045", ! --"tiles_subcity.046", ! "tiles_subcity.063", ! "tiles_subcity.079", ! "tiles_subcity.092", ! "tiles_subcity.125", ! "tiles_subcity.144", ! "tiles_subcity.145", ! "tiles_subcity.147", ! "tiles_subcity.161", ! }, ! inventory = nil, ! leg_used = 0, ! tick_time = 1, ! walking = 0, ! charAnim = nil, ! shadow = nil, ! shadowClass = Shadow, ! deathBitmap = nil, ! ! bAttacking = false, ! bWalkieTalkie = false, ! }; ! } |