#!/usr/bin/perl -w

# This contains some cell templates to generate quickly castles/towers

# usage: see vroom.pl

# ANNOTATIONS: see doc/notes.txt

# (c) Copyright by Tels 1999-2000. All Rights Reserved. Do NOT distribute.
# Updates and support on bloodgate.com/thief

# 2000-02-20 v0.0.1 - from scratch, mediumCastle, makeTower
# 2000-02-25 v0.0.2 - added cellar, some minor fixes

package Cowgen::VWorld::Castle;
require Exporter;
@ISA     = qw(Exporter);
@EXPORT_OK  = qw(
             mediumCastle
             makeTower
             );

use Cowgen::Bunch;
use Cowgen::VWorld::Room;
use Cowgen::Dromed;
use Cowgen::Architecture::Basics;
use Cowgen::Architecture::Inside;
use strict 'vars';

my $version = "0.0.2";
my $count = "000";

sub mediumCastle
  {
  # create a medium castle skeleton with 4 towers, gatehouse, cellar
  # it isnt too specific so that you can fill it later with rooms etc
  # name parameters: name, storeys, cellarstoreys, towerstoreys 
  # (how much storeys should the towers have), towersize, storeysize, gatehousesize,
  # width, length, thin (how much to thin out the wings; 0.1 of towersize works best;
  # can be relatively to towersize (0..-1)), yardroom, walltexture, skytexture
  my $p = $_[0];
  if (!defined $p)
    {
    $p = {}; 
    print "Warning: Description hash is undefined in mediumCastle().\n";
    }
  $p = { @_ } if (ref($p) ne 'HASH');
  my $name = $p->{name} || "mediumCastle##num##";
  $name =~ s/##num##/ $count++; /eg;
  my $storeys = abs($p->{storeys} || 2) || 1; 
  my $cellarstoreys = abs($p->{cellarstoreys} || 0);
  my $towerstoreys = abs($p->{towerstoreys} || 3);
  my $towersize = abs($p->{towersize} || 4);
  my $storeysize = abs($p->{storeysize} || 12);
  my $gatehousesize = abs($p->{gatehousesize} || $towersize*1.5);
  my $width = abs($p->{width} || $towersize*5);
  my $length = abs($p->{length} || $towersize*8);
  my $thin = rel2abs($p->{thin},$towersize);
  my $room = $p->{room};
  my $yardroom = $p->{yardroom} || $room;
  my $cellarroom = $p->{cellarroom} || $room;
  my $walltexture = $p->{walltexture} || -1; 
  my $skytexture = $p->{skytexture} || sky(); 
  # make towers
  my $allstoreys = $storeys+$towerstoreys;
  my $tower_se = makeTower("tower_se",$towersize,$storeysize,$allstoreys,$cellarstoreys);
  my $tower_sw = makeTower("tower_sw",$towersize,$storeysize,$allstoreys,$cellarstoreys);
  my $tower_ne = makeTower("tower_ne",$towersize,$storeysize,$allstoreys,$cellarstoreys);
  my $tower_nw = makeTower("tower_nw",$towersize,$storeysize,$allstoreys,$cellarstoreys);
  # make parts
  my $hs = $towerstoreys*$storeysize; my $ss = $storeys*$storeysize; 
  my $ws = $storeys;
  my $nw = splitWing(  "northwing", $width-2*$towersize, $skytexture, $walltexture, 
   $hs, $ss, $thin, 1, $ws, $storeysize,$yardroom,$towersize,$cellarstoreys,$cellarroom);
  my $ww = splitWing(  "westwing", $towersize, $skytexture, $walltexture, 
   $hs, $ss, $thin, 0, $ws, $storeysize,$yardroom,$towersize,$cellarstoreys,$cellarroom);
  my $ew = splitWing(  "eastwing", $towersize, $skytexture, $walltexture, 
   $hs, $ss, $thin, 0, $ws, $storeysize,$yardroom,$towersize,$cellarstoreys,$cellarroom);

  my $yardcellar = cell ( name => "mainyardcellar", size => $cellarstoreys*$storeysize, 
    div => inZ(), room => $cellarroom,
    );
  addCells ($yardcellar, $cellarstoreys, $storeysize, "yard_cellar##num##");
  my $mainyard = cell ( name => "yard", size => $storeysize*$allstoreys,
    room => $yardroom, nowall => NOWALL, 
  );
  my $yard = cell ( name => "center", size => $width-2*$towersize, div => inZ(),
    cells => [ $yardcellar, $mainyard ],
  );

  my $se = splitWing(  "southeastwing", ($width-$towersize*2-$gatehousesize)/2, $skytexture, 
   $walltexture, $hs, $ss, $thin, 1, $ws, $storeysize,$yardroom,$towersize,
   $cellarstoreys,$cellarroom);
  my $sw = splitWing(  "southwestwing", ($width-$towersize*2-$gatehousesize)/2, $skytexture, 
   $walltexture, $hs, $ss, $thin, 1, $ws, $storeysize,$yardroom,$towersize,
   $cellarstoreys,$cellarroom);
  my $headroom = { texture => $skytexture, nowall => aSouth()+aNorth()+aEast()+aWest(), 
    bandheight => 0, floortexture => $walltexture, ceilingtexture => $skytexture,
    clobberwall => NOWALL+NOEDGE, };
  # gate house
  my $ghc = cell ( name => "gatehousecellar", size => $storeysize*$cellarstoreys,  
      div => inZ(), room => $cellarroom,
    );
  addCells ($ghc, $cellarstoreys, $storeysize, "gatehouse_cellar##num##");
  my $gh = 
     cell ( name => "gatehouse", size => $storeysize*($storeys+$towerstoreys)-$storeysize/2,  
      div => inZ() );
  addCells ($gh, $storeys, $storeysize, "gatehouse_storey##num##");
  my $gatehouse = cell ( name => "gatehouse_all", size => $gatehousesize, div => inZ(),
   cells => [ 
     $ghc, $gh,
     cell ( name => "gatehouse_head", size => $storeysize/2, room => $headroom ),
    ] );
  # split into three parts
  my $n = cell( name => "northern", div => inY(), size => $towersize,  
    cells => [ $tower_nw, $nw, $tower_ne
    ] );
  my $m = cell( name => "middle", div => inY(), size => $length-2*$towersize, 
    cells => [ $ww, $yard, $ew
    ] );
  my $s = cell( name => "southern", div => inY(), size => $towersize, 
    cells => [ $tower_sw, $sw, $gatehouse, $se, $tower_se
    ] );
  my $castle = cell( 
    name => $name, div => inX(), size => $length,
     cells => [ $n, $m, $s
    ] ); 
  return $castle; 
  }

