diff --git a/README b/README index c87bcf7..8bf827b 100644 --- a/README +++ b/README @@ -2,9 +2,9 @@ Red Rogue is a platformer-roguelike written in Flex and compiled with FlashDevel The game is played with arrow keys (or w,a,s,d) and the space bar. -There is no jump. Landing on an opponent's head causes knockback-stun. +There is no jump. Landing on an opponent causes knockback/stun. -The space bar opens a menu, from there the inventory can be accessed to equip you and your minion, to cast spells, search for traps and other things like saving and loading. +The space bar opens a menu, from there the inventory can be accessed to equip you and your minion, to cast spells, search for traps and other things. There's also default hot-key-bindings, go to the website and click on "instructions" to discover what they are. diff --git a/TODO.txt b/TODO.txt index 1bf6e90..e6616b1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,4 +1,4 @@ -Change log: fixed game crashing when entering pocket dungeon (caused by content creation restructure), sanity checks to prevent stacked equipping from gameState implemented, fixed anubis armour creation crashing game +Change log: brain.avoid altered to force a direction even if character positions are equal, death now converts the minion into a husband when presented with yendor, fixed camera dipping on stairs when entering Bug hunt chaos wall colliders can child a character and pull it into a wall - how? @@ -8,29 +8,25 @@ Bug hunt balrog frozen after smite attack, stuck to wall - no further info (perhaps secret wall? or chaos wall?) chaos walls frozen without graphics rendered and no walls beneath them (activated, not on chaos wall render list?) minion weapon invisible after level change (arbalest and skull equipped) - investigate portals around level 20 plus and killing the balrog in the same area Guide +Stun shockwave + roll to shockwave + experiment with secondary velocities on Colliders + Add Balrog death and ending events to tracking endings quest menu - picking up yendor change to return to overworld - yendor in the underworld - transformation event - endGameEvent setting: - trigger conditions - entering with yendor - death collecting yendor - - minion must be non-consumed - set husband minion to face player instead of facing player's direction (awwww) - run whole scene as animation? - requires event management state - preamble would require characters to move into place - lock out player input yendor or At in the overworld + + husband clause: how do we resolve the husband getting polymorphed? + new overworld backdrop? night? entrance crumble anim all rocks crumble, rise up? + blood, stone and cogs spewing out of dungeon? + earthquake whilst husband tag on UserData diff --git a/bin/game.swf b/bin/game.swf index 6c500dd..ec6f331 100644 Binary files a/bin/game.swf and b/bin/game.swf differ diff --git a/obj/gameConfig.old b/obj/gameConfig.old index 4713a71..76aa56f 100644 --- a/obj/gameConfig.old +++ b/obj/gameConfig.old @@ -14,18 +14,18 @@ CONFIG::timeStamp - '14/09/2012' + '18/09/2012' - C:\Users\st33d\Documents\rogue\442\src + C:\Users\st33d\Documents\rogue\443\src C:\Program Files (x86)\FlashDevelop\Library\AS3\classes - C:\Users\st33d\Documents\rogue\442\src\assets\assets.swc + C:\Users\st33d\Documents\rogue\443\src\assets\assets.swc - C:\Users\st33d\Documents\rogue\442\src\Preloader.as + C:\Users\st33d\Documents\rogue\443\src\Preloader.as #FFFFFF 30 diff --git a/obj/gameConfig.xml b/obj/gameConfig.xml index 4713a71..76aa56f 100644 --- a/obj/gameConfig.xml +++ b/obj/gameConfig.xml @@ -14,18 +14,18 @@ CONFIG::timeStamp - '14/09/2012' + '18/09/2012' - C:\Users\st33d\Documents\rogue\442\src + C:\Users\st33d\Documents\rogue\443\src C:\Program Files (x86)\FlashDevelop\Library\AS3\classes - C:\Users\st33d\Documents\rogue\442\src\assets\assets.swc + C:\Users\st33d\Documents\rogue\443\src\assets\assets.swc - C:\Users\st33d\Documents\rogue\442\src\Preloader.as + C:\Users\st33d\Documents\rogue\443\src\Preloader.as #FFFFFF 30 diff --git a/src/Game.as b/src/Game.as index ce8d9a5..dc51ed7 100644 --- a/src/Game.as +++ b/src/Game.as @@ -74,7 +74,7 @@ public class Game extends Sprite { - public static const BUILD_NUM:int = 442; + public static const BUILD_NUM:int = 443; public static const TEST_BED_INIT:Boolean = false; public static const ONLINE:Boolean = true; @@ -808,17 +808,18 @@ if(minion && minion.armour && minion.armour.name == Item.FACE) minion.unequip(minion.armour); // change the rogue to a colour version and revert the minion if changed skinMc = new RogueColMC(); - if(player.name != Character.ROGUE){ - console.print("rogue reverts to human form"); - } + if(player.name != Character.ROGUE) + console.print(player.nameToString() + " reverts to human form"); player.changeName(Character.ROGUE, new RogueColMC); if(minion){ - if(minion.name == Character.HUSBAND){ + if(minion.name == Character.HUSBAND || UserData.gameState.husband){ + if(minion.name != Character.HUSBAND) + console.print(minion.nameToString() + " reverts to human form"); minion.changeName(Character.HUSBAND, new AtColMC); } else if(minion.name != Character.SKELETON){ minion.changeName(Character.SKELETON); - console.print("minion reverts to undead form"); + console.print(minion.nameToString() + " reverts to undead form"); } } @@ -867,17 +868,19 @@ endGameEvent = false; if(!player.active) consumedPlayerInit(); - - /*else { + /**/else { // end game checks if(map.type == Map.AREA){ if(map.level == Map.UNDERWORLD){ - // check for yendor, activate death - if(gameMenu.inventoryList.getItem(Item.YENDOR, Item.ARMOUR)){ + // check for yendor (and debugging), activate death + if( + gameMenu.inventoryList.getItem(Item.YENDOR, Item.ARMOUR) && + !(minion && minion.name == Character.HUSBAND) + ){ endGameEvent = true; for(i = 0; i < entities.length; i++){ if(entities[i] is Stone && (entities[i] as Stone).name == Stone.DEATH){ - (entities[i] as Stone).callMain = true; + (entities[i] as Stone).setEndGameEvent(); break; } } @@ -888,11 +891,11 @@ gameMenu.inventoryList.getItem(Item.YENDOR, Item.ARMOUR) || (minion && minion.name == Character.HUSBAND) ){ - endGameEvent = true; + //endGameEvent = true; } } } - }*/ + } changeMusic(); diff --git a/src/UserData.as b/src/UserData.as index c369af9..7b7ae31 100644 --- a/src/UserData.as +++ b/src/UserData.as @@ -121,7 +121,8 @@ package { runeNames:[], storyCharCodes:[], quests:[], - randomSeed:XorRandom.seedFromDate() + randomSeed:XorRandom.seedFromDate(), + husband:false }; initMinion(); diff --git a/src/com/robotacid/ai/Brain.as b/src/com/robotacid/ai/Brain.as index eadf2c9..11819b9 100644 --- a/src/com/robotacid/ai/Brain.as +++ b/src/com/robotacid/ai/Brain.as @@ -629,6 +629,7 @@ if(targetX < charPos.x) char.actions |= RIGHT; else if(targetX > charPos.x) char.actions |= LEFT; + else char.actions = game.random.coinFlip() ? RIGHT : LEFT; if(target.collider.y >= char.collider.y + char.collider.height) char.actions |= UP; if(altNode) altNode = null; diff --git a/src/com/robotacid/engine/ChaosWall.as b/src/com/robotacid/engine/ChaosWall.as index caadc47..2fa83f8 100644 --- a/src/com/robotacid/engine/ChaosWall.as +++ b/src/com/robotacid/engine/ChaosWall.as @@ -341,6 +341,7 @@ package com.robotacid.engine { /* Destructor */ public function kill():void { + if(!active) return; if(fuse){ if(chaosWalls[target.y][target.x]) chaosWalls[target.y][target.x].callMain = true; } diff --git a/src/com/robotacid/engine/Character.as b/src/com/robotacid/engine/Character.as index 38e2b75..c8c804d 100644 --- a/src/com/robotacid/engine/Character.as +++ b/src/com/robotacid/engine/Character.as @@ -1342,6 +1342,7 @@ item.collect(this, false); if(brain) brain.flee(target); game.console.print(nameToString() + " stole " + item.nameToString()); + game.createDistSound(mapX, mapY, "pickUp"); } // polymorph target into a werewolf diff --git a/src/com/robotacid/engine/Item.as b/src/com/robotacid/engine/Item.as index a2819b8..6bda98c 100644 --- a/src/com/robotacid/engine/Item.as +++ b/src/com/robotacid/engine/Item.as @@ -303,7 +303,8 @@ collider.x + collider.width > game.player.collider.x && game.player.collider.x + game.player.collider.width > collider.x && collider.y + collider.height > game.player.collider.y && - game.player.collider.y + game.player.collider.height > collider.y + game.player.collider.y + game.player.collider.height > collider.y && + active ){ if(type == KEY && game.player.keyItem){ // fires a warning once if a key is already carried @@ -360,6 +361,19 @@ } } + /* Destroy a dropped item */ + public function destroyOnMap(sparks:Boolean = false):void{ + if(location == DROPPED){ + collider.world.removeCollider(collider); + active = false; + } + location = UNASSIGNED; + gfx.filters = []; + gfx.visible = true; + gfx.scaleX = 1; + renderer.createSparkRect(collider, collider.width + collider.height); + } + /* Increases current level of item and sets attributes accordingly */ public function levelUp(n:int = 1):void{ if(!(type == WEAPON || type == ARMOUR)) return; diff --git a/src/com/robotacid/engine/Minion.as b/src/com/robotacid/engine/Minion.as index 682ec79..4dbab63 100644 --- a/src/com/robotacid/engine/Minion.as +++ b/src/com/robotacid/engine/Minion.as @@ -127,6 +127,7 @@ inventory.updateItem(item); return item; } + /* Unselect item as equipped */ override public function unequip(item:Item):Item{ super.unequip(item); @@ -152,6 +153,11 @@ } } + override public function finishQuicken():void { + // the minion's transformation event ends at the end of a quickening + super.finishQuicken(); + } + /* This pulls the minion to the vicinity of the player */ public function teleportToPlayer():void{ queueSummons = false; diff --git a/src/com/robotacid/engine/Player.as b/src/com/robotacid/engine/Player.as index ddc7f4f..611a4b5 100644 --- a/src/com/robotacid/engine/Player.as +++ b/src/com/robotacid/engine/Player.as @@ -320,7 +320,7 @@ if((looking & DOWN) || collider.state == Collider.FALL){ if(cameraDisplacement.y < CAMERA_DISPLACEMENT_Y){ cameraDisplacement.y += CAMERA_DISPLACE_SPEED * 0.5; - if((dir & DOWN) || collider.state == Collider.FALL) cameraDisplacement.y += CAMERA_DISPLACE_SPEED * 0.5; + if((dir & DOWN) || (collider.state == Collider.FALL && collider.world)) cameraDisplacement.y += CAMERA_DISPLACE_SPEED * 0.5; } } else if(looking & UP){ if(cameraDisplacement.y > -CAMERA_DISPLACEMENT_Y){ diff --git a/src/com/robotacid/engine/Stone.as b/src/com/robotacid/engine/Stone.as index 74319d9..7f1d01a 100644 --- a/src/com/robotacid/engine/Stone.as +++ b/src/com/robotacid/engine/Stone.as @@ -28,6 +28,7 @@ private var minimapFeature:MinimapFX; private var hits:int; + private var endGameEventData:Object; // names public static const SECRET_WALL:int = 0; @@ -94,7 +95,98 @@ /* This is used by the Death character during an end-game event */ override public function main():void { - //super.main(); + var i:int, item:Item; + var mc:MovieClip = gfx as MovieClip; + if(!endGameEventData.gotYendor){ + if(endGameEventData.count){ + endGameEventData.count--; + } else { + endGameEventData.yendor = game.gameMenu.inventoryList.getItem(Item.YENDOR, Item.ARMOUR); + // player has yendor, take it manually + if(endGameEventData.yendor){ + endGameEventData.playerX = game.player.collider.x + game.player.collider.width * 0.5 + endGameEventData.deathX = collider.x + collider.width * 0.5 + if(endGameEventData.deathX > endGameEventData.playerX){ + dir = looking = LEFT; + } else { + dir = looking = RIGHT; + } + endGameEventData.charContact = null; + if(collider.leftContact) endGameEventData.charContact = collider.leftContact.userData as Character; + if(!endGameEventData.charContact && collider.rightContact) endGameEventData.charContact = collider.rightContact.userData as Character; + if(endGameEventData.charContact == game.player){ + if(endGameEventData.yendor.user) endGameEventData.yendor = endGameEventData.yendor.user.unequip(endGameEventData.yendor); + game.gameMenu.inventoryList.removeItem(endGameEventData.yendor); + game.soundQueue.add("pickUp"); + endGameEventData.gotYendor = true; + } + // player may have dropped yendor - teleport it (a cheeky player may try to drop it into the water) + } else { + for(i = 0; i < game.items.length; i++){ + item = game.items[i]; + if(item.name == Item.YENDOR && item.type == Item.ARMOUR){ + if(item.mapX < mapX) dir = looking = LEFT; + else if(item.mapY > mapY) dir = looking = RIGHT; + if(collider.intersects(item.collider)){ + item.destroyOnMap(true); + game.createDistSound(item.mapX, item.mapY, "teleportYendor", Effect.TELEPORT_SOUNDS); + endGameEventData.gotYendor = true; + } + } + } + } + move(); + if(endGameEventData.gotYendor){ + game.console.print("death takes yendor"); + endGameEventData.count = 60; + } + } + } else if(!endGameEventData.transformedMinion){ + if(collider.x > endGameEventData.startX){ + dir = looking = LEFT; + move(); + } else { + dir = 0; + if(game.minion.mapX < mapX){ + looking = LEFT; + } else { + looking = RIGHT; + } + if(endGameEventData.count){ + if(game.minion.state == Character.WALKING) endGameEventData.count--; + move(); + if(endGameEventData.count == 0){ + game.minion.quicken(); + } + } else { + state = LUNGING; + p.x = mc.x + mc.weapon.x; + p.y = mc.y + mc.weapon.y; + if(weapon) p.x += weapon.gfx.getBounds(weapon.gfx).right; + for(i = 0; i < 3; i++){ + game.lightning.strike( + renderer.lightningShape.graphics, game.world.map, p.x, p.y, + game.minion.collider.x + game.minion.collider.width * 0.5, + game.minion.collider.y + game.minion.collider.height * 0.5 + ); + } + if(game.minion.state == Character.WALKING){ + game.endGameEvent = false; + state = WALKING; + callMain = false; + endGameEventData = null; + move(); + } else if(game.minion.state == Character.QUICKENING){ + if(game.minion.quickeningCount == 10){ + var explosion:Explosion = new Explosion(0, game.minion.mapX, game.minion.mapY, 3, 0, game.player, null, game.player.missileIgnore); + game.minion.changeName(Character.HUSBAND); + game.console.print(game.minion.nameToString() + " became husband"); + UserData.gameState.husband = true; + } + } + } + } + } } override public function createCollider(x:Number, y:Number, properties:int, ignoreProperties:int, state:int = 0, positionByBase:Boolean = true):void { @@ -189,6 +281,18 @@ revealed = true; } + /* Set up Death for the end game event of transforming the minion */ + public function setEndGameEvent():void{ + callMain = true; + endGameEventData = { + gotYendor:false, + transformedMinion:false, + startX:collider.x, + count:30, + charContact:null + } + } + /* Called to make this object visible */ override public function render():void{ if(name == DEATH){