			   ------------------
			   -- Language War --
			   ------------------

-- See lw.doc for a complete description of how to play.
-- See lw.sum for a brief summary of the commands.

-- There's a VGA graphics version of this program in the Euphoria package
-- for WIN32.

-- This is based on a space war game developed in 1979 for the TRS-80 by 
-- David A. Craig with assistance from Robert H. Craig. 

-- Language War uses text mode. For examples of high-speed action games 
-- in graphics modes, complete with Sound Blaster sound effects, see the 
-- Games section of the Euphoria Archive. Go to 
-- http://www.RapidEuphoria.com and click "The Archive". Most of the games 
-- include complete source code.

-- Run with: eui lw.ex

type file_number(integer x)
    return x >= -1
end type

file_number sum_no
object line


include vars.e
include screen.e
include std/graphics.e

-- display summary file
sum_no = open("lw.sum", "r")
if sum_no != -1 then
    set_bk_color(BLUE)
    set_color(WHITE)
    clear_screen()
    while TRUE do
    line = gets(sum_no)
	if atom(line) then
	    exit
	end if
	puts(CRT, line)
    end while
    close(sum_no)
end if

include sched.e
include soundeff.e
include display.e
include damage.e
include weapons.e
include commands.e
include emove.e
include enemy.e

type energy_source(integer x)
    return x = G_PL or x = G_BS
end type

procedure setpb(pb_row row, energy_source stype)
-- initialize a planet or a base

    g_index r, c, ri, ci
    h_coord x, xi
    v_coord y, yi
    boolean unique

    -- choose a quadrant
    pb[row][P_TYPE] = stype
    r = rand(G_SIZE)
    c = rand(G_SIZE)
    pb[row][P_QR] = r
    pb[row][P_QC] = c
    
    pb[row][P_EN] = (rand(250) + rand(250)) * 50 + 30000
    galaxy[r][c][stype] = galaxy[r][c][stype] + 1

    -- choose a position in the quadrant
    while TRUE do
	if stype = G_PL then
	    x = rand(HSIZE - length(PLANET_MIDDLE) - 2*length(EUPHORIA_L)) 
		+ length(EUPHORIA_L)
	    y = rand(VSIZE-4) + 1
	else
	    x = rand(HSIZE - length(BASE) - 2*length(EUPHORIA_L))  
		+ length(EUPHORIA_L)
	    y = rand(VSIZE-3) + 1
	    pb[row][P_POD] = 1
	    pb[row][P_TORP] = rand(7) + 8
	end if
	pb[row][P_X] = x
	pb[row][P_Y] = y

	-- make sure position doesn't overlap another planet or base
	unique = TRUE
	for i = 1 to row - 1 do
	    ri = pb[i][P_QR]
	    ci = pb[i][P_QC]
	    if r = ri and c = ci then
		-- in the same quadrant
		xi = pb[i][P_X]
		if x >= xi - length(PLANET_MIDDLE) and
		   x <= xi + length(PLANET_MIDDLE) then
		    yi = pb[i][P_Y]
		    if y >= yi-2 and y <= yi+2 then
			unique = FALSE
			exit
		    end if
		end if
	    end if
	end for
	if unique then
	    exit
	end if
    end while
end procedure


procedure init()
-- initialize
    g_index r, c

    wrap(0)
    ship = {{EUPHORIA_L, EUPHORIA_R}, -- Euphoria
	   {KRC_L,       KRC_R},      -- K&R C
	   {ANC_L,       ANC_R},      -- ANSI C
	   {CPP_L,       CPP_R},      -- C++
	   {BASIC_L,     BASIC_R},    -- BASIC
	   {JAVA_L,      JAVA_R}}     -- Java

    otype = {"EUPHORIA",
	     "C",
	     "ANSI C",
	     "C++",
	     "BASIC",
	     "Java",
	     "PLANET",
	     "BASE"}

    -- initial waiting time between activations
    wait = {0.45, -- KEYB
	    0.67, -- EMOVE
	     6.0, -- LIFE
	INACTIVE, -- DEAD
	INACTIVE, -- BSTAT
	INACTIVE, -- FIRE
	     2.3, -- MOVE
	INACTIVE, -- MESSAGE
	INACTIVE, -- DAMAGE
	INACTIVE} -- ENTER

    -- early activation tolerance
    eat = {1.0,   -- KEYB
	   .04,   -- EMOVE
	   .20,   -- LIFE
	   .30,   -- DEAD
	   .30,   -- BSTAT
	   .20,   -- FIRE
	   .30,   -- MOVE
	   .20,   -- MESSAGE
	   .10,   -- DAMAGE
	   .30}   -- ENTER

    tcb = repeat(2, NTASKS)
    tcb[TASK_EMOVE] = 1 -- task emove scheduled to go first
    sched(TASK_BSTAT, 1 + rand(300))
    sched(TASK_ENTER, 1 + rand(60))
    sched(TASK_DAMAGE, INACTIVE)
    sched(TASK_DEAD, INACTIVE)
    scanon = FALSE

    -- blank lower portion
    set_bk_color(WHITE)
    set_color(BLACK)
    for i = WARP_LINE to WARP_LINE + 2 do
	position(i, 1)
	puts(CRT, repeat(' ', 80))
    end for

    -- set number of objects in the galaxy
    nobj = {1,  -- Euphoria (must be 1)
	   40,  -- regular K&R C ships
	    9,  -- ANSI C ships
	    1,  -- C++
	   50,  -- BASIC ships
	   20,  -- Java ships
	   NPLANETS,  -- planets
	   NBASES}    -- bases

    quadrant[EUPHORIA][Q_TYPE] = G_EU
    quadrant[EUPHORIA][Q_DEFL] = 3
    ds = repeat(DEFLECTOR, 3)
    quadrant[EUPHORIA][Q_TORP] = 5
    ts = repeat(TORPEDO, 5)
    ps = {POD}
    quadrant[EUPHORIA][Q_EN] = 30000
    wlimit = 5
    curwarp = 4
    curdir = 1
    exi = 3
    eyi = 0
    truce_broken = FALSE
    qrow = 1
    qcol = 1
    stext()
    nchars = 0

    -- initialize galaxy sequence
    galaxy = repeat(repeat(repeat(0, NTYPES), G_SIZE), G_SIZE)
    for i = G_KRC to G_JAV do
	for j = 1 to nobj[i] do
	    r = rand(G_SIZE)
	    c = rand(G_SIZE)
	    galaxy[r][c][i] = galaxy[r][c][i] + 1
	end for
    end for

    -- initialize planet/base sequence
    for i = 1 to nobj[G_BS] do
	setpb(i, G_BS)
    end for
    for i = nobj[G_BS]+1 to PROWS do
	setpb(i, G_PL)
    end for
    esymr = EUPHORIA_R
    esyml = EUPHORIA_L
    esym = EUPHORIA_R
    quadrant[EUPHORIA][Q_X] = HSIZE - length(esym) + 1
    quadrant[EUPHORIA][Q_Y] = VSIZE
    quadrant[EUPHORIA][Q_UNDER] = "   "
    qrow = pb[1][P_QR]
    qcol = gmod(pb[1][P_QC] - 1)
    bstat = TRUCE
    reptime[1..NSYS] = 0
    ndmg = 0
    wait[TASK_DAMAGE] = INACTIVE
    shuttle = FALSE
    set_bk_color(BLACK)
    set_color(WHITE)
    BlankScreen(TRUE)  -- blank upper portion
end procedure

procedure trek()
-- Language War Main Routine

    natural nk

    init()
    current_task = TASK_FIRE
    if level = 'n' then
	wait[TASK_FIRE] = 3.0 -- novice level
    else
	wait[TASK_FIRE] = 1.0 -- expert level
    end if
    gameover = FALSE

    while not gameover do
	sched(current_task, wait[current_task])
	current_task = next_task()
	if current_task = TASK_KEYB then
	    task_keyb()

	elsif current_task = TASK_FIRE then
	    task_fire()

	elsif current_task = TASK_EMOVE then
	    task_emove()

	elsif current_task = TASK_LIFE then
	    task_life()

	elsif current_task = TASK_MOVE then
	    task_move()

	elsif current_task = TASK_MESSAGE then
	    task_message()

	elsif current_task = TASK_DAMAGE then
	    task_dmg()

	elsif current_task = TASK_ENTER then
	    task_enter()

	elsif current_task = TASK_DEAD then
	    task_dead()

	elsif current_task = TASK_BSTAT then
	    task_bstat()

	end if
    end while

    nk = c_remaining()
    set_msg()
    if nk = 0 then
	victory_sound()
	set_color(RED+BLINKING)
	puts(CRT, "PROGRAMMERS THROUGHOUT THE GALAXY ARE EUPHORIC!!!!!")
	delay(15)
    else
	printf(CRT, "%d C SHIPS REMAIN. YOU ARE DEAD. C RULES THE GALAXY!", nk)
	delay(5)
    end if
end procedure

puts(CRT, "    Type n for novice level: ")
init_delay() -- uses up some time - do it here while user is thinking

sequence in 
in = gets(0)
if find('n', in) then
    level = 'n'
else
    level = 'e'    
end if

cursor(NO_CURSOR)

trek()

position(max_lines, 1)
cursor(UNDERLINE_CURSOR)
set_bk_color(BLACK)
set_color(WHITE)
puts(CRT, '\n')