sub makeTower
  {
  # construct a multi storey tower
  # parameters: name, size, storeysize, storeys, cellarstoreys
  my $name = shift || "tower##num##";
  $name =~ s/##num##/ $count++; /eg;
  my $size = shift || 16;
  my $storeysize = shift || 8;
  my $storeys = shift || 3;
  my $cs = shift || 0;
  my $tower = cell( { name => $name, div => inZ(), size => $size, } ); 
  addCells ($tower, $cs, $storeysize, "$name"."_cellar##num##") if ($cs != 0);
  addCells ($tower, $storeys, $storeysize, "$name"."_storey##num##");
  $tower; # return
  }

sub splitWing
  {
  # generate a wing with headroom and fillrooms beside it
  # parameters: name, size, outsidetexture, walltexture, headsize, belowsize, thinsize,
  # direction, storeys, $storeysize, cellarstoreys
  my ($name,$size,$ot,$wt,$hs,$bs,$ts,$dir,$storeys,$storeysize,$fr,$es,$cs,$cr) = @_;
  $es = $size if (!defined $es);
  $ts = $ts/2;
  my $nw = aSouth()+aNorth(); $nw = aEast()+aWest() if ($dir == 0);
  $nw += aBottom();
  my $cw1 = aSouth()+aNorth(); $cw1 = aEast()+aWest() if ($dir == 0);
  my $nl = aWest()+aTop(); $nl = aNorth()+aTop() if ($dir == 1);
  my $nr = aEast()+aTop(); $nr = aSouth()+aTop() if ($dir == 1);
  my $cl = aWest(); $cl = aNorth() if ($dir == 1);
  my $cr = aEast(); $cr = aSouth() if ($dir == 1);
  my $f = aSouth(); $f = aEast() if ($dir == 1);
  my $hr = { texture => $wt, ceilingtexture => $ot, sidetexture => $ot, bandwidth => 0, 
   bandthick => 0, bandheight => 0, ceilingthick => 0, floorthick => 0, facing => $f,
   floortexture => $wt, clobberwall => $cw1, };
  my $head = cell ( name => "head_filler_$name", size => $hs, div => none(), 
   nowall => $nw, room => $hr);
  my $div = inX(); $div = inY() if ($dir == 0);
  my $below,$b;
  if ($ts > 0)
    {
    my $filler1 = cell ( name => "filler1_$name", size => $ts, div => none(), room => $fr, 
     nowall => $nl, clobberwall => $cl,);
    my $filler2 = cell ( name => "filler2_$name", size => $ts, div => none(), room => $fr,
     nowall => $nr, clobberwall => $cr, );
    my $wing = cell ( name => "$name", size => $es-$ts*2, div => inZ(), );
    $below = cell ( name => "below_$name", size => $bs, div => $div,
      cells => [ $filler1, $wing, $filler2] );
    $b = $wing;
    }  
  else
    {
    $b = cell ( name => "$name", size => $bs, div => inZ(), );
    }
  addCells ($b, $storeys, $storeysize, $name."_storey##num##");
  my $c = cell (name => "$name\_cellar", size => $cs*$storeysize, div => inZ(), 
    room => $cr,
    );
  addCells ($c, $cs, $storeysize, $name."_cellar##num##");
  my $cell = cell ( name => "complete_$name", size => $size, div => inZ(), 
    cells => [ $c, $below, $head ] );
  $cell;  
  }

1;
