View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001232 | Ecere SDK | ide:codeeditor | public | 2020-11-16 02:59 | 2020-11-16 02:59 |
Reporter | jerome | Assigned To | |||
Priority | immediate | Severity | crash | Reproducibility | have not tried |
Status | new | Resolution | open | ||
Target Version | 0.44.16 | ||||
Summary | 0001232: IDE Code Editor Freeze | ||||
Description | Frozen IDE after inserting text | ||||
Steps To Reproduce | Uncomment line 170 in attached file and type heavyShield, before HeavyShield { } | ||||
Tags | No tags attached. | ||||
Attached Files | tilesRPG.ec (18,324 bytes)
import "ecere" import "tiles" // define NILREM_START = Point { 28, 20 }; define NILREM_START = Point { 108, 20 }; TileMap * theMap; TileUnit * nilrem; Sprite nilremSprite; int vx, vy; bool inTheShop; define MAPW = 32; define MAPH = 20; define SHOP_POS = Point { 30, 20 }; enum ItemType { none = -1, lightShield = 0, dagger, longSword, battleSword, heavyShield, helmet, steelBoots, lightArmor, plateArmor, plateLeggings }; enum EquipmentSlot { head, feet, body, legs, leftHand, rightHand, ring, ring2, ring3, ring4 }; struct ItemStats { const String name; int value; EquipmentSlot slot; bool twoHands; int decDamage; int difficulty; int damage; }; ItemStats itemStats[ItemType] = { { "Light shield", 20, leftHand, false, 2 }, { "Dagger", 10, rightHand, false, 0, 2, 2 }, { "Long sword", 40, rightHand, false, 0, 4, 4 }, { "Battle sword", 100,rightHand, true, 0, 8, 10 }, { "Heavy shield", 100, leftHand, false, 5 }, { "Helmet", 60, head, false, 5 }, { "Steel boots", 40, feet, false, 2 }, { "Light armor", 40, body, false, 4 }, { "Plate armor", 150, body, false, 8 }, { "Plate leggings", 50, legs, false, 3 } }; class Spell { public: int difficulty; int damage; int manaCost; virtual void Backfire(Creature self, Creature opponent) { self.health -= damage/4; } virtual void Success(Creature self, Creature opponent) { if(damage > opponent.health) damage = opponent.health; PrintLn(self._class.name, " did ", damage, " damage to ", opponent._class.name, "."); opponent.health -= damage; } } class FireBall : Spell { difficulty = 20, damage = 8; manaCost = 5; }; class Lightning : Spell { difficulty = 10, damage = 4; manaCost = 3; }; class Healing : Spell { difficulty = 20; manaCost = 5; void Success(Creature self, Creature opponent) { self.health += self.maxHealth / 5; if(self.health > self.maxHealth) self.health = self.maxHealth; } void Backfire(Creature self, Creature opponent) { self.health -= damage/4; } }; class Creature { public: int xp; int health, maxHealth; int mana, maxMana; int dexterity; int magic; int strength; int gold; Array<Spell> spells; ItemType equipment[EquipmentSlot]; TileUnit * unit; Sprite sprite; } class Player : Creature { public: int manaPotions; int healthPotions; int training; spells = { [ FireBall { }, Lightning { }, Healing { } ] }; Player() { EquipmentSlot i; for(i = 0; i <= EquipmentSlot::ring4; i++) equipment[i] = none; } } class Slug : Creature { xp = 10; maxHealth = 10; dexterity = 7; strength = 5; gold = 1; } class GiantRat : Creature { xp = 30; maxHealth = 20; dexterity = 9; strength = 8; gold = 3; } class GiantSpider : Creature { xp = 50; maxHealth = 30; dexterity = 20; strength = 10; gold = 4; } class Bat : Creature { xp = 70; maxHealth = 10; dexterity = 40; strength = 5; gold = 6; } class Goblin : Creature { xp = 120; maxHealth = 50; dexterity = 50; strength = 25; gold = 10; } class Ghoul : Creature { xp = 250; maxHealth = 70; dexterity = 20; strength = 30; gold = 30; } class DarkKnight : Creature { xp = 500; maxHealth = 100; dexterity = 50; strength = 50; gold = 50; magic = 30; maxMana = 50; spells = { [ FireBall { } ] }; // equipment = { [ HeavyShield { }, LongSword { }, Helmet { }, SteelBoots { }, PlateArmor { }, PlateLeggings { }, null, null, null, null ] }; }; Array<Class> badGuys { [ class(Slug), class(GiantRat), class(GiantSpider), class(Goblin), class(Bat), class(DarkKnight), class(Ghoul) ]}; Sprite badGuysSprites[7]; class EvilSorcerer : Creature { xp = 1000; maxHealth = 1000; dexterity = 75; strength = 50; gold = 20000; magic = 50; maxMana = 500; //equipment = { [ HeavyShield { }, LongSword { }, Helmet { }, SteelBoots { }, PlateArmor { }, PlateLeggings { }, null, null, null, null ] }; spells = { [ FireBall { }, Lightning { }, Healing { } ] }; } Player player { xp = 0, maxHealth = 40, health = 40, mana = 20, maxMana = 20, magic = 20, strength = 10, dexterity = 10, gold = 1000, training = 2 }; enum UnitType { hut = 1, shop = 2 }; const String unitSpritesFiles[UnitType] = { "", "hut.png", "shop.png" }; const Point unitSpritesSize[UnitType] = { { 0, 0 }, { 2, 2 }, { 3, 3 } }; Sprite unitSprites[UnitType]; struct UnitPlacement { UnitType type; Point pos; }; Array<UnitPlacement> unitPlacements { [ { shop, SHOP_POS }, { hut, { 10, 10 } }, { hut, { 3, 15 } }, { hut, { 5, 7 } }, { hut, { 8, 19 } }, { hut, { 18, 18 } }, { hut, { 17, 17 } } ] }; define SHOP_ITEMS_POS = Point { 24, 240 }; define SHOP_ITEMS_SPACING = Point { 48, 48 }; class StatsUI : Window { background = black; void OnRedraw(Surface surface) { surface.background = red; surface.Area(10, 10, 10 + player.health * 260 / player.maxHealth, 20); surface.foreground = white; surface.Rectangle(10, 10, 270, 20); surface.WriteTextf(10, 24, "Health: %d / %d", player.health, player.maxHealth); surface.background = blue; surface.Area(10, 50, 10 + player.mana * 260 / player.maxMana, 60); surface.foreground = white; surface.Rectangle(10, 50, 270, 60); surface.WriteTextf(10, 64, "Mana: %d / %d", player.mana, player.maxMana); surface.foreground = gold; surface.WriteTextf(10, 90, "Gold coins: %d", player.gold); } } bool shopInventory[ItemType] = { true, true, true, true, true, true, true, true, true, true }; class ShopUI : Window { ItemType selectedItem; selectedItem = none; background = black; Picture backPic { this, image = { "shop-inside.png" }; anchor = { top = 0 }; clickThrough = true; }; Button btnBuy { backPic, master = this, disabled = true; position = { 220, 470 }; caption = "Buy item"; bool NotifyClicked(Button button, int x, int y, Modifiers mods) { ItemStats eq = itemStats[selectedItem]; EquipmentSlot slot = eq.slot; int tradeIn; ItemType tradeIn1 = none, tradeIn2 = none; if(slot == ring) while(player.equipment[slot] != none && slot < ring4) slot++; if(slot == rightHand && eq.twoHands) { if(player.equipment[EquipmentSlot::leftHand] != none) tradeIn1 = player.equipment[EquipmentSlot::leftHand]; if(player.equipment[EquipmentSlot::rightHand] != none) tradeIn2 = player.equipment[EquipmentSlot::rightHand]; } else if((slot == leftHand || slot == rightHand) && player.equipment[EquipmentSlot::rightHand] != none && itemStats[player.equipment[EquipmentSlot::rightHand]].twoHands) { if(player.equipment[EquipmentSlot::rightHand] != none) tradeIn1 = player.equipment[EquipmentSlot::rightHand]; } else if(player.equipment[slot] != none) tradeIn1 = player.equipment[slot]; tradeIn = ((tradeIn1 != none ? itemStats[tradeIn1].value : 0) + (tradeIn2 != none ? itemStats[tradeIn2].value : 0)) / 2; if(player.gold + tradeIn < eq.value) MessageBox { contents = "Y'aint got enough money! Watcha gonna do now huh? Run away like a coward? Come back when you have what you promised us!" }.Modal(); else { char message[1024] = ""; if(tradeIn1 != none && tradeIn2 != none) strcatf(message, "You will need to trade in your %s and %s, for %d .", itemStats[tradeIn1].name, itemStats[tradeIn2].name, tradeIn); else if(tradeIn1 != none) strcatf(message, "You will need to trade in your %s, for %d. ", itemStats[tradeIn1].name, tradeIn); strcatf(message, "Are you sure you want to buy this %s for %d?", eq.name, eq.value); if(MessageBox { type = yesNo, contents = message }.Modal() == yes) { if(tradeIn1 != none) shopInventory[tradeIn1] = true; if(tradeIn2 != none) shopInventory[tradeIn2] = true; if(eq.twoHands || (tradeIn1 != none && itemStats[tradeIn1].twoHands)) { player.equipment[leftHand] = none; player.equipment[rightHand] = none; } player.equipment[slot] = selectedItem; player.gold += tradeIn - eq.value; shopInventory[selectedItem] = false; selectedItem = none; } } return true; } }; bool OnLeftButtonDown(int x, int y, Modifiers mods) { if(x >= SHOP_ITEMS_POS.x && x < SHOP_ITEMS_POS.x + 5 * SHOP_ITEMS_SPACING.x && y >= SHOP_ITEMS_POS.y && y < SHOP_ITEMS_POS.y + 2 * SHOP_ITEMS_SPACING.y) { int ix = (x - SHOP_ITEMS_POS.x) / SHOP_ITEMS_SPACING.x; int iy = (y - SHOP_ITEMS_POS.y) / SHOP_ITEMS_SPACING.y; selectedItem = (ItemType)(iy * 5 + ix); if(!shopInventory[selectedItem]) selectedItem = none; btnBuy.disabled = selectedItem == none; Update(null); } return true; } void OnDrawOverChildren(Surface surface) { ItemType i; for(i = 0; i < 10; i++) { if(shopInventory[i]) { surface.Blit(shopItemsBitmap, SHOP_ITEMS_POS.x + (i%5) * SHOP_ITEMS_SPACING.x, SHOP_ITEMS_POS.y + (i/5) * SHOP_ITEMS_SPACING.y, 0, i * 32, 32, 32); } } if(selectedItem != -1) { int ix = selectedItem % 5; int iy = selectedItem / 5; ItemStats * stats = &itemStats[selectedItem]; surface.foreground = lime; surface.Rectangle( SHOP_ITEMS_POS.x + ix * SHOP_ITEMS_SPACING.x - 8, SHOP_ITEMS_POS.y + iy * SHOP_ITEMS_SPACING.y - 8, SHOP_ITEMS_POS.x + (ix+1) * SHOP_ITEMS_SPACING.x - 8, SHOP_ITEMS_POS.y + (iy+1) * SHOP_ITEMS_SPACING.y - 8); surface.foreground = white; surface.CenterTextf(140, 360, stats->name); surface.foreground = gold; surface.CenterTextf(140, 400, "%d gold coins", stats->value); surface.foreground = whiteSmoke; surface.WriteTextf(80, 420, "Damage: %d", stats->damage ? stats->damage : -stats->decDamage); if(stats->difficulty) surface.WriteTextf(80, 440, "Difficulty: %d", stats->difficulty); } } } Bitmap shopItemsBitmap { }; class App : GuiApplication { driver = "OpenGL"; timerResolution = 60; bool Cycle(bool idle) { nilrem->tick++; UnitUpdate(theMap, nilrem); mainWindow.Update(null); if(vx < 1024 - MAPW && nilrem->pos.x > vx + MAPW*3/4) vx++; else if(vx > 0 && nilrem->pos.x < vx + MAPW/4) vx--; if(vy < 1024 - MAPH && nilrem->pos.y > vy + MAPH*3/4) vy++; else if(vy > 0 && nilrem->pos.y < vy + MAPH/4) vy--; if(theMap->frames[nilrem->pos.y * 1024 + nilrem->pos.x] == 1) { if(GetRandom(1, 100) > 95) PrintLn("There *IS* a rat here!!!"); } if(nilrem->pos.x >= SHOP_POS.x && nilrem->pos.x <= SHOP_POS.x + 2 && nilrem->pos.y >= SHOP_POS.y && nilrem->pos.y <= SHOP_POS.y + 2) { if(!inTheShop) { mainWindow.shopUI.visible = true; inTheShop = true; } } else { mainWindow.shopUI.visible = false; inTheShop = false; } return true; } } class MainMap : Window { void OnRedraw(Surface surface) { int w = clientSize.w; int h = clientSize.h; surface.background = skyBlue; surface.Clear(colorBuffer); MapRedraw(theMap, surface, vx, vy, MAPW, MAPH); //surface.background = green; //surface.Area(100, 100, 200, 200); //surface.WriteTextf(10, 10, "Welcome to TimberCraft!"); } bool OnRightButtonDown(int x, int y, Modifiers mods) { UnitMove(theMap, nilrem, { vx + x / 32, vy + y / 32 }); return true; } } static const String chInventoryItems[] = { "ch-LightShield.png", "ch-Dagger.png", "ch-LongSword.png", "ch-battleSword.png", "ch-HeavyShield.png", "ch-Helmet.png", "ch-SteelBoots.png", "ch-LightArmor.png", "ch-PlateArmor.png", "ch-Leggings.png" }; class CharacterUI : Window { ItemType selectedItem; selectedItem = none; Bitmap bmpItems[10]; background = black; Picture backPic { this, image = { "character.png" }; anchor = { top = 0 }; clickThrough = true; }; bool OnLoadGraphics() { ItemType i; for(i = ItemType::lightShield; i <= ItemType::plateLeggings; i++) { bmpItems[i] = { alphaBlend = true }; bmpItems[i].Load(chInventoryItems[i], null, displaySystem); } return true; } void OnDrawOverChildren(Surface surface) { EquipmentSlot i; for(i = 0; i <= EquipmentSlot::ring4; i++) { ItemType type = player.equipment[i]; if(type != none) { Bitmap bmp = bmpItems[type]; if(bmp) surface.Blit(bmp, 0, 0, 0, 0, bmp.width, bmp.height); } } } } class TimberCraftWindow : Window { caption = $"TimberCraft"; background = formColor; borderStyle = sizable; hasMaximize = true; hasMinimize = true; hasClose = true; // clientSize = { 892, 323 }; clientSize = { 1370, 700 }; //position = { }; //state = maximized; //displayDriver = "OpenGL"; MainMap mainMap { this, clientSize = { MAPW * 32, MAPH * 32 }; position = { 24, 24 }; borderStyle = bevel; }; CharacterUI characterUI { this, clientSize = { 280, 500 }; anchor = { top = 0, right = 5 }; }; ShopUI shopUI { this, visible = false; caption = "The Shop"; clientSize = { 280, 500 }; anchor = { top = 0, right = 5 }; }; StatsUI stasUI { this, clientSize = { 280 }; anchor = { top = 500, right = 5, bottom = 0 }; }; TimberCraftWindow() { File f = FileOpen("map1.map", read); if(f) { int y = 0; char mapLine[1030]; int i; theMap = MapCreate(3, 1024, 1024, 32, 32, 4); for(i = 0; i < 3; i++) { theMap->dim[0] = { 1024, 1024 }; theMap->spaces[i] = new0 TileUnit * [1024 * 1024]; theMap->moves[i] = new0 byte[1024 * 1024]; } theMap->dim[1] = { 1024, 1024 }; theMap->dim[2] = { 1024, 1024 }; while(true) { if(f.GetLine(mapLine, sizeof(mapLine)) && y < theMap->maxDim.y) { int x; for(x = 0; x < theMap->maxDim.x; x++) { char ch = mapLine[x]; if(ch >= '0' && ch <= '9') { theMap->frames[y * theMap->maxDim.x + x ] = ch - '0'; } else break; } y++; } else break; } delete f; for(y = 0; y < 1024; y++) { int x; for(x = 0; x < 1024; x++) { uint16 frame = theMap->frames[y * 1024 + x]; theMap->moves[1][y * 1024 + x] = frame < 2; } } } // Load the character sprite nilremSprite = { }; // Create the character unit nilrem = UnitCreate(theMap, 1, NILREM_START.x, NILREM_START.y, null); nilrem->direction = South; nilrem->w = 1; nilrem->h = 1; nilrem->sprite = nilremSprite; UnitPlace(theMap, nilrem); // Load the buildings sprites UnitType u; for(u = hut; u <= shop; u++) unitSprites[u] = { }; // Place the buildings units for(u : unitPlacements) { UnitPlacement p = u; UnitType t = p.type; Point pos = p.pos; TileUnit * unit = UnitCreate(theMap, 0, pos.x, pos.y, null); if(t != shop) unit->covering[1] = 1; unit->direction = North; unit->w = unitSpritesSize[t].x; unit->h = unitSpritesSize[t].y; unit->sprite = unitSprites[t]; UnitPlace(theMap, unit); } } bool OnLoadGraphics() { bool result = false; int i; Bitmap mapTiles { }; if(mapTiles.Load("mapTiles.png", null, null)) { mapTiles.Convert(null, pixelFormat888, null); for(i = 0; i < theMap->numTiles; i++) { theMap->tileImage[i] = { }; theMap->tileImage[i].Allocate(null, theMap->tileW, theMap->tileH, 0, pixelFormat888, false); theMap->tileImage[i].Grab(mapTiles, 0, i * theMap->tileH); theMap->tileImage[i].MakeDD(displaySystem); } result = true; } delete mapTiles; nilremSprite.Load("Nilrem.png", null, true, false, null, displaySystem); // Load the buildings sprites UnitType u; for(u = hut; u <= shop; u++) unitSprites[u].Load(unitSpritesFiles[u], null, true, false, null, displaySystem); shopItemsBitmap.LoadT("items.png", null, displaySystem); return result; } bool OnKeyHit(Key key, unichar ch) { switch(key) { case right: nilrem->direction = East; break; case left: nilrem->direction = West; break; case up: nilrem->direction = North; break; case down: nilrem->direction = South; break; } Update(null); return true; } } TimberCraftWindow mainWindow {}; | ||||