2023-10-09 14:49:12 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Copyright (c) 2023 - Ognjen 'xolatile' Milan Robovic
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
-- Xabina is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either
-- version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
2023-10-09 14:49:12 -04:00
-- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-08 15:11:04 -04:00
-- Experimental minimal terminal rogue-like game in Ada programming language. I used to write a lot of Ada programs some time ago, then went in full C and assembly mode, and came
2023-10-09 14:49:12 -04:00
-- back to Ada, but realized that I keep my folders messy... Since it's bothersome to find my old Ada projects and share them here, I decided that the most easy thing to do is to
-- write a new program in Ada, a tiny game. Work in progress, it's messy and ugly for now...
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-08 15:11:04 -04:00
with ada.text_io , ada . strings . unbounded ;
use ada.text_io , ada . strings . unbounded ;
2023-10-09 16:33:18 -04:00
-- Do not use this command below, it's for real-time game...
-- $ gnatmake xabina.adb && stty raw -echo && ./xabina && reset
2023-10-08 15:11:04 -04:00
function xabina return integer is
2023-10-09 14:49:12 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- System
2023-10-09 14:56:48 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-08 15:11:04 -04:00
2023-10-09 15:26:24 -04:00
type integer_subrange is
record
minimum : integer := 0 ;
maximum : integer := 0 ;
end record ;
type natural_subrange is
2023-10-09 14:49:12 -04:00
record
minimum : natural := 0 ;
maximum : natural := 0 ;
end record ;
2023-10-09 16:33:18 -04:00
type colours is (
2023-10-09 14:49:12 -04:00
COLOUR_GREY , COLOUR_RED , COLOUR_GREEN , COLOUR_YELLOW , COLOUR_BLUE , COLOUR_PINK , COLOUR_CYAN , COLOUR_WHITE
) ;
2023-10-09 16:33:18 -04:00
type effects is (
2023-10-09 14:49:12 -04:00
EFFECT_NORMAL , EFFECT_BOLD , EFFECT_ITALIC , EFFECT_UNDERLINE , EFFECT_BLINK , EFFECT_REVERSE
) ;
2023-10-09 16:33:18 -04:00
function render_character ( -- A joke function...
symbol : character := ' ' ;
colour : colours := COLOUR_WHITE ;
effect : effects := EFFECT_NORMAL
) return natural is
begin
put ( character ' val ( 27 ) & "[" ) ;
case effect is
when EFFECT_NORMAL => put ( "0" ) ;
when EFFECT_BOLD => put ( "1" ) ;
when EFFECT_ITALIC => put ( "3" ) ;
when EFFECT_UNDERLINE => put ( "4" ) ;
when EFFECT_BLINK => put ( "5" ) ;
when EFFECT_REVERSE => put ( "7" ) ;
end case ;
put ( ";3" ) ;
case colour is
when COLOUR_GREY => put ( "0" ) ;
when COLOUR_RED => put ( "1" ) ;
when COLOUR_GREEN => put ( "2" ) ;
when COLOUR_YELLOW => put ( "3" ) ;
when COLOUR_BLUE => put ( "4" ) ;
when COLOUR_PINK => put ( "5" ) ;
when COLOUR_CYAN => put ( "6" ) ;
when COLOUR_WHITE => put ( "7" ) ;
end case ;
put ( "m" ) ;
put ( symbol ) ;
put ( character ' val ( 27 ) & "[0m" ) ;
return 1 ;
end render_character ;
2023-10-09 14:49:12 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Entity
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type entities is (
ENTITY_NONE , ENTITY_MENU , ENTITY_MAP , ENTITY_ITEM , ENTITY_PLANT , ENTITY_ANIMAL , ENTITY_GOBLIN , ENTITY_PLAYER ,
ENTITY_SPELL , ENTITY_AMMUNITION , ENTITY_WEAPON , ENTITY_ARMOUR , ENTITY_SCROLL , ENTITY_POTION , ENTITY_CONSUMABLE , ENTITY_NOTE
2023-10-09 14:56:48 -04:00
) ;
2023-10-09 14:49:12 -04:00
type entity_constant_type is tagged
record
2023-10-09 16:33:18 -04:00
entity : entities := ENTITY_NONE ; -- Entity identifier.
name : unbounded_string := null_unbounded_string ; -- Entity general name.
symbol : character := ' ' ; -- Entity ASCII character representation.
colour : colours := COLOUR_WHITE ; -- Entity VT100 escape sequence colour.
effect : effects := EFFECT_NORMAL ; -- Entity VT100 escape sequence effect.
2023-10-09 14:49:12 -04:00
end record ;
type entity_variable_type is tagged
record
x : integer := 0 ; -- Global X coordinate.
y : integer := 0 ; -- Global Y coordinate.
end record ;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Map:
-- -- Map data is only constant, not variable, since X and Y coordinates are determined by player, camera or global position.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type map_list is (
2023-10-09 14:49:12 -04:00
STONE_WALL , WOODEN_WALL , STONE_FLOOR , WOODEN_FLOOR
) ;
type map_constant_type is new entity_constant_type with
2023-10-08 15:11:04 -04:00
record
2023-10-09 16:33:18 -04:00
collide : boolean := false ;
2023-10-08 15:11:04 -04:00
end record ;
2023-10-09 16:33:18 -04:00
type map_constant_list is array ( map_list ) of map_constant_type ;
2023-10-08 15:11:04 -04:00
2023-10-09 16:33:18 -04:00
map_constant_data : constant map_constant_list := (
( ENTITY_MAP , to_unbounded_string ( "Stone Wall" ) , '#' , COLOUR_GREY , EFFECT_BOLD , true ) ,
( ENTITY_MAP , to_unbounded_string ( "Wooden Wall" ) , '#' , COLOUR_YELLOW , EFFECT_NORMAL , true ) ,
( ENTITY_MAP , to_unbounded_string ( "Stone Floor" ) , '.' , COLOUR_GREY , EFFECT_BOLD , false ) ,
( ENTITY_MAP , to_unbounded_string ( "Wooden Floor" ) , '.' , COLOUR_YELLOW , EFFECT_NORMAL , false )
2023-10-08 15:11:04 -04:00
) ;
2023-10-09 14:49:12 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
-- Weapon
2023-10-09 14:56:48 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type weapon_list is (
2023-10-09 15:26:24 -04:00
IRON_SWORD , IRON_GREATSWORD , IRON_AXE , IRON_BATTLEAXE , IRON_SPEAR , IRON_SHIELD , IRON_MACE , IRON_HAMMER
) ;
2023-10-09 16:33:18 -04:00
type weapon_mark is mod 72 ;
type weapon_constant_type is new entity_constant_type with
2023-10-09 15:26:24 -04:00
record
2023-10-09 16:33:18 -04:00
dual_wield : boolean := false ;
weight : natural := 0 ;
value : natural := 0 ;
attack_range : integer_subrange := ( 0 , 0 ) ;
defense_range : integer_subrange := ( 0 , 0 ) ;
distance_range : integer_subrange := ( 0 , 0 ) ;
-- description : unbounded_string := null_unbounded_string;
2023-10-09 15:26:24 -04:00
end record ;
2023-10-09 16:33:18 -04:00
type weapon_variable_type is new entity_variable_type with
2023-10-09 15:26:24 -04:00
record
2023-10-09 16:33:18 -04:00
enchantment : natural := 0 ;
condition : natural := 0 ;
2023-10-09 15:26:24 -04:00
end record ;
2023-10-09 16:33:18 -04:00
type weapon_constant_list is array ( weapon_list ) of weapon_constant_type ;
type weapon_variable_list is array ( weapon_mark ) of weapon_variable_type ;
weapon_constant_data : constant weapon_constant_list := (
( ENTITY_WEAPON , to_unbounded_string ( "Iron Sword" ) , ' l ' , COLOUR_RED , EFFECT_NORMAL , true , 31 , 11 , ( 3 , 7 ) , ( 0 , 2 ) , ( 0 , 1 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Greatsword" ) , ' L ' , COLOUR_RED , EFFECT_BOLD , false , 67 , 19 , ( 5 , 11 ) , ( 1 , 3 ) , ( 0 , 2 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Axe" ) , ' r ' , COLOUR_RED , EFFECT_NORMAL , true , 43 , 13 , ( 1 , 7 ) , ( 0 , 2 ) , ( 0 , 1 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Battleaxe" ) , ' T ' , COLOUR_RED , EFFECT_BOLD , false , 73 , 17 , ( 6 , 13 ) , ( 1 , 2 ) , ( 0 , 2 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Spear" ) , ' I ' , COLOUR_RED , EFFECT_BOLD , false , 53 , 11 , ( 4 , 10 ) , ( 2 , 4 ) , ( 0 , 2 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Shield" ) , ' o ' , COLOUR_RED , EFFECT_NORMAL , true , 37 , 13 , ( 0 , 3 ) , ( 4 , 9 ) , ( 0 , 1 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Mace" ) , ' i ' , COLOUR_RED , EFFECT_NORMAL , true , 41 , 11 , ( 3 , 8 ) , ( 0 , 2 ) , ( 0 , 1 ) ) ,
( ENTITY_WEAPON , to_unbounded_string ( "Iron Hammer" ) , ' t ' , COLOUR_RED , EFFECT_NORMAL , true , 47 , 13 , ( 4 , 7 ) , ( 0 , 3 ) , ( 0 , 1 ) )
2023-10-09 15:26:24 -04:00
) ;
2023-10-09 16:33:18 -04:00
weapon_variable_data : weapon_variable_list ;
2023-10-09 14:56:48 -04:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Plant
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type plant_list is (
PLANT_FLOWER , PLANT_GRASS , PLANT_REED , PLANT_BUSH , PLANT_APPLE_TREE , PLANT_LEMON_TREE , PLANT_OAK_TREE , PLANT_PINE_TREE
2023-10-09 14:56:48 -04:00
) ;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Animal
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type animal_list is (
ANIMAL_ROACH , ANIMAL_RAT , ANIMAL_BAT , ANIMAL_SPIDER , ANIMAL_LIZARD , ANIMAL_SNAIL , ANIMAL_WORM , ANIMAL_MOLE
2023-10-09 14:56:48 -04:00
) ;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 14:49:12 -04:00
-- Goblin
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
type goblin_list is (
GOBLIN_FEMALE , GOBLIN_WORKER , GOBLIN_WARRIOR , GOBLIN_BOAR_RIDER , GOBLIN_SHAMAN , GOBLIN_CHIEF , GOBLIN_KING , GOBLIN_OGRE
2023-10-09 14:56:48 -04:00
) ;
2023-10-09 14:49:12 -04:00
type goblin_constant_type is new entity_constant_type with
record
2023-10-09 15:26:24 -04:00
health_limit : natural := 0 ;
armour_limit : natural := 0 ;
mana_limit : natural := 0 ;
stamina_limit : natural := 0 ;
attack_range : natural_subrange := ( 0 , 0 ) ;
2023-10-09 14:49:12 -04:00
end record ;
type goblin_variable_type is new entity_variable_type with
record
2023-10-09 15:26:24 -04:00
health : natural := 0 ;
armour : natural := 0 ;
mana : natural := 0 ;
stamina : natural := 0 ;
2023-10-09 14:49:12 -04:00
end record ;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Gameplay
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-10-09 16:33:18 -04:00
x : natural := 0 ;
2023-10-08 15:11:04 -04:00
begin
2023-10-09 16:33:18 -04:00
for this in weapon_list
2023-10-08 15:11:04 -04:00
loop
2023-10-09 16:33:18 -04:00
put_line ( "> " & to_string ( weapon_constant_data ( this ) . name ) ) ;
2023-10-08 15:11:04 -04:00
end loop ;
2023-10-09 16:33:18 -04:00
x := x + render_character ( '@' , COLOUR_BLUE , EFFECT_BOLD ) ;
2023-10-08 15:11:04 -04:00
return 0 ;
end xabina ;