importing devsrv CVS to Savannah CVS
166
MANUAL.norwegian
|
@ -1,48 +1,56 @@
|
|||
/* $Id$ */
|
||||
|
||||
|
||||
|
||||
Kontroller
|
||||
|
||||
|
||||
|
||||
* Piltaster: Panorer
|
||||
Piltaster: Panorer
|
||||
|
||||
* Venstreklikk: Velg enhet/flytt enhet
|
||||
Venstreklikk: Velg enhet/flytt enhet
|
||||
|
||||
* Høyreklikk: Hovedmeny, avbryt handling
|
||||
Høyreklikk: Hovedmeny, avbryt handling
|
||||
|
||||
* Escape: Avslutt spill
|
||||
Tredje museknapp: Sentrer på peker
|
||||
|
||||
* z: Zoom inn
|
||||
Escape: Avslutt spill
|
||||
|
||||
* x: Zoom ut
|
||||
z: Zoom inn
|
||||
|
||||
* c: Standard zoom-nivå
|
||||
x: Zoom ut
|
||||
|
||||
* u: Angre siste trekk (bare deterministiske flytt kan omgjøres)
|
||||
c: Standard zoom-nivå
|
||||
|
||||
* r: Gjenta trekk
|
||||
u: Angre siste trekk (bare deterministiske flytt kan omgjøres)
|
||||
|
||||
* n: Gå gjennom alle enheter som kan flytte
|
||||
r: Gjenta trekk
|
||||
|
||||
* l: Gå til lederenhet
|
||||
n: Gå gjennom alle enheter som kan flytte
|
||||
|
||||
* space: Avslutt runden for denne enheten, og gå videre til neste enhet som kan flytte
|
||||
1-7: Vis hvor langt valgte enhet kan flytte på x antall runder
|
||||
|
||||
* ctrl-f: Bytt mellom fullskjerm- og vindumodus
|
||||
space: Avslutt runden for denne enheten, og gå videre til neste enhet som kan flytte
|
||||
|
||||
* ctrl-r: Rekrutter enhet
|
||||
l: Gå til lederenhet
|
||||
|
||||
* ctrl-c: Tilbakekall enhet
|
||||
ctrl-f: Bytt mellom fullskjerm- og vindumodus
|
||||
|
||||
* ctrl-a: Skru på/av akselerert spillmodus
|
||||
ctrl-r: Rekrutter enhet
|
||||
|
||||
* d: Beskriv valgte enhet
|
||||
ctrl-shift-r: Gjenta siste rekruttering
|
||||
|
||||
* ctrl-d: Studer den valgte enhets motstand mot angrep
|
||||
ctrl-c: Tilbakekall enhet
|
||||
|
||||
* ctrl-t: Studer hvordan den valgte enhet takler forskjellige typer terreng
|
||||
ctrl-a: Skru på/av akselerert spillmodus
|
||||
|
||||
* ctrl-s: Lagre spill
|
||||
d: Beskriv valgte enhet
|
||||
|
||||
ctrl-d: Studer den valgte enhets motstand mot angrep
|
||||
|
||||
ctrl-t: Studer hvordan den valgte enhet takler forskjellige typer terreng
|
||||
|
||||
ctrl-s: Lagre spill
|
||||
|
||||
|
||||
|
||||
|
@ -52,7 +60,7 @@ Lyskuler
|
|||
|
||||
|
||||
|
||||
Hvordan kan jeg se om en enhet er venn eller fiende? På toppen av energiindikatoren som finnes ved siden av hver enhet er det en lyskule. Denne lyskulen forteller:
|
||||
På toppen av livsindikatoren som finnes ved siden av hver enhet er det en lyskule. Denne lyskulen er:
|
||||
|
||||
|
||||
|
||||
|
@ -64,9 +72,9 @@ Hvordan kan jeg se om en enhet er venn eller fiende? P
|
|||
|
||||
* blå hvis enheten tilhører en alliert, men ikke er kontrollert av deg
|
||||
|
||||
* svart hvis enheten er fiendtlig
|
||||
|
||||
|
||||
Fiendtlige enheter har ingen lyskule på toppen av livsindikatoren. (I tidligere versjoner < 0.5.2 var det en svart kule på toppen av livsindikatoren til fiendtlige enheter)
|
||||
|
||||
|
||||
|
||||
|
@ -80,11 +88,27 @@ Spillet skjer gjennom en serie kamper, eller scenario. Hvert scenario setter din
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
Gull
|
||||
|
||||
|
||||
|
||||
Hver side blir gitt et beløp gull i begynnelsen, og mottar så 2 gullstykker per runde, pluss 2 gullstykker for hver landsby som kontrolleres. Hver side må betale 1 gullstykke i underhold hver runde per enhet på slagmarken.
|
||||
Hver side blir gitt et beløp gull i begynnelsen, og mottar så 2 gullstykker per runde, pluss 2 gullstykker for hver landsby som kontrolleres.
|
||||
|
||||
|
||||
|
||||
Hver enhet har også en underholdskostnad. Denne kostnader er generelt lik nivået til enheten (men se karaktertrekket 'Lojal' under). Enheter som ikke blir tilbakekalt eller rekruttert - det vil si, enheter som leder en side eller blir med frivillig - har ingen underholdskostnad. Underhold blir bare betalt hvis totalt underhold for enhetene til en side er større enn antall landsbyer den siden kontrollerer. Underhold som blir betalt er differansen mellom antall landsbyer og underholdskostnaden. Formelen for å bestemme inntekt per runde blir derfor:
|
||||
|
||||
|
||||
|
||||
2 + antall landsbyer - maksimum(0, underhold - landsbyer)
|
||||
|
||||
|
||||
|
||||
hvor underhold er lik summen av nivåene til alle enheter som har blitt tilbakekalt eller rekruttert.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -104,11 +128,41 @@ Du kan f
|
|||
|
||||
|
||||
|
||||
Du kan ikke flytte en enhet samme runde som den blir rekruttert eller tilbakekalt.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Enhetsspesialiteter
|
||||
|
||||
|
||||
|
||||
Enhetsspesialiteter er beskrevet under Beskrivelse i hovedmenyen.
|
||||
Enhetsspesialiteter er beskrevet under Beskrivelse inne i selve spillet.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Karaktertrekk
|
||||
|
||||
|
||||
|
||||
Enheter har personlige egenskaper som reflekterer deres karakter. Karaktertrekk blir tildelt enheter tilfeldig når hyres. Hver enhet får tildelt to karaktertrekk. Mulige karaktertrekk er som følger:
|
||||
|
||||
|
||||
|
||||
Lojal: Enheten betaler aldri mer en 1 i underhold.
|
||||
|
||||
Sterk: Enheten gjør ekstra skade i nærkamp, og har noen ekstra livspoeng.
|
||||
|
||||
Rask: Enheten kan flytte en ekstra rute, men har litt færre livspoeng.
|
||||
|
||||
Motstandsdyktig: Enheten har flere livspoeng.
|
||||
|
||||
Intelligent: Enheten trenger færre erfaringspoeng for å avansere til et høyere nivå.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -120,6 +174,12 @@ N
|
|||
|
||||
|
||||
|
||||
Du kan ikke flytte gjennom de seks rutene rundt en motstander (deres Kontrollsone) uten å stoppe.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Kamp
|
||||
|
||||
|
||||
|
@ -140,6 +200,8 @@ Hver enhet har en viss sjanse for
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
Holdning
|
||||
|
||||
|
||||
|
@ -148,10 +210,6 @@ Hver enhet har en holdning: lovlydig, n
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| runde | tid |
|
||||
|
||||
-------------------------
|
||||
|
@ -170,19 +228,23 @@ Hver enhet har en holdning: lovlydig, n
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Lovlydige enheter gjør 25% mer skade om dagen, og 25% mindre om natten. Kaotiske enheter gjør 25% mer skade om natten, og 25% mindre om dagen. Nøytrale enheter blir ikke påvirket av dag/natt syklusen.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Helbredelse
|
||||
|
||||
|
||||
|
||||
Skadde enheter i landsbyer vil heles 8 livspoeng hver runde. Skadde enheter ved siden av enheter med 'helbrede' eller 'kurere' egenskaper vil også bli helbredet. Enheter ved siden av enheter som har 'helbrede' som egenskap vil heles maksimum 4 livspoeng per runde, og 8 livspoeng per runde for enheter som har 'kurere' som egenskap. Jo flere enheter det er rundt en helbredende enhet, jo mindre vil hver bli helbredet.
|
||||
Skadde enheter i landsbyer vil heles 8 livspoeng hver runde. Skadde enheter ved siden av enheter som innehar 'helbreder' eller 'kurerer' -evner vil også bli helbredet. Enheter ved siden av enheter som har 'helbreder' som evne vil heles maksimum 4 livspoeng per runde, og 8 livspoeng per runde for enheter som har 'kurerer' som evne. Jo flere enheter det er rundt en helbredende enhet, jo mindre vil hver bli helbredet.
|
||||
|
||||
|
||||
|
||||
'Helbreder' gjør at forgiftning ikke gjør skade, mens 'kurerer' fjerner forgiftningen helt. Når forgiftning blir kurert får ikke enheten som blir kurert tilbake livspoeng den runden.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -194,5 +256,41 @@ Enheter f
|
|||
|
||||
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
Flerspiller
|
||||
|
||||
|
||||
|
||||
Det er også flere måter å delta i en flerspiller-omgang med Wesnoth. Den enkleste måten er et 'samme-stol' spill: Flere spillere spiller på samme PC, det hver spiller overtar når det er hans tur. For å starte et 'samme-stol' spill, velg 'Flerspiller' fra hovedmenyen -> 'Vert for flerspiller'. Etter å ha valgt kart, endre alle navnene i 'Spillertype' til å være menneske eller datastyrte spillere (altså ingen 'Nettverksspillere'), og start så spillet.
|
||||
|
||||
|
||||
|
||||
Du kan også spille Wesnoth over nettverk. En spiller bruker sin PC som 'vert', og andre spillere henger seg på. Velg 'Flerspiller' -> 'Vert for flerspiller', og endre så noen av 'Spillertype' boksene til 'Nettverksspiller'. Når du har startet spillet, vil det vente på at andre spillere skal henge seg på. De andre spillerne må velge 'Flerspiller' -> 'Bli med i spill', og så skrive navnet til vertsmaskinen eller IP-adressen til spilleren som er vert.
|
||||
|
||||
|
||||
|
||||
Når alle spillerne har hengt seg på begynner spillet. Spilleren som er vert må være i stand til å motta forbindelser til port 15000. De andre spillerne må kunne binde seg til port 15000 på en ekstern maskin. Du kan bare spille spill over nettverk mot spillere som har eksakt samme versjon av spillet som deg.
|
||||
|
||||
|
||||
|
||||
Du kan også spille spill på Wesnoths egne tjenere. Wesnoth har to offentlig tilgjengelige tjenere:
|
||||
|
||||
|
||||
|
||||
server.wesnoth.org: for utgitte versjoner av spillet
|
||||
|
||||
devsrv.wesnoth.org: for CVS versjoner av spillet (versjoner under utvikling)
|
||||
|
||||
|
||||
|
||||
For å koble til tjeneren, velg 'Flerspiller' -> 'Bli med i spill' og skriv så vertsnavnet til tjeneren. Du må bruke nøyaktig den versjonen av spillet som tjeneren er satt opp for å bruke, for å få lov til å spille.
|
||||
|
||||
|
||||
|
||||
Når du er tilkoblet tjeneren, blir du plasser i et 'vestibyle'. I vestibylen kan du se hvilke andre spillere som er på nett, hvilke spill som er tilgjengelige, og starte nye spill. En spiller starter et nytt spillet, så kan de andre spillerne henge seg på.
|
||||
|
||||
|
||||
|
||||
Det er mulig å bare observere et pågående spill, ved å bli med i spillet som en 'Observatør'.
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = src
|
||||
if ICONS
|
||||
ISUBDIRS = icons
|
||||
else
|
||||
ISUBDIRS =
|
||||
endif
|
||||
SUBDIRS = src $(ISUBDIRS)
|
||||
pkgdatadir=$(datadir)/@DATADIR@
|
||||
|
||||
dist_noinst_DATA = @MANUAL_FILES@ copyright changelog @UTIL_FILES@
|
||||
|
|
23
Makefile.in
|
@ -1,4 +1,4 @@
|
|||
# Makefile.in generated by automake 1.7.9 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.7.8 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
|
@ -64,11 +64,22 @@ EDITOR_TRUE = @EDITOR_TRUE@
|
|||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FONT_FILES = @FONT_FILES@
|
||||
GNOME1_DESKTOP = @GNOME1_DESKTOP@
|
||||
GNOME1_FALSE = @GNOME1_FALSE@
|
||||
GNOME1_TRUE = @GNOME1_TRUE@
|
||||
GNOME_CONFIG = @GNOME_CONFIG@
|
||||
ICONS_FALSE = @ICONS_FALSE@
|
||||
ICONS_TRUE = @ICONS_TRUE@
|
||||
IMAGE_FILES = @IMAGE_FILES@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
KDE_CONFIG = @KDE_CONFIG@
|
||||
KDE_DESKTOP = @KDE_DESKTOP@
|
||||
KDE_FALSE = @KDE_FALSE@
|
||||
KDE_ICON = @KDE_ICON@
|
||||
KDE_TRUE = @KDE_TRUE@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
|
@ -131,7 +142,9 @@ sharedstatedir = @sharedstatedir@
|
|||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = src
|
||||
@ICONS_TRUE@ISUBDIRS = icons
|
||||
@ICONS_FALSE@ISUBDIRS =
|
||||
SUBDIRS = src $(ISUBDIRS)
|
||||
|
||||
dist_noinst_DATA = @MANUAL_FILES@ copyright changelog @UTIL_FILES@
|
||||
nobase_dist_pkgdata_DATA = @DATA_FILES@ @FONT_FILES@ @IMAGE_FILES@ @MUSIC_FILES@ @SOUND_FILES@
|
||||
|
@ -158,7 +171,7 @@ DIST_COMMON = README $(dist_man6_MANS) $(dist_noinst_DATA) \
|
|||
$(srcdir)/configure COPYING INSTALL Makefile.am aclocal.m4 \
|
||||
config.h.in configure configure.ac depcomp install-sh missing \
|
||||
mkinstalldirs
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
DIST_SUBDIRS = src icons
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
|
@ -430,7 +443,7 @@ distdir: $(DISTFILES)
|
|||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|
@ -530,7 +543,7 @@ install-am: all-am
|
|||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
|
26
changelog
|
@ -1,3 +1,29 @@
|
|||
Version 0.6.2:
|
||||
* extended tutorial
|
||||
* two new music tracks
|
||||
* new scenarios for 'The Dark Hordes' campaign:
|
||||
* Mages and Elves
|
||||
* scenario balancing for 'Dark Hordes' campaign:
|
||||
* Brother Against Brother
|
||||
* The Skull of Agarash
|
||||
* multiplayer improvements:
|
||||
* added basic random map generator
|
||||
* made basic messaging possible using 'Speak' from main menu
|
||||
* medium difficulty level is used by default when starting new campaign
|
||||
* snapshot saving, faster loading if you skip replay
|
||||
* more unit graphics and animations
|
||||
* undeads can not be drained anymore
|
||||
* fixed description for 'Wolf Rider'
|
||||
* updated translations:
|
||||
* dutch
|
||||
* internationalization: string fixes
|
||||
* fixed client-hosted multiplayer bug where more than two player games were not possible
|
||||
* fixed problem with saving at the end of the scenario pointing to the previous scenario
|
||||
* autotools: checks for png support in sdl_image and ogg support in sdl_mixer
|
||||
* autotools: application icon and menu entries in KDE and GNOME
|
||||
* improved speed of reading cfg-files
|
||||
* code refactoring
|
||||
|
||||
Version 0.6.1:
|
||||
* removed plague ability from Wraiths
|
||||
* decreased Lich's melee damage by one
|
||||
|
|
138
config.h.in
|
@ -1,156 +1,104 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <dirent.h>
|
||||
header file, and it defines `DIR'. */
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the `floor'
|
||||
function. */
|
||||
/* Define to 1 if you have the `floor' function. */
|
||||
#undef HAVE_FLOOR
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <inttypes.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <memory.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the `SDL_mixer' library (-lSDL_mixer). */
|
||||
#undef HAVE_LIBSDL_MIXER
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <ndir.h>
|
||||
header file, and it defines `DIR'. */
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the `socket'
|
||||
function. */
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#undef HAVE_SOCKET
|
||||
|
||||
/*
|
||||
Define to 1 if `stat' has the bug
|
||||
that it succeeds when given the zero-length file name
|
||||
argument. */
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
#undef HAVE_STAT_EMPTY_STRING_BUG
|
||||
|
||||
/*
|
||||
Define to 1 if stdbool.h conforms to C99.
|
||||
*/
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <stdint.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <stdlib.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the `strftime'
|
||||
function. */
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <strings.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <string.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the `strtoul'
|
||||
function. */
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <sys/dir.h>
|
||||
header file, and it defines `DIR'. */
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <sys/ndir.h>
|
||||
header file, and it defines `DIR'. */
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <sys/stat.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <sys/types.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <unistd.h>
|
||||
header file. */
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/*
|
||||
Define to 1 if the system has the
|
||||
type `_Bool'. */
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#undef HAVE__BOOL
|
||||
|
||||
/*
|
||||
Define to 1 if `lstat' dereferences a symlink
|
||||
specified with a trailing slash. */
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
|
||||
/*
|
||||
Name of package */
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/*
|
||||
Define to the address where bug reports for
|
||||
this package should be sent. */
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/*
|
||||
Define to the full name of this package.
|
||||
*/
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/*
|
||||
Define to the full name and version of
|
||||
this package. */
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/*
|
||||
Define to the one symbol short name of
|
||||
this package. */
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/*
|
||||
Define to the version of this package. */
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/*
|
||||
Define to 1 if you have the ANSI
|
||||
C header files. */
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/*
|
||||
Define to 1 if your <sys/time.h> declares `struct
|
||||
tm'. */
|
||||
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/*
|
||||
Version number of package */
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/*
|
||||
Define to empty if `const' does not conform
|
||||
to ANSI C. */
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
|
@ -159,12 +107,8 @@
|
|||
#undef inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
Define to `int' if <sys/types.h> does not define.
|
||||
*/
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
/*
|
||||
Define to `unsigned' if <sys/types.h> does not define.
|
||||
*/
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
|
150
configure.ac
|
@ -1,13 +1,17 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(wesnoth, 0.8, davidnwhite@optusnet.com.au, Battle for Wesnoth)
|
||||
#######################################################################
|
||||
# Initial configuration #
|
||||
#######################################################################
|
||||
|
||||
AC_REVISION($Version: 0.8$)
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(wesnoth, 0.11, davidnwhite@optusnet.com.au, Battle for Wesnoth)
|
||||
|
||||
AC_REVISION($Version: 0.11$)
|
||||
PACKAGE=wesnoth
|
||||
MAJOR_VERSION="0"
|
||||
MINOR_VERSION="6"
|
||||
MICRO_VERSION="1"
|
||||
MICRO_VERSION="2-CVS"
|
||||
|
||||
if test "x$MICRO_VERSION" = "x"; then
|
||||
VERSION=$MAJOR_VERSION.$MINOR_VERSION
|
||||
|
@ -19,23 +23,63 @@ AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
|
|||
AC_CONFIG_SRCDIR([src/actions.cpp])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
|
||||
#######################################################################
|
||||
# Checks for programs. #
|
||||
#######################################################################
|
||||
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
|
||||
|
||||
# SDL_CONFIG
|
||||
|
||||
AC_PATH_PROGS(SDL_CONFIG, [sdl-config sdl11-config], none)
|
||||
|
||||
if test "x$SDL_CONFIG" = "xnone"; then
|
||||
|
||||
AC_MSG_ERROR([*** SDL not found! Get SDL from www.libsdl.org.
|
||||
AC_MSG_ERROR([*** SDL not found! Get SDL from www.libsdl.org.
|
||||
If you already installed it, check it's in the path. If problem remains,
|
||||
please send a mail to the address that appears in ./configure --version
|
||||
indicating your platform, the version of configure script and the problem.])
|
||||
|
||||
fi
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# GNOME_CONFIG
|
||||
|
||||
AC_PATH_PROGS([GNOME_CONFIG], [gnome-config], [none])
|
||||
|
||||
if test "x$GNOME_CONFIG" = "xnone"; then
|
||||
gnome1=no
|
||||
else
|
||||
GNOME1_DESKTOP=`$GNOME_CONFIG --datadir`/gnome/apps/Games
|
||||
gnome1=yes
|
||||
fi
|
||||
|
||||
AC_SUBST([GNOME1_DESKTOP])
|
||||
AM_CONDITIONAL(GNOME1, test x$gnome1 = xyes)
|
||||
|
||||
|
||||
# KDE_CONFIG
|
||||
|
||||
AC_PATH_PROGS(KDE_CONFIG, kde-config, none)
|
||||
|
||||
if test "x$KDE_CONFIG" = "xnone"; then
|
||||
kde=no
|
||||
else
|
||||
KDE_DESKTOP=`$KDE_CONFIG --expandvars --install apps`/Games/TacticStrategy
|
||||
KDE_ICON=`$KDE_CONFIG --expandvars --install icon`
|
||||
kde=yes
|
||||
fi
|
||||
|
||||
AC_SUBST([KDE_DESKTOP])
|
||||
AC_SUBST([KDE_ICON])
|
||||
AM_CONDITIONAL(KDE, test x$kde = xyes)
|
||||
|
||||
#######################################################################
|
||||
# Checks for libraries. #
|
||||
#######################################################################
|
||||
|
||||
SDL_LIBS=`$SDL_CONFIG --libs`
|
||||
OLD_LIBS=$LIBS
|
||||
|
@ -50,7 +94,7 @@ AC_CHECK_LIB([SDL_image],
|
|||
[SDL_IMAGE_LIBS=-lSDL_image],
|
||||
[AC_MSG_ERROR([*** SDL_image lib not found! Get SDL_image from
|
||||
http://www.libsdl.org/projects/SDL_image/index.html])])
|
||||
|
||||
|
||||
AC_CHECK_LIB([SDL_mixer],
|
||||
[Mix_OpenAudio],
|
||||
[SDL_MIXER_LIBS=-lSDL_mixer],
|
||||
|
@ -77,7 +121,11 @@ AC_SUBST([SDL_MIXER_LIBS])
|
|||
AC_SUBST([SDL_NET_LIBS])
|
||||
AC_SUBST([SDL_TTF_LIBS])
|
||||
|
||||
# Checks for header files.
|
||||
|
||||
#######################################################################
|
||||
# Checks for header files. #
|
||||
#######################################################################
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
|
||||
|
@ -121,7 +169,11 @@ AC_SUBST([SDL_CFLAGS])
|
|||
|
||||
AC_CHECK_HEADERS([stdlib.h unistd.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
#######################################################################
|
||||
# Checks for typedefs, structures, and compiler characteristics. #
|
||||
#######################################################################
|
||||
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
@ -135,6 +187,64 @@ AC_FUNC_STAT
|
|||
AC_FUNC_STRFTIME
|
||||
AC_CHECK_FUNCS([floor socket strtoul])
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Check for PNG support in SDL_image #
|
||||
#######################################################################
|
||||
|
||||
AC_MSG_CHECKING([for PNG support in SDL_image])
|
||||
|
||||
OLD_CPPFLAGS=$CPPFLAGS
|
||||
OLD_CXXFLAGS=$CXXFLAGS
|
||||
OLD_LIBS=$LIBS
|
||||
|
||||
CPPFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
CXXFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS $SDL_LIBS $SDL_IMAGE_LIBS"
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <SDL_image.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
SDL_RWops *src;
|
||||
|
||||
src = SDL_RWFromFile("images/mage.png", "rb");
|
||||
if (src == NULL)
|
||||
exit(0);
|
||||
exit(!IMG_isPNG(src));
|
||||
}
|
||||
],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)]
|
||||
[AC_MSG_ERROR([*** SDL_image has no PNG support! You need SDL_image with PNG support])],
|
||||
[AC_MSG_RESULT[not tested in cross-compiling]])
|
||||
|
||||
CPPFLAGS=$OLD_CPPFLAGS
|
||||
CXXFLAGS=$OLD_CXXFLAGS
|
||||
LIBS=$OLD_LIBS
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Check for OGG support in SDL_mixer #
|
||||
#######################################################################
|
||||
|
||||
OLD_LIBS=$LIBS
|
||||
LIBS="$LIBS $SDL_LIBS $SDL_MIXER_LIBS"
|
||||
|
||||
AC_CHECK_LIB([SDL_mixer],
|
||||
[OGG_new],
|
||||
,
|
||||
[AC_MSG_WARN([*** SDL_mixer has no OGG support. You won't have music in the game.])])
|
||||
|
||||
LIBS=$OLD_LIBS
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Configuration options #
|
||||
#######################################################################
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Enable debug in wesnoth],
|
||||
CXXFLAGS="$CXXFLAGS -DDEBUG -ggdb3")
|
||||
|
@ -172,9 +282,27 @@ AC_ARG_ENABLE(tools,
|
|||
[ --enable-tools Enable compilation of translation tools],
|
||||
tools=yes)
|
||||
|
||||
AC_ARG_ENABLE(icons,
|
||||
[ --disable-icons Disable installation of icons and menu entries],
|
||||
icons=$enableval,
|
||||
icons=yes)
|
||||
|
||||
AM_CONDITIONAL(SERVER, test x$server = xyes)
|
||||
AM_CONDITIONAL(EDITOR, test x$editor = xyes)
|
||||
AM_CONDITIONAL(TOOLS, test x$tools = xyes)
|
||||
AM_CONDITIONAL(ICONS, test x$icons = xyes)
|
||||
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Icon and menu handling #
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Data file substitution. #
|
||||
#######################################################################
|
||||
|
||||
MANUAL_FILES=`ls MANUAL*`
|
||||
MANUAL_FILES=`echo $MANUAL_FILES`
|
||||
|
@ -199,7 +327,9 @@ AC_SUBST([MUSIC_FILES])
|
|||
AC_SUBST([SOUND_FILES])
|
||||
AC_SUBST([UTIL_FILES])
|
||||
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
icons/Makefile
|
||||
src/Makefile
|
||||
src/server/Makefile
|
||||
src/tools/Makefile])
|
||||
|
|
|
@ -10,6 +10,45 @@
|
|||
|
||||
{items.cfg}
|
||||
|
||||
{terrain_generator.cfg}
|
||||
|
||||
[game_config]
|
||||
base_income=2
|
||||
village_income=1
|
||||
heal_amount=4
|
||||
healer_heals_per_turn=8
|
||||
cure_amount=8
|
||||
curer_heals_per_turn=18
|
||||
recall_cost=20
|
||||
kill_experience=8
|
||||
|
||||
title="title.png"
|
||||
icon="wesnoth-icon.png"
|
||||
title_music="wesnoth-7.ogg"
|
||||
|
||||
map_image="misc/map.png"
|
||||
sidebar_image="misc/rightside.png"
|
||||
sidebar_image_bottom="misc/rightside-bottom.png"
|
||||
|
||||
moved_energy_image="moved-energy.png"
|
||||
unmoved_energy_image="unmoved-energy.png"
|
||||
partmoved_energy_image="partmoved-energy.png"
|
||||
enemy_energy_image="enemy-energy.png"
|
||||
ally_energy_image="ally-energy.png"
|
||||
|
||||
cross_image="misc/cross.png"
|
||||
dot_image="misc/dot.png"
|
||||
|
||||
footprint_left_nw=misc/foot-left-nw.png
|
||||
footprint_left_n=misc/foot-left-n.png
|
||||
footprint_right_nw=misc/foot-right-nw.png
|
||||
footprint_right_n=misc/foot-right-n.png
|
||||
|
||||
missile_n_image=missile-n.png
|
||||
missile_ne_image=missile-ne.png
|
||||
|
||||
[/game_config]
|
||||
|
||||
[campaign]
|
||||
id=heir_throne
|
||||
name=Heir to the Throne
|
||||
|
@ -356,7 +395,7 @@
|
|||
[movement costs]
|
||||
deep water=100
|
||||
shallow water=3
|
||||
swamp water=3
|
||||
swamp water=2
|
||||
grassland=1
|
||||
sand=2
|
||||
forest=1
|
||||
|
@ -372,7 +411,7 @@
|
|||
[defense]
|
||||
deep water=80
|
||||
shallow water=70
|
||||
swamp water=70
|
||||
swamp water=60
|
||||
grassland=60
|
||||
sand=70
|
||||
forest=30
|
||||
|
@ -395,6 +434,7 @@
|
|||
[/movetype]
|
||||
[movetype]
|
||||
name=woodlandfloat
|
||||
flies=true
|
||||
[movement costs]
|
||||
deep water=2
|
||||
shallow water=1
|
||||
|
@ -438,6 +478,7 @@
|
|||
|
||||
[movetype]
|
||||
name=fly
|
||||
flies=true
|
||||
[movement costs]
|
||||
deep water=1
|
||||
shallow water=1
|
||||
|
@ -610,6 +651,7 @@
|
|||
|
||||
[movetype]
|
||||
name=undeadfly
|
||||
flies=true
|
||||
[movement costs]
|
||||
deep water=1
|
||||
shallow water=1
|
||||
|
@ -654,5 +696,6 @@
|
|||
[/units]
|
||||
|
||||
{tutorial.cfg}
|
||||
{tutorial2.cfg}
|
||||
{scenarios}
|
||||
{scenario-test.cfg}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[story]
|
||||
music=wesnoth-1.ogg
|
||||
[part]
|
||||
id=intro_1
|
||||
story="In the twenty-seventh year of Garard II, king of Wesnoth, the kingdom was plunged into a bitter war with the Northern peoples."
|
||||
|
|
|
@ -1,16 +1,3 @@
|
|||
ggfffffffgggggggggggg
|
||||
ggfffffffgtgggggggggg
|
||||
ggfffffffCggggggggggg
|
||||
ggfffffft1Cgggggggggg
|
||||
ggfffffffCCgggggggggg
|
||||
ggggggggCCCgggggggggg
|
||||
ggggggggC2ggggggggggg
|
||||
ggggggggggggggggggggg
|
||||
ggggggggggggggggggggg
|
||||
ggggSSggggggggggggggg
|
||||
ggggSSSgggggggggggggg
|
||||
ggggSSSgggggggggggggg
|
||||
ggggSSSgggggggggggggg
|
||||
ggggggggggggggggggggg
|
||||
ggggggggggggggggggggg
|
||||
ggggggggggggggggggggg
|
||||
fff1
|
||||
cccc
|
||||
fff2
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
ggggggfffffffffffffggggtgggcs
|
||||
fffffhfffggfftgggrgrffffggggc
|
||||
fffffhfffggfftgggrrrffffggggc
|
||||
ffffffggghggghgrrgfgrrfffgggf
|
||||
ffthgggffggggrrgggfftgrrrggff
|
||||
fffgggfgfggghCgghhgggffgfrggf
|
||||
fffgggffggtCC1gggggffffggrggf
|
||||
ffthgggffggggmrgggfftgrrrggff
|
||||
fffgggfgfggghCrghhgggffgfrggf
|
||||
fffgggffggtCC1rggggffffggrggf
|
||||
fffffgggggggCCCggfffffffggrgg
|
||||
ccccftffffgghhgffffftffcccrgt
|
||||
ccccccggffffggghggggfcccccrrg
|
||||
ssssscgcfffggggfhfgcccsssscrg
|
||||
ssssccctgfffggggggccssgtssccr
|
||||
ccc//cggffffggghggggfcccccrrg
|
||||
csssccgcfffggggfhfgcccsssscrg
|
||||
ssssccptgfffggggggccssgtssccr
|
||||
sssccgggffffffgggggcsssgssccr
|
||||
sssschgggffhhmffggccssshssscr
|
||||
sscccchhhtfmfhhhfgcccsstssscr
|
||||
ccccgthmmmhhhmmfffcsssssssccr
|
||||
tcggggghmmmtmmmhhggcccccsscrg
|
||||
cccccchhhtfmfhhhfgcccsstssscr
|
||||
c/gcgthmmmhhhmmfffccssssssccr
|
||||
tcggggghmmmtmmmhhggcccccsscpg
|
||||
ccsggggfffhhhmmmthgggcgcsccrt
|
||||
gggtggfffhhmmmmhhfffggccccrhh
|
||||
gggggfffhmmmhmmmmmfffgtcc//gf
|
||||
|
@ -21,6 +21,6 @@ chhgggfffmhhhhmmhffffrc//cgtf
|
|||
sccfgfffhhhmmmhhhhffgr/cccgff
|
||||
ccgggggffggfhhfffffrrggccgggf
|
||||
tggggfffgCgfghgrtrrggtgcggfff
|
||||
gggffhhfCC2Chhrfrgggggcctggfh
|
||||
gggffhhfCC2rhhrfrgggggcctggfh
|
||||
ggtggftfhgCCrrrhhffccccsscghm
|
||||
ggggffhhggggggggmmcccssssschm
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
ggggggffggggggggtDvcsssggggggggggggggggggggggggg
|
||||
gggggfffffggggggRRRcsgcggggggggggggggggggggggggg
|
||||
ggvggfggfffgggggRRR\cggggggggggggggggggggggggggg
|
||||
ggggCCgggffggggcRc\Rggggggggtggggggtgggggggggggg
|
||||
ggffC1Cggggggtcc|ccgRRgggggggggggtgggggggggggggg
|
||||
gggfffCffggghhggccggRRgggggggggggggggggggggggggg
|
||||
ggggfffffgghhggccggggRRggggggggCCCgggggggggggggg
|
||||
ccggggggghhggccgggggggRtgggggggC3ggggggggggggggg
|
||||
ccccgcchhgcccggggggggrrrggggggghCggggggggggggggg
|
||||
gvccccctgccggggggggggggrrrgggggtgggggggggggfffff
|
||||
ggggggcccggggvgggggggmggggrggggggggggggggggggggg
|
||||
ggggggffggggggggtDvcsssddggggggggggggggggggggggg
|
||||
gggggfffffggggggRRRcsdcdgggggggggggggggggggggggg
|
||||
ggvggftgfffgggggRRR\cddggggggggggggggggggggggggg
|
||||
ggggCCgggffggggccc\Rggggggggtggggggggggggggggggg
|
||||
ggffC1CggggggtcccccgRRgggggggggggtgggggggggggggg
|
||||
gggfffCffggghhggccggRRgggggggggggggggCgggggggggg
|
||||
ddggfffffgghhgg\cggggRRgggggggggggggg2CCCggggggg
|
||||
ccdgggggghhggccgggggggRtgggggggggggggCCCgggggggg
|
||||
ccccgcchhdcccggggggggrrrggggggghgggggggmgggggggg
|
||||
dvcc|cctgccggggggggggggrrrgggggtggggghghgggfffff
|
||||
ddddggc|cggggvgggggggmggggrggggggggggghhgggggggg
|
||||
gggggggggggggggggggmhhhgggrggggggggggggggggggggg
|
||||
ggggggvgggggggggghghhfgffgrrgvgggggggggggggggggg
|
||||
gggggggggggggggggggffffffhgrggggggtggggggggggggg
|
||||
gggggggggggggggggffffhfghhmrfggggggggggggggggggg
|
||||
gggggggtgggggggggffhfffghgggrrgggggggggggggggggg
|
||||
gggggggggggggggggffhfffghgggrrgggggggggggggggggg
|
||||
ggggggggggggggggggfffffvggggvgrrgggvgggggggggggg
|
||||
ggtgggggggggggggggggfggggggggggrgggggggggggggggg
|
||||
gggggggggggggggggggggggggggggggrggggggCggggggggg
|
||||
ggggggggggDggtgggggggggggggggggrgggggCCCgggggggg
|
||||
ggggggggggggmumugggggggggggggrrvgggggC2ggggggggg
|
||||
gggggggggggguuuuuugggggggggrrgggggggggCCgggggggg
|
||||
ggggggggggmguuDumuugmggggrrggggggggggggggggggggg
|
||||
gggtggggggmmmuuuumummrrrrggggtgggggggggggggggggg
|
||||
ggggggggggguuuugmggrrgggggggggggggggggggggghfggg
|
||||
gmggggggDgggggDgggggggggDcccggggggggvgggggfghggg
|
||||
hhfhhggggggggggggggggggggggcc/ggtgggggggggfhfhff
|
||||
tmmgggggggggghmmgfmggggtggggcgccccggggggtggtffgf
|
||||
hhghhgggggggggfghfgmgfgggggggggcscccggggggffhggg
|
||||
ggtgggggggggggggggggfggcccgggggrgggggggggggggggg
|
||||
gmghggggggggggggggggcccsscgggggrggggggCggggggggg
|
||||
gmmhmhgmmgDhgtggggggccsscggggggrgggggCCCgggggggg
|
||||
gmhmmmhhhhghmumuggggccsccggggrrvgggggC3ggggggggg
|
||||
gcmmmhhmhgghuuuuuuggggcgccgrrgggggggggCCgggggggg
|
||||
cggghghmmgmDuuDumuugmgggg/rggggggggggggggggggggg
|
||||
pvgtggmgghmmmuuuumummrrrrcgggtgggggggggggggggggg
|
||||
ccggggmghhhuuuugmggrrggggcggggggggggggggggghfggg
|
||||
cmggggghDmhgggggggggggggDcccggggggggvgggggfghggg
|
||||
hhfhhghmmmgmgggggggggggggggcc|ggtgggggggggfhfhff
|
||||
tmmggmmmmgmmghmmgfmggggtggggcgccccggggggtggtffgf
|
||||
hhghhgmgggmgggfghfgmgfgggggggggcscccggggggffhggg
|
||||
ggggggggggggggggfgggtggggggggggcsscccgggggfghgfg
|
||||
ggggggtgggggggggmggggggggggggtgccsscgggggggggggg
|
||||
ggggggggggCCgtggggggggggggggggggcccggggggggggggg
|
||||
gggggggggm4CCggggggggggggggggggggggggggggggggggg
|
||||
ggggggggggCggggggggggggtggggggggggggggggtggggggg
|
||||
gggggggggggggggggggggggggggggghgffffgggggggggggg
|
||||
ggggggtggggggggggggggggggggghgffffgghggggggggggg
|
||||
ggggggggggggggggggggggggggggfffmffffghhgggggtggg
|
||||
ggggggggggggggtgggggggggggffffghfggffmfffggggggg
|
||||
ggggggggggggggggggggggggggggfhfggthggggtgggggggg
|
||||
ggggggggggggggggggggggggggfffghhggggggggggtggggg
|
||||
gggggggggggggggggggggggggggggggggggtgggggggggggg
|
||||
ggggggtgggggggggmggggggggggggtgccssccdgdgdgdddgg
|
||||
ggggggggggCCggggggggggggggggggggcccccdggggddddgg
|
||||
gggggggggm4CCgggggggggggggggggggggddcdddggggdddd
|
||||
ggggggggggCggggggggggggggggdgddgggddcddgtggddggg
|
||||
gggggggggggggggggggggggggdgddgdgfffddddggdggdgdd
|
||||
ggggggtggggggggggggdddgddgdgdgddddggdgdgdgdgggdd
|
||||
ggggggggggggggggggddddgdgdggfffmffdfghhggddddggg
|
||||
ggggggggggggggggdgdddddddgffffghfggdfmfffdggdddg
|
||||
ggggggggggggggggggddgdddggddfhfgdthdggggggdddddd
|
||||
ggggggggggggggggggggggggggdffghhggggdggdgggddddg
|
||||
ggggggggggggggggggggggggggggdgdgggdcgggggggddggg
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
ccgggggggggggccSSSfftSSSgggggggtgggggcccggggtfftgg
|
||||
ccgggggggggggccSSfSffSSgggtggggggggggcccgggfffffgg
|
||||
cgggggggggggccccfgSSSgggggggggggggggcggcgggfcfffff
|
||||
ccggggggtgggggcfggggggggggggggtggggtccgcccggcctfff
|
||||
ccccggggggggggCCCggggggggggtgggggggcccccccccgggfff
|
||||
ccctcgggggggggC2Cfggggggggggggggggmmcccccccggggfff
|
||||
ccccccgcggggggCCCffgggtggggggggggmmmmmcctccgggggff
|
||||
ccccccgcctgfgggtgfftggggggggggggmmmmmmmmccggggggff
|
||||
ccccccggccffggggffffccggggggtggggmmmmmmccgggggffff
|
||||
cccggcgggccfffgffffffcggggggggggggmgmmmmggggggffff
|
||||
cccgccccgfffffffffffgtgdgtggggggggggmmgggggmgtffff
|
||||
ccccddcgffffffffffffgSgddggggggggggggmmgggtmmfffff
|
||||
cccddddddfffffffffffSSgddcgmmgtgggggggmmggmmfffftf
|
||||
ccdddftdddfffggggfftggdddccmmgcggggggtggggmfmffffg
|
||||
ccdddfffftfffgggggcggddddcctmcccggggggggdgmmffffgg
|
||||
cdtddfffffffcgggggccggdddcmmmccccgggggggdddmffmmgg
|
||||
dgggggfffddccgggccccgdggccmmmmmmmmmggggddddtffmmgg
|
||||
ddggggffddtgcggccccctgggcccmmmmmgmmgggdddddddggmmg
|
||||
ddggggffgggggggcccccfgggccccmmmmgtmmdddddddgggggmm
|
||||
gdgdggtfgffggfffcccffffggcccmmmmmmmmddddddggggggmg
|
||||
ggdgdggffffgggftffffffffggctmmmmmggmmdddgggggggggg
|
||||
gggdgggfffffggfccfffffffgggmmmmtmgggdddggggggggggg
|
||||
ggdggggfffffgfffcffffdffggccmmmmmggdddddgggggggggg
|
||||
gdgggggffffffgtfffftgddggcccmmmgmddddmmddggggggggg
|
||||
ddggcccfffffffgfgggggggdgccccctggdddddmggggggggggg
|
||||
tdggccccggfffgfggdggggdggcgtccgggggmmmmggggggggggg
|
||||
ddccccccggffffgggdddddggggggcgggggggmmmggggggggggg
|
||||
gcgcggcggggggfgggdgdddggggggggggggggmmgddggggggggg
|
||||
ggtggggggggtgggggggdgggggggggggggggggmdggdgggggggg
|
||||
ccccggcggggggggggggggggggggggggggmmmdddgdddggggggg
|
||||
cccccccgggggggggggggggggggggggggggmmdddggddddddggg
|
||||
cccccgcggggggtgggtggggggggggggggtgmmdddggggddddggg
|
||||
cccccggcgggggggggggggggmgmgggtgggmgddddggggtmddgtg
|
||||
cccccgcccggggggggggggggmtmmmgggggggdddddgmmmmmdggg
|
||||
ccgggccgcggggggggggggggmmmmmggggggggddddhhmmmmmmgh
|
||||
tcggggggggggggggggtgggmmmmmmmgggggggdddhhhmmmmmmhh
|
||||
ccggggtgggggggggggggggggmmmmmmggtggddthhhmmmmmmmhg
|
||||
ggggggggggtggggggggggggmmmmmmggggggggghhhhmgmmghgg
|
||||
ggggggggggggggggggggggmmmtmmmggggggggghhSmgmgmgghh
|
||||
fffgggggggggggggtgggggmmmmmmmmgggggggggSCCCgmmghhh
|
||||
fffgCCChgggffgggggggggmmmmgmmgggggggggggC1Cmgmhhhh
|
||||
ffggC3ChhhgffgggggggggmmmgtggggggggtggggCCCtghhhhh
|
||||
fffhCCChhhhftggggtgggggmgggggggggggggggggSgghhhhhh
|
||||
tffhhhhhhhhhffggggggggggmmmggggtggggggggggghhhhShh
|
||||
fffhhhhhgghffggggggghggtgmmmggggggggggggggghhthSSS
|
||||
fffhhhhggggftgggggghhhggmmmmggggggggggggggghhhggSg
|
||||
ffffhhhgggggfgggghhhggggmmmmgggggggggggggghghhgggg
|
||||
fffffgggggffgggghhhhhghhmggmgmmgggggggggggghghgggg
|
||||
ffffffgggfffgggghhhhhhhhggggmmmgggggggggggghhggggg
|
||||
ffffffffffffgggghhhhhhhggggggmmgggggggggggghgggggg
|
|
@ -143,8 +143,9 @@ Defeat:
|
|||
description=Gwiti Ha'atel
|
||||
message="Die, yes die, and go to the Land of the Dead. Perhaps one day you will be back under my command!"
|
||||
[/message]
|
||||
[endlevel]
|
||||
[endlevel]
|
||||
result=victory
|
||||
bonus=yes
|
||||
[/endlevel]
|
||||
[/event]
|
||||
|
||||
|
@ -200,6 +201,20 @@ Defeat:
|
|||
[/message]
|
||||
[/event]
|
||||
|
||||
|
||||
|
||||
[event]
|
||||
name=turn 9
|
||||
[message]
|
||||
id=msg2_1_16
|
||||
description=Nati Ha'atel
|
||||
message="You miserable wretch, know that it is only by my mercy that you look upon the sun again, for you shall die before it sets again."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_1_17
|
||||
description=Gwiti Ha'atel
|
||||
message="May I remind you that even as we speak, my undead legions are marching towards you?"
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[/scenario]
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ Defeat
|
|||
[message]
|
||||
id=msgcrossroads4
|
||||
description=Kalenz
|
||||
message="Beware! These forests are not safe! Asheviere has hired Orcs to guard these roads, because of their strategic important. We shall have to fight to get by here."
|
||||
message="Beware! These forests are not safe! Asheviere has hired Orcs to guard these roads, because of their strategic importance. We shall have to fight to get by here."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgcrossroads5
|
||||
|
@ -127,7 +127,7 @@ Defeat
|
|||
[/unit]
|
||||
[message]
|
||||
id=msgcrossroads1
|
||||
description=Nioden
|
||||
description=Niodien
|
||||
message="Stay on the path! The forests here are not safe!"
|
||||
[/message]
|
||||
[/event]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
name="The Isle of Anduin"
|
||||
map=map1
|
||||
music=wesnoth-4.ogg
|
||||
music=wesnoth-8.ogg
|
||||
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
|
|
224
data/scenarios/Mages_And_Elves.cfg
Normal file
|
@ -0,0 +1,224 @@
|
|||
[scenario]
|
||||
name="Mages and Elves"
|
||||
id="Mages_And_Elves"
|
||||
map=undmap3
|
||||
turns=40
|
||||
|
||||
|
||||
{DUSK}
|
||||
{FIRST_WATCH}
|
||||
{SECOND_WATCH}
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
{AFTERNOON}
|
||||
|
||||
next_scenario="Crelanus_Book"
|
||||
|
||||
music="wesnoth-2.ogg"
|
||||
|
||||
objectives="
|
||||
Victory:
|
||||
@Move Gwiti to the Tower of Sorcery
|
||||
@Kill both enemy leaders
|
||||
Defeat:
|
||||
#Death of Gwiti Ha'atel
|
||||
#Turns run out"
|
||||
|
||||
|
||||
[side]
|
||||
description=Gwiti Ha'atel
|
||||
type=Dark Apprentice
|
||||
side=1
|
||||
canrecruit=1
|
||||
controller=human
|
||||
recruit= Dark Adept,Ghost,Walking Corpse,Vampire Bat,Skeleton,Skeleton Archer
|
||||
enemy=2,3
|
||||
[/side]
|
||||
|
||||
|
||||
|
||||
[side]
|
||||
type=Great Mage
|
||||
description=Quirind
|
||||
side=2
|
||||
canrecruit=1
|
||||
#ifdef HARD
|
||||
recruit= Great Mage,Arch Mage,Red Mage,White Mage,Paladin
|
||||
|
||||
#ifdef NORMAL
|
||||
recruit= Arch Mage,Red Mage,White Mage,Mage,Knight,Heavy Infantry
|
||||
#endif
|
||||
|
||||
#ifdef EASY
|
||||
recruit= Red Mage,Mage,Horseman,Heavy Infantry
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EASY
|
||||
gold=40
|
||||
#endif
|
||||
|
||||
#ifdef NORMAL
|
||||
gold=65
|
||||
#endif
|
||||
|
||||
#ifdef HARD
|
||||
gold=90
|
||||
#endif
|
||||
|
||||
enemy=1
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
type=Elvish Marshal
|
||||
description=Lessalin
|
||||
side=3
|
||||
canrecruit=1
|
||||
#ifdef HARD
|
||||
recruit= Elvish Hero,Elvish Ranger,Elvish Captain,Elvish Outrider,Gryphon Rider,Elvish Scout,Elvish Druid
|
||||
|
||||
#ifdef NORMAL
|
||||
recruit= Elvish Hero,Elvish Fighter,Gryphon Rider,Elvish Archer,Thief,Elvish Scout,Elvish Shaman
|
||||
#endif
|
||||
|
||||
#ifdef EASY
|
||||
recruit= Elvish Fighter,Elvish Archer,Elvish Scout,Thief,Elvish Shaman
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EASY
|
||||
gold=60
|
||||
#endif
|
||||
|
||||
#ifdef NORMAL
|
||||
gold=90
|
||||
#endif
|
||||
|
||||
#ifdef HARD
|
||||
gold=120
|
||||
#endif
|
||||
|
||||
enemy=1
|
||||
[/side]
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[message]
|
||||
id=msg2_3_1
|
||||
speaker=narrator
|
||||
message="After sending the Dark Spirit away for his failure, Gwiti turned towards the Tower of Kaleon, where the greatest mages once studied."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_2
|
||||
description=Gwiti Ha'atel
|
||||
message="At last, I have reached the main road. Unless I am far off my course, I should find the Tower of Kaleon here, filled with the secrets of ancient mages. Soon they shall all be mine."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_3
|
||||
description=Quirind
|
||||
message="A necromancer! I must send for aid."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_4
|
||||
description=Quirind
|
||||
message="Accursed and dreadful one, know that we mages, guardians of the Tower of Kaleon, shall bar your way with all our spells! Flee now and you may survive."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_5
|
||||
description=Lessalin
|
||||
message="Quirind, know that you have the Elves at your back."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_6
|
||||
description=Lessalin
|
||||
message="Foul sorcerer of death, go far from this place or we shall send you to your own realm."
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_7
|
||||
description=Gwiti Ha'atel
|
||||
message="Not born is the one that could challenge me!"
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[item]
|
||||
x=15
|
||||
y=3
|
||||
image=terrain/dwarven-doors.png
|
||||
[/item]
|
||||
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Gwiti Ha'atel
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg2_3_8
|
||||
speaker=unit
|
||||
message="No! No! Noooo! It is over, I feel the shades reaching for me..."
|
||||
[/message]
|
||||
[endlevel]
|
||||
result=defeat
|
||||
[/endlevel]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Quirind
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg2_3_9
|
||||
speaker=unit
|
||||
message="Argh! I have fallen, and the Tower lies stripped of its defenses!"
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Lessalin
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg2_3_10
|
||||
speaker=unit
|
||||
message="Quirind, we have failed! You must guard the tower."
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
|
||||
[event]
|
||||
|
||||
name=time out
|
||||
[message]
|
||||
id=msg2_3_11
|
||||
description=Quirind
|
||||
message="Ah ha ha ha! The tower's protective spells are now in force, you cannot enter without mastering a magic equal to it."
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
x=15
|
||||
y=3
|
||||
description=Gwiti Ha'atel
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg2_3_12
|
||||
speaker=unit
|
||||
message="Haha! I have gained entry to the tower!"
|
||||
[/message]
|
||||
[message]
|
||||
id=msg2_3_13
|
||||
description=Lessalin
|
||||
message="A curse upon that foul necromancer!"
|
||||
[/message]
|
||||
[endlevel]
|
||||
result=victory
|
||||
bonus=yes
|
||||
[/endlevel]
|
||||
[/event]
|
||||
|
||||
[/scenario]
|
||||
|
|
@ -117,7 +117,7 @@ Defeat:
|
|||
[message]
|
||||
id=msg6_4b
|
||||
description=Li'sar
|
||||
message=Don't tell me such treason. Your lies will perish with you!
|
||||
message=Treason! Your lies will perish with you!
|
||||
[/message]
|
||||
[message]
|
||||
id=msg6_5
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[multiplayer]
|
||||
name=Random map
|
||||
map_data="{ranmap.cfg}"
|
||||
map_generation=default
|
||||
turns=90
|
||||
id=ranmap
|
||||
|
||||
|
@ -23,10 +23,4 @@
|
|||
canrecruit=1
|
||||
controller=human
|
||||
[/side]
|
||||
[side]
|
||||
side=3
|
||||
enemy=1
|
||||
canrecruit=1
|
||||
controller=human
|
||||
[/side]
|
||||
[/multiplayer]
|
||||
|
|
|
@ -203,9 +203,9 @@ Defeat:
|
|||
name=have_thieves
|
||||
value=yes
|
||||
[/set_variable]
|
||||
[can_recruit]
|
||||
[allow_recruit]
|
||||
type=Thief
|
||||
[/can_recruit]
|
||||
[/allow_recruit]
|
||||
[/command]
|
||||
[/option]
|
||||
[option]
|
||||
|
|
|
@ -1,415 +0,0 @@
|
|||
[scenario]
|
||||
name="The Liberation Front"
|
||||
map=LiberationMap
|
||||
turns=28
|
||||
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
{AFTERNOON}
|
||||
{DUSK}
|
||||
{FIRST_WATCH}
|
||||
{SECOND_WATCH}
|
||||
|
||||
id=The_Liberation_Front
|
||||
next_scenario=Undefined
|
||||
|
||||
music="wesnoth-4.ogg"
|
||||
|
||||
[bigmap]
|
||||
image=misc/map.png
|
||||
[dot]
|
||||
type=cross
|
||||
x=187
|
||||
y=187
|
||||
[/dot]
|
||||
[/bigmap]
|
||||
|
||||
objectives="
|
||||
Victory:
|
||||
@Defeat All three Orc Leaders
|
||||
Defeat:
|
||||
#Death of Konrad
|
||||
#Death of Delfador
|
||||
#Death of Kalenz
|
||||
#Death of Li'sar
|
||||
#Time runs out"
|
||||
|
||||
[item]
|
||||
x=14
|
||||
y=3
|
||||
image=terrain/dwarven-doors.png
|
||||
[/item]
|
||||
[item]
|
||||
x=10
|
||||
y=26
|
||||
image=terrain/castle-ruins.png
|
||||
[/item]
|
||||
[item]
|
||||
x=10
|
||||
y=27
|
||||
image=terrain/castle-ruins.png
|
||||
[/item]
|
||||
[item]
|
||||
x=11
|
||||
y=27
|
||||
image=terrain/castle-ruins.png
|
||||
[/item]
|
||||
[item]
|
||||
x=17
|
||||
y=21
|
||||
image=terrain/castle-ruins.png
|
||||
[/item]
|
||||
[item]
|
||||
x=5
|
||||
y=34
|
||||
image=terrain/castle-ruins.png
|
||||
[/item]
|
||||
|
||||
[side]
|
||||
type=Commander
|
||||
description=Konrad
|
||||
side=1
|
||||
canrecruit=1
|
||||
controller=human
|
||||
recruit=Elvish Scout,Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Merman,Thief,Gryphon Rider, Dwarf,
|
||||
enemy=2,3,4
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
type=Orcish Warlord
|
||||
description=Knafa-Telfar
|
||||
side=2
|
||||
canrecruit=1
|
||||
recruit=Orcish Warrior,Wolf Rider,Orcish Crossbow,Orcish Assassin,Troll Warrior
|
||||
#ifdef EASY
|
||||
gold=250
|
||||
#endif
|
||||
#ifdef NORMAL
|
||||
gold=300
|
||||
#endif
|
||||
#ifdef HARD
|
||||
gold=350
|
||||
#endif
|
||||
enemy=1
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
type=Orcish Warlord
|
||||
description=Urug-Tan
|
||||
side=3
|
||||
canrecruit=1
|
||||
#ifdef EASY
|
||||
recruit=Orcish Grunt,Wolf Rider,Orcish Archer,Orcish Assassin,Troll
|
||||
gold=250
|
||||
#endif
|
||||
#ifdef NORMAL
|
||||
recruit=Orcish Grunt,Goblin Knight,Orcish Crossbow,Orcish Assassin,Troll Warrior
|
||||
gold=300
|
||||
#endif
|
||||
#ifdef HARD
|
||||
recruit=Orcish Warrior,Goblin Knight,Orcish Crossbow,Orcish Assassin,Troll Warrior
|
||||
gold=350
|
||||
#endif
|
||||
enemy=1
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
race=Orcs3
|
||||
type=Orcish Warlord
|
||||
description=Shuuga-Mool
|
||||
side=4
|
||||
canrecruit=1
|
||||
recruit=Orcish Warrior,Wolf Rider,Orcish Crossbow,Troll Warrior,Orcish Slayer
|
||||
#ifdef EASY
|
||||
gold=250
|
||||
#endif
|
||||
#ifdef NORMAL
|
||||
gold=300
|
||||
#endif
|
||||
#ifdef HARD
|
||||
gold=350
|
||||
#endif
|
||||
enemy=1
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
race=Orcs3
|
||||
type=Orcish Warlord
|
||||
description=Ba-grah'Nook
|
||||
side=5
|
||||
canrecruit=0
|
||||
[/side]
|
||||
|
||||
[event]
|
||||
name=start
|
||||
[recall]
|
||||
description=Delfador
|
||||
[/recall]
|
||||
[recall]
|
||||
description=Kalenz
|
||||
[/recall]
|
||||
[recall]
|
||||
description=Li'sar
|
||||
[/recall]
|
||||
#move The orcs off their keeps so they don't recruit yet
|
||||
[command]
|
||||
[kill]
|
||||
description=Knafa-Telfar
|
||||
[/kill]
|
||||
[/command]
|
||||
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=29
|
||||
y=22
|
||||
description=Knafa-Telfar
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
|
||||
[command]
|
||||
[kill]
|
||||
description=Urug-Tan
|
||||
[/kill]
|
||||
[/command]
|
||||
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=1
|
||||
y=35
|
||||
description=Urug-Tan
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
[/event]
|
||||
[event]
|
||||
name=turn 1
|
||||
[message]
|
||||
description=Konrad
|
||||
id=msg13_1
|
||||
message="Alright Delfador, now that I have claimed the Scepter of Fire I am going to hold you to your promise."
|
||||
[/message]
|
||||
[message]
|
||||
description=Delfador
|
||||
id=msg13_2
|
||||
message="Which one?"
|
||||
[/message]
|
||||
[message]
|
||||
description=Konrad
|
||||
id=13_3
|
||||
message="That we free these lands from the scourge of the orcs!"
|
||||
[/message]
|
||||
[message]
|
||||
description=Delfador
|
||||
id=msg13_4
|
||||
message="Very well Konrad. But the orcs must have contacted Asheviere about our trip into the mines, and I doubt she will trust them to take care of the job. So make haste, and dispatch these beasts quickly, lest reinforcements arrive."
|
||||
[/message]
|
||||
[message]
|
||||
description=Shuuga-Mool
|
||||
message="The human and his friends have returned! I will deal with them myself!"
|
||||
id=msg13_5
|
||||
[/message]
|
||||
[message]
|
||||
speaker=Knafa-Telfar
|
||||
id=msg13_6
|
||||
message="If your sure boss..."
|
||||
[/message]
|
||||
[message]
|
||||
description=Shuuga-Mool
|
||||
id=msg13_7
|
||||
message="COURSE I'm sure worm! Do as your told!"
|
||||
[/message]
|
||||
[message]
|
||||
speaker=Knafa-Telfar
|
||||
id=msg13_8
|
||||
message="Alright, alright! Sorry boss!"
|
||||
[/message]
|
||||
[/event]
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Shuuga-Mool
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg13_9
|
||||
description=Knafa-Telfar
|
||||
message="They killed the boss!"
|
||||
[/message]
|
||||
[message]
|
||||
id=msg13_10
|
||||
description=Urug-Tan
|
||||
message="I knew you should've helped him!"
|
||||
[/message]
|
||||
[message]
|
||||
id=msg13_11
|
||||
description=Knafa-Telfar
|
||||
message="So this is my fault!?! Nevermind! Let's just kill them!"
|
||||
[/message]
|
||||
[command]
|
||||
[kill]
|
||||
description=Knafa-Telfar
|
||||
[/kill]
|
||||
[/command]
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=29
|
||||
y=21
|
||||
description=Knafa-Telfar
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
[command]
|
||||
[kill]
|
||||
description=Urug-Tan
|
||||
[/kill]
|
||||
[/command]
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=1
|
||||
y=35
|
||||
description=Urug-Tan
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
|
||||
[/event]
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
x=27-29
|
||||
y=19-23
|
||||
[/filter]
|
||||
[command]
|
||||
[kill]
|
||||
description=Knafa-Telfar
|
||||
[/kill]
|
||||
[/command]
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=29
|
||||
y=21
|
||||
description=Knafa-Telfar
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
[message]
|
||||
description=Knafa-Telfar
|
||||
id=msg13_15
|
||||
message="They're attacking me boss! I gotta defend myself!"
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
x=1-3
|
||||
y=33-37
|
||||
[/filter]
|
||||
[command]
|
||||
[kill]
|
||||
description=Urug-Tan
|
||||
[/kill]
|
||||
[/command]
|
||||
[command]
|
||||
[unit]
|
||||
side=2
|
||||
x=29
|
||||
y=21
|
||||
description=Urug-Tan
|
||||
type=Orcish Warlord
|
||||
canrecruit=1
|
||||
[/unit]
|
||||
[/command]
|
||||
[message]
|
||||
description=Urug-Tan
|
||||
id=msg13_16
|
||||
message="They're attacking me boss! I gotta defend myself!"
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=turn 18
|
||||
[unit]
|
||||
description=Ba-grah'Nook
|
||||
type=Orcish Warlord
|
||||
canrecruit=0
|
||||
x=20
|
||||
y=44
|
||||
side=5
|
||||
[/unit]
|
||||
[unit]
|
||||
description=Grungy
|
||||
type=Troll Warrior
|
||||
x=20
|
||||
y=45
|
||||
side=5
|
||||
[/unit]
|
||||
[unit]
|
||||
description=Stupid
|
||||
type=Troll
|
||||
x=19
|
||||
y=45
|
||||
side=5
|
||||
[/unit]
|
||||
[unit]
|
||||
description=Ugly
|
||||
type=Troll
|
||||
x=21
|
||||
y=45
|
||||
side=5
|
||||
[/unit]
|
||||
[unit]
|
||||
description=Gorba
|
||||
type=Orcish Slayer
|
||||
x=19
|
||||
y=44
|
||||
side=5
|
||||
[/unit]
|
||||
[unit]
|
||||
description=Bogar
|
||||
type=Orcish Slayer
|
||||
x=21
|
||||
y=44
|
||||
side=5
|
||||
[/unit]
|
||||
[message]
|
||||
description=Ba-grah'Nook
|
||||
id=msg13_12
|
||||
message="Hail! We've come in response to your message, the Queen has given us specific orders to help you deal with these humans once and for all. We're the vanguard that's been sent out from an entire army that's been ordered to deal with these miscreants!"
|
||||
[/message]
|
||||
[message]
|
||||
description=Delfador
|
||||
id=msg13_13
|
||||
message="This is a bad turn of events! We must finish them quickly and flee! We are not capable of dealing with an entire army dedicated to wiping us out in our current condition!"
|
||||
[/message]
|
||||
[/event]
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Knafa-Telfar
|
||||
description=Urug-Tan
|
||||
[/filter]
|
||||
[message]
|
||||
description=Delfador
|
||||
id=msg13_14
|
||||
message="We've slain our opposition! Now let us make haste!"
|
||||
[/message]
|
||||
[endlevel]
|
||||
result=victory
|
||||
bonus=yes
|
||||
[/endlevel]
|
||||
[/event]
|
||||
|
||||
{deaths.cfg}
|
||||
|
||||
[/scenario]
|
|
@ -12,7 +12,7 @@
|
|||
{DAWN}
|
||||
|
||||
id="Skull_Agarash"
|
||||
next_scenario=null
|
||||
next_scenario="Mages_And_Elves"
|
||||
|
||||
music="wesnoth-3.ogg"
|
||||
|
||||
|
@ -58,13 +58,13 @@ Defeat:
|
|||
canrecruit=1
|
||||
recruit=Orcish Grunt,Wolf Rider,Orcish Archer,Troll Whelp
|
||||
#ifdef HARD
|
||||
gold=180
|
||||
gold=135
|
||||
#endif
|
||||
#ifdef MEDIUM
|
||||
gold=120
|
||||
gold=90
|
||||
#endif
|
||||
#ifdef EASY
|
||||
gold=80
|
||||
gold=60
|
||||
#endif
|
||||
enemy=1,4
|
||||
[/side]
|
||||
|
@ -78,13 +78,13 @@ Defeat:
|
|||
canrecruit=1
|
||||
recruit=Orcish Grunt,Wolf Rider,Orcish Archer,Troll Whelp
|
||||
#ifdef HARD
|
||||
gold=180
|
||||
gold=135
|
||||
#endif
|
||||
#ifdef MEDIUM
|
||||
gold=120
|
||||
gold=90
|
||||
#endif
|
||||
#ifdef EASY
|
||||
gold=80
|
||||
gold=60
|
||||
#endif
|
||||
enemy=1,3
|
||||
[/side]
|
||||
|
@ -96,15 +96,15 @@ Defeat:
|
|||
[message]
|
||||
id=und2_2_1
|
||||
speaker=narrator
|
||||
message="After Gwiti destroyed his brother, he was planning a march upon Wesnoth. But a Dark Spirit came to him, counselling him..."
|
||||
message="After Gwiti destroyed his brother, a Dark Spirit came to him, counselling him..."
|
||||
[/message]
|
||||
[/command]
|
||||
|
||||
[command]
|
||||
[move_unit_fake]
|
||||
type=Wraith
|
||||
x=1,2,3,4,5,6,7
|
||||
y=4,4,4,4,4,4,4
|
||||
x=1,2,3,4,5,6,7,7
|
||||
y=4,4,4,4,4,4,4,5
|
||||
[/move_unit_fake]
|
||||
[/command]
|
||||
|
||||
|
@ -122,7 +122,7 @@ Defeat:
|
|||
[message]
|
||||
id=und2_2_2
|
||||
description=Dark Spirit
|
||||
message="Gwiti... Gwiti!"
|
||||
message="Gwitiii... Gwiti!"
|
||||
[/message]
|
||||
[message]
|
||||
id=und2_2_3
|
||||
|
@ -132,7 +132,7 @@ Defeat:
|
|||
[message]
|
||||
id=und2_2_4
|
||||
description=Dark Spirit
|
||||
message="Gwiti, do not yet march upon Wesnoth. First, you shall go south, against the orcs, and there find the Skull of Agarash."
|
||||
message="Gwiti, do not yet march in pursuit of your war. First, you shall go south, against the orcs, and there find the Skull of Agarash."
|
||||
[/message]
|
||||
[message]
|
||||
id=und2_2_5
|
||||
|
@ -184,8 +184,9 @@ Defeat:
|
|||
description=Gwiti Ha'atel
|
||||
message="Argh! This is only half of the skull!"
|
||||
[/message]
|
||||
[endlevel]
|
||||
result=victory
|
||||
[endlevel]
|
||||
result=victory
|
||||
bonus=yes
|
||||
[/endlevel]
|
||||
[/event]
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ image=ocean
|
|||
name=deep water
|
||||
char=s
|
||||
blue=150
|
||||
submerge=0.5
|
||||
unit_height_adjust=-3
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -10,12 +12,16 @@ image=coast
|
|||
name=shallow water
|
||||
char=c
|
||||
blue=250
|
||||
submerge=0.4
|
||||
unit_height_adjust=-4
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
image=swampwater,swampwater2,swampwater3
|
||||
name=swamp water
|
||||
char=w
|
||||
submerge=0.4
|
||||
unit_height_adjust=-3
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
@ -168,6 +174,15 @@ char=C
|
|||
red=100
|
||||
green=100
|
||||
blue=100
|
||||
unit_height_adjust=3
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
image=keep
|
||||
name=keep
|
||||
char=K
|
||||
unit_height_adjust=8
|
||||
aliasof=C
|
||||
[/terrain]
|
||||
|
||||
[terrain]
|
||||
|
|
164
data/terrain_generator.cfg
Normal file
|
@ -0,0 +1,164 @@
|
|||
[map_generator]
|
||||
name=default
|
||||
width=40
|
||||
height=40
|
||||
iterations=1000
|
||||
hill_size=10
|
||||
max_lakes=40
|
||||
villages=300
|
||||
players=2
|
||||
min_lake_height=500
|
||||
lake_size=150
|
||||
river_frequency=20
|
||||
|
||||
temperature_iterations=40
|
||||
temperature_size=50
|
||||
|
||||
default_flatland=g
|
||||
|
||||
roads=3
|
||||
road_windiness=3
|
||||
|
||||
#list of common terrain types which come in at
|
||||
#different heights, from highest to lowest
|
||||
[height]
|
||||
height=700
|
||||
terrain=m
|
||||
[/height]
|
||||
[height]
|
||||
height=600
|
||||
terrain=h
|
||||
[/height]
|
||||
[height]
|
||||
height=40
|
||||
terrain=g
|
||||
[/height]
|
||||
[height]
|
||||
height=30
|
||||
terrain=d
|
||||
[/height]
|
||||
[height]
|
||||
height=5
|
||||
terrain=c
|
||||
[/height]
|
||||
[height]
|
||||
height=0
|
||||
terrain=s
|
||||
[/height]
|
||||
|
||||
#at low temperatures, and at reasonable height,
|
||||
#snow appears
|
||||
[flatland]
|
||||
max_temperature=200
|
||||
min_height=400
|
||||
terrain=S
|
||||
[/flatland]
|
||||
|
||||
#swamp appears on low land, at moderate temperatures
|
||||
[flatland]
|
||||
min_temperature=500
|
||||
max_temperature=700
|
||||
max_height=200
|
||||
terrain=w
|
||||
[/flatland]
|
||||
|
||||
#forest appears at moderate temperatures
|
||||
[flatland]
|
||||
min_temperature=300
|
||||
max_temperature=600
|
||||
terrain=f
|
||||
[/flatland]
|
||||
|
||||
#desert appears at high temperatures
|
||||
[flatland]
|
||||
min_temperature=900
|
||||
terrain=d
|
||||
[/flatland]
|
||||
|
||||
#road costs
|
||||
[road_cost]
|
||||
terrain=g
|
||||
cost=1
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=d
|
||||
cost=2
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=f
|
||||
cost=3
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=c
|
||||
cost=5
|
||||
convert_to_bridge=|,/,\
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=h
|
||||
cost=5
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=m
|
||||
cost=10
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
[road_cost]
|
||||
terrain=r
|
||||
cost=0
|
||||
convert_to=r
|
||||
[/road_cost]
|
||||
|
||||
#road going through snow is covered over by
|
||||
#the snow (presumably the road was built when
|
||||
#it wasn't snowing)
|
||||
[road_cost]
|
||||
terrain=S
|
||||
cost=2
|
||||
convert_to=S
|
||||
[/road_cost]
|
||||
|
||||
[village]
|
||||
terrain=g
|
||||
convert_to=v
|
||||
[/village]
|
||||
[village]
|
||||
terrain=d
|
||||
convert_to=v
|
||||
[/village]
|
||||
|
||||
#villages in forest are Elvish
|
||||
[village]
|
||||
terrain=f
|
||||
convert_to=t
|
||||
[/village]
|
||||
[village]
|
||||
terrain=h
|
||||
convert_to=v
|
||||
[/village]
|
||||
[village]
|
||||
terrain=m
|
||||
convert_to=v
|
||||
[/village]
|
||||
|
||||
#villages in snow
|
||||
[village]
|
||||
terrain=S
|
||||
convert_to=V
|
||||
[/village]
|
||||
|
||||
[castle]
|
||||
valid_terrain=g,f,h
|
||||
min_distance=16
|
||||
[/castle]
|
||||
|
||||
[/map_generator]
|
|
@ -1,42 +1,41 @@
|
|||
[language]
|
||||
language="Nederlands"
|
||||
id=nl #language code - English=en, French=fr, etc
|
||||
13_3="That we free these lands from the scourge of the orcs!"
|
||||
A_Choice_Must_Be_Made="A Choice Must Be Made"
|
||||
A_Choice_Must_Be_Made="Staan voor een keuze"
|
||||
A_Choice_Must_Be_Made_objectives="
|
||||
Victory:
|
||||
@Defeat either of the enemy leaders
|
||||
Defeat
|
||||
Overwinning:
|
||||
@Versla een van de leiders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador"
|
||||
AncientLich="Ancient Lich"
|
||||
AncientLich_description="The final form that a mage of the undead can achieve, the Ancient Lich strikes terror into the hearts of those who see him. Not only is his touch that of death, but his spells are powerful enough to freeze even the bravest where they stand."
|
||||
ArchMage="Arch Mage"
|
||||
ArchMage_description="A leader among the mages, the arch mage hurls huge balls of fire at his enemies. The arch mage can teleport from any village to any other friendly village, translating himself from place to place in an instant."
|
||||
Assassin="Assassin"
|
||||
Assassin_description="Assassins are masters of the night. Like rogues they can backstab, and ignore enemy zones of control. They can also throw poison-tipped knives at their enemies from long range."
|
||||
Blackwater_Port="Blackwater Port"
|
||||
AncientLich="Oude Lich"
|
||||
AncientLich_description="Het hoogste wat een magiër van de ondoden kan bereiken. De Oude Lich brengt een koude angst in de harten van die die hem zien. Niet alleen is zijn aanraking er een van dood, zijn spreuken zijn krachtig genoeg om zelfs de dapperste mannen aan de grond te nagelen."
|
||||
ArchMage="Oppermagiër"
|
||||
ArchMage_description="De Oppermagiër is een leider onder de magiërs. Hij kan enorme vuurballen naar de vijand gooien. De Oppermagiër kan zichzelf teleporteren van elk dorp naar elk andere bevriende dorp, zich zelf in een ogenblik van plaats naar plaats bewegend."
|
||||
Assassin="Sluipmoordenaar"
|
||||
Assassin_description="Sluipmoordenaars zijn de meesters van de nacht. Net als rogues beheersen ze de ruggesteek en worden ze niet tegengehouden door vijandige zones. Sluipmoordenaars gooien messen met een giftige punt van een grote afstand op hun vijand."
|
||||
Blackwater_Port="Zwartwater Haven"
|
||||
Blackwater_Port_objectives="
|
||||
Victory:
|
||||
@Defeat enemy leader
|
||||
@Resist until the end of the turns
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla vijandige leider
|
||||
@Houdt stand tot de laatste beurt
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Seimus"
|
||||
BloodBat="Blood Bat"
|
||||
BloodBat_description="The fur of this undead flying beast is tainted red by the blood of its victims. The Blood Bat is fast, and can drain the blood of those it attacks, thus healing itself. Through its draining, it can even end up stronger than it began the battle!"
|
||||
BoneShooter="Bone Shooter"
|
||||
BoneShooter_description="These undead elite archers use the bones of those slain in battle not only to kill their foes, but also to strike terror in their hearts."
|
||||
Brother_Against_Brother="Brother Against Brother"
|
||||
BloodBat="Bloedvleermuis"
|
||||
BloodBat_description="De vacht van dit ondode vliegende beest zit onder het rode bloed van zijn slachtoffers. De Bloedvleermuis is snel en kan het bloed opzuigen van degene die het aanvalt en zichzelf daarmee genezen. Het kan er zelfs sterker dan aan het begin van de strijd door worden!"
|
||||
BoneShooter="Beender Schieter"
|
||||
BoneShooter_description="Deze ondode elite boogschutters gebruiken de botten van zij die vielen als pijlen. Niet alleen dood zoiets, maar slaat de angst ook om het hart."
|
||||
Brother_Against_Brother="Broer tegen broer"
|
||||
Brother_Against_Brother_objectives="
|
||||
Victory:
|
||||
@Defeat your brother Nati Ha'atel
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla je broer Nati Ha'atel
|
||||
Verslagen:
|
||||
#Dood van Gwiti Ha'atel
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
Cavalry="Cavelarie"
|
||||
Cavalry_description="The best riders in Wesnoth are recruited into the military to become members of the cavalry. This strictly disciplined force is especially suited to capturing and holding villages."
|
||||
Cavalry_description="De beste rijders in Wesnoth worden gerecruteerd voor het leger om bij de cavalerie te komen. Deze gedisciplineerde eenheid is vooral geschikt voor de verovering en het vasthouden van dorpen."
|
||||
Chocobone="Chocobone"
|
||||
Chocobone_description="Riding the bones of large birds used as mounts by an ancient and lost civilization, the skeletons can move faster than most calvary units."
|
||||
Commander="Commander"
|
||||
|
@ -141,9 +140,9 @@ swiftly fly towards their victims."
|
|||
GryphonRider_description="Only a few of the already nature-loving elves are able to make a friendship bond with the mighty gryphons. Those who do can ride these flying beasts, discovering the whole new world of the skies."
|
||||
Gryphon_Mountain="Gryphon Mountain"
|
||||
Gryphon_Mountain_objectives="
|
||||
Victory:
|
||||
@Defeat the mother gryphon and the enemy commander
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla the mother gryphon and the enemy commander
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
|
@ -153,9 +152,9 @@ Defeat:
|
|||
Halbardier_description="The best among the soldiers are choosen to become halberdiers. Thought a little slower then the sword, their weapon can strike deadly blows."
|
||||
Hasty_Alliance="Hasty Alliance"
|
||||
Hasty_Alliance_objectives="
|
||||
Victory:
|
||||
@Defeat enemy leader
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla vijandige leider
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz
|
||||
|
@ -183,23 +182,23 @@ For this reason, the mage is an excellent choice for flushing out enemies hiding
|
|||
When a unit is adjacent to a mage of Light, it will fight as if it were day when it is dusk, and as if it were dusk when it is night. Like the White Mage, the Mage of Light also cures adjacent friendly units."
|
||||
Merman="Merman"
|
||||
MermanLord="Merman Lord"
|
||||
MermanLord_description="The Merman Lord is a master of the sea, skilled in use of the trident, the Merman Lord easily defeats any enemy who is foolish enough to wander into his preferred environment."
|
||||
MermanLord_description="The Merman Lord is a master of the sea, skilled in use of the trident, the Merman Lord easily Verslagens any enemy who is foolish enough to wander into his preferred environment."
|
||||
Merman_description="A skilled creature of the sea, the Merman is powerful and quick in any amphibious environment, but struggles on land."
|
||||
Mountain_Pass="Mountain Pass"
|
||||
Mountain_Pass_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Move Konrad to the end of the road
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
Muff_Malals_Peninsula="Muff Malal's Peninsula"
|
||||
Muff_Malals_Peninsula_objectives="
|
||||
Victory:
|
||||
@Defeat Muff Malal
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla Muff Malal
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
NORMAL="Held (normaal)"
|
||||
Naga="Naga"
|
||||
Naga_description="The naga, like the merman, are inhabitants of the seas. While they are smaller and nimbler than their counterparts, they share their distaste for dry land."
|
||||
|
@ -207,13 +206,13 @@ Defeat:
|
|||
Necromancer_description="A necromancer is a mage that decided to follow the paths of the dark arts. By tapping into the power of the undead, the necromancer can cast spells that drain the lifeforce from his foes and add it to his own."
|
||||
Northern_Winter="Northern Winter"
|
||||
Northern_Winter_objectives="
|
||||
Victory:
|
||||
@Defeat enemy leaders
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla vijandige leiders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
Ogre="Ogre"
|
||||
Ogre_description="Ogres are giant, stupid humanoids that usually live alone in the wilderness. While they can be easily outran or outsmarted, their strenght is not to be underestimated."
|
||||
OrcishArcher="Orcish Archer"
|
||||
|
@ -236,9 +235,9 @@ Defeat:
|
|||
Pikeman_description="Pikemen are are more experienced soldiers that change their spears for long pikes. Pikemen can be deadly when fighting calvary."
|
||||
Plunging_into_the_Darkness="Plunging into the Darkness"
|
||||
Plunging_into_the_Darkness_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Find the Dwarves
|
||||
Defeat
|
||||
Verslagen
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
|
@ -254,9 +253,9 @@ Defeat
|
|||
RoyalGuard_description="Members of the Royal Guard are hand picked from the strongest and sturdiest of the army. They are deployed only in critical situations and, so far, they have always succeeded in the job at hand."
|
||||
Sceptre="The Sceptre of Fire"
|
||||
Sceptre_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Capture the Sceptre of Fire with Konrad or Li'sar
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz
|
||||
|
@ -277,18 +276,18 @@ Defeat:
|
|||
Skeleton_description="A warrior, slain in battle and brought back by dark magics. All undead are weak to fire and holy spells, but resistant against bladed weapons."
|
||||
Skull_Agarash="The Skull of Agarash"
|
||||
Skull_Agarash_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Take the Skull of Agarash
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Gwiti Ha'atel
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
SleepingGryphon="Sleeping Gryphon"
|
||||
SleepingGryphon_description="Shhhh! The gryphon is sleeping! You'd better not wake it up!"
|
||||
Snow_Plains="Snow Plains"
|
||||
Snow_Plains_objectives="
|
||||
Victory:
|
||||
@Defeat enemy leader
|
||||
Defeat
|
||||
Overwinning:
|
||||
@Versla vijandige leider
|
||||
Verslagen
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador"
|
||||
Soldier="Soldier"
|
||||
|
@ -297,57 +296,57 @@ Defeat
|
|||
Spearman_description="The spearman is the base of the human armies. These young soldiers are given basic training and put in the front lines to face the bulk of the battle."
|
||||
Swamp_Of_Dread="Swamp Of Dread"
|
||||
Swamp_Of_Dread_objectives="
|
||||
Victory:
|
||||
@Defeat all enemy leaders
|
||||
Defeat
|
||||
Overwinning:
|
||||
@Versla all vijandige leiders
|
||||
Verslagen
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador"
|
||||
Swordsman="Swordsman"
|
||||
Swordsman_description="The swordsman is the base of the human armies. These young soldiers are given basic training and put in the front lines to face the bulk of the battle."
|
||||
The_Bay_of_Pearls="The Bay of Pearls"
|
||||
The_Bay_of_Pearls_objectives="
|
||||
Victory:
|
||||
@Defeat both enemy leaders
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla both vijandige leiders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
The_Dwarven_Doors="The Dwarven Doors"
|
||||
The_Dwarven_Doors_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Move Konrad to entrance of the Dwarven Kingdom.
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
The_Elves_Besieged="The Elves Besieged"
|
||||
The_Elves_Besieged_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Move Konrad to the signpost in the north-west
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
The_Ford_of_Abez="The Ford of Abez"
|
||||
The_Ford_of_Abez_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Move Konrad to the North side of the river.
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
The_Isle_of_Anduin="The Isle of Anduin"
|
||||
The_Isle_of_Anduin_objectives="
|
||||
Victory:
|
||||
@Defeat enemy leader
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla vijandige leider
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
The_Liberation_Front="The Liberation Front"
|
||||
The_Liberation_Front_objectives="
|
||||
Victory:
|
||||
@Defeat All three Orc Leaders
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla All three Orc Leaders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz
|
||||
|
@ -355,33 +354,33 @@ Defeat:
|
|||
#Time runs out"
|
||||
The_Lost_General="The Lost General"
|
||||
The_Lost_General_objectives="
|
||||
Victory:
|
||||
@Defeat all enemy leaders
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla all vijandige leiders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
The_Princess_of_Wesnoth="The Princess of Wesnoth"
|
||||
The_Princess_of_Wesnoth_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Force Li'sar's surrender
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
The_Siege_of_Elensefar="The Siege of Elensefar"
|
||||
The_Siege_of_Elensefar_objectives="
|
||||
Victory:
|
||||
@Defeat both enemy leaders
|
||||
Defeat:
|
||||
Overwinning:
|
||||
@Versla both vijandige leiders
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Turns run out"
|
||||
#Geen beurten meer"
|
||||
The_Valley_of_Death-The_Princesss_Revenge="The Valley of Death - The Princess's Revenge"
|
||||
The_Valley_of_Death-The_Princesss_Revenge_objectives="
|
||||
Victory:
|
||||
Overwinning:
|
||||
@Survive for two days
|
||||
Defeat:
|
||||
Verslagen:
|
||||
#Dood van Konrad
|
||||
#Dood van Delfador
|
||||
#Dood van Kalenz"
|
||||
|
@ -488,8 +487,8 @@ The white mage is potent in battle against the undead, which experience high dam
|
|||
create_new_game="Creeer spel"
|
||||
date_format="%a %b %d %H:%M %Y"
|
||||
deep water="Diep Water"
|
||||
defeat_heading="Verlies"
|
||||
defeat_message="Je hebt verloren!"
|
||||
Verslagen_heading="Verlies"
|
||||
Verslagen_message="Je hebt verloren!"
|
||||
defense="Verdediging"
|
||||
describe_unit="Omschrijving"
|
||||
difficulty_level="Selecteer moeilijkheidsgraad:"
|
||||
|
@ -498,7 +497,7 @@ The white mage is potent in battle against the undead, which experience high dam
|
|||
early_finish_bonus="vroege finish bonus"
|
||||
elves="Elven"
|
||||
end_game_heading="Einde"
|
||||
# end_game_message="You have reached the end of the currently playable levels"
|
||||
end_game_message="Er zijn geen scenario's meer in deze campagne"
|
||||
end_turn="Eind Beurt"
|
||||
error_no_campaigns="Er zijn geen campagnes beschikbaar"
|
||||
fifty_percent="80% van het goud wordt behouden in het volgende scenario"
|
||||
|
@ -580,12 +579,12 @@ The white mage is potent in battle against the undead, which experience high dam
|
|||
mountains="Bergen"
|
||||
movement="Verplaatsing"
|
||||
moves="Bereik"
|
||||
# msg10_10="If this is true, Konrad, perhaps we should take another route and go around the mountain, rather then to try and defeat these new foes."
|
||||
# msg10_10="If this is true, Konrad, perhaps we should take another route and go around the mountain, rather then to try and Verslagen these new foes."
|
||||
# msg10_11="What say you, Delfador?"
|
||||
# msg10_12="No! We do not have the time to waste, we make for top of the pass, beware of mountain trolls, and do not stray too close to the water!"
|
||||
# msg10_13="The shinsplitters will aid you in your quest, look, they arise from the villages to the east, the mighty shinsplitters!!! To battle!"
|
||||
# msg10_2="Look Konrad, before us lies the great road built by the dwarves!"
|
||||
# msg10_20="Well, we have defeated our foes let us hope the mountain does not defeat us!"
|
||||
# msg10_20="Well, we have Verslagened our foes let us hope the mountain does not Verslagen us!"
|
||||
# msg10_21="I wish you all the best on your journey, I must return to my village and take care of my family, dwarven hospitality will welcome you, wherever you go friends!"
|
||||
# msg10_22="Let us move onward!"
|
||||
# msg10_3a="But, I can hardly see, with all this mist around!"
|
||||
|
@ -674,50 +673,49 @@ The white mage is potent in battle against the undead, which experience high dam
|
|||
msg1_10="Laat ze maar komen. We bestrijden ze met alles wat we hebben."
|
||||
msg1_11="Wees voorzichtig, Konrad! Zorg goed voor hem, Delfador!"
|
||||
msg1_12="En zo het begon..."
|
||||
# msg1_13="Okay, we have made it this far! But where do we go next?"
|
||||
# msg1_14="We must travel north, and try to make it to the Isle of Anduin. Hopefully there we will find refuge."
|
||||
# msg1_15="Of course you are right, Delfador. But what will become of the Elves here?"
|
||||
# msg1_16="The Elves will fight. They may even prevail. But I fear things do not bode well for them. Let us not speak of it now. Onward!"
|
||||
# msg1_17="Good luck Konrad! Don't worry about us, we will fight as best we can!"
|
||||
# msg1_18="I....I don't think I can make it anymore"
|
||||
# msg1_19="Prince...you must keep fighting! Nooooooo!"
|
||||
msg1_13="Goed, we hebben het gehaald! Maar waar gaan we nu naar toe?"
|
||||
msg1_14="We reizen naar het zuiden en proberen naar het eiland van Anduin te komen. Hopelijk vinden we daar een onderkomen"
|
||||
msg1_15="Natuurlijk heb je gelijk, Delfador. Maar wat zal er met de Elven hier gebeuren?"
|
||||
msg1_16="De Elven zullen doorvechten. Ze zullen het misschien zelfs overleven. Maar het ziet er niet goed uit voor hen. Laat ons daar nu niet over spreken. Voorwaarts!"
|
||||
msg1_17="Succes, Konrad! Maak je geen zorgen over ons. We vechten zo goed we kunnen!"
|
||||
msg1_18="Ik....ik haal het niet meer"
|
||||
msg1_19="Prins...Je moet blijven vechten! Neeeee!"
|
||||
msg1_2="Meester Delfador! Kijk, Orks komen van alle richtingen! Wat moeten we doen?"
|
||||
# msg1_20="It is over, I am doomed...."
|
||||
# msg1_21="I have....have failed in my duty to protect the prince, I am defeated"
|
||||
# msg1_22="Don't die! Delfador! Please, you have to stay alive!"
|
||||
# msg1_23="Ugh"
|
||||
# msg1_24="Oh no! We have run out of time, they have arrived with reinforcements..."
|
||||
# msg1_25="Die villain, die!"
|
||||
# msg1_26="Only the foolish oppose me!"
|
||||
# msg1_27="I am Galdrad. You will have to fight me to get any further!"
|
||||
# msg1_28="Only a fool would dare to attack me!"
|
||||
# msg1_28a="I am Delfador the Great, prepare to die!"
|
||||
# msg1_29="Let me through you rogue!"
|
||||
msg1_20="Het is over, ik ben verloren...."
|
||||
msg1_21="Ik heb.... heb gefaald in mijn plicht om de prins te beschermen. Ik ben verslagen"
|
||||
msg1_22="Blijf leven! Delfador! Alstublieft, U mag niet dood!"
|
||||
msg1_23="Ugh"
|
||||
msg1_24="Oh nee! We zijn te langzaam geweest. Er komen versterkingen aan bij de Orks...."
|
||||
msg1_25="Sterf, schurk, sterf!"
|
||||
msg1_26="Alleen de dommen houden me tegen!"
|
||||
msg1_27="Ik ben Galdrad. Je moet eerst mij verslaan, voor je verder kan!"
|
||||
msg1_28="Alleen een gek durft het aan mij aan te vallen!"
|
||||
msg1_28a="Ik ben Delfador the Grote, wees klaar om te sterven!"
|
||||
msg1_29="Laat me door, etter!"
|
||||
msg1_3="Er zijn er teveel om te bevechten. We moeten ontsnappen!"
|
||||
# msg1_30="They are destroying our home!"
|
||||
# msg1_31="There can be no looking back. We must go quickly!"
|
||||
msg1_30="Ze vernietigen ons huis!"
|
||||
msg1_31="Kijk niet terug! We moeten door en snel!"
|
||||
msg1_4="Maar waar naar toe? Dit is ons enige huis! En wat gebeurt er met de Elven?"
|
||||
msg1_5="We zullen met hen strijden, maar jij moet weg, Konrad. Het is van groot belang dat jij ontsnapt!"
|
||||
msg1_6="We gaan naar het noorden. Misschien kunnen we het eiland van Anduin bereiken. Als we dat halen, dan zullen we zeker veilig zijn. Konrad, we moeten wat Elven inhuren om ons te helpen en dan moet je naar de wegwijzer in het noord-westen. Ik zal je beschermen!"
|
||||
msg1_5="We zullen tegen hen strijden, maar jij moet weg, Konrad. Het is van groot belang dat jij ontsnapt!"
|
||||
msg1_6="We gaan naar het zuiden. Misschien kunnen we het eiland van Anduin bereiken. Als we dat halen, dan zullen we zeker veilig zijn. Konrad, we moeten wat Elven inhuren om ons te helpen en dan moet je naar de wegwijzer in het noord-westen. Ik zal je beschermen!"
|
||||
msg1_7="Da's goed, laten we opschieten!"
|
||||
msg1_8="Val de Elven aan, bezet hun dorpen, laten we dit land claimen voor de Koningin!"
|
||||
msg1_9="Haha! We snijden die vieze Elven aan stukjes!"
|
||||
# msg1b_1="We should be able to board a ship at Blackwater Port, but it seems the Orcs are heading there too. One of my old apprentices has settled in these lands - I am sure he will help us!"
|
||||
# msg1b_10="I could offer you a ship - I sent it to the open sea with the elder and the children, but it should arrive back in port soon."
|
||||
# msg1b_11="Thank you, sir."
|
||||
# msg1b_11b="I only hope that we will do as well the next time the evil Orcs attack us."
|
||||
# msg1b_12="We should embark now."
|
||||
# msg1b_13="I failed to the Blackwater port people...."
|
||||
# msg1b_14="Without his help, we will be unable to use the ships, there is no hope..."
|
||||
# msg1b_2="Defaldor, some Orcs are following our trail! We must make haste!"
|
||||
# msg1b_3="Delfaldor, my old master, your arrival bring us the light of hope.
|
||||
We heard the news that the orcs were attacking the elvish woods and some of them where headed here to attack us also, but our defenses are still weak."
|
||||
# msg1b_4="We will help you fight them off."
|
||||
# msg1b_5a="I shall send one of my mages to aid you. Recruit more mages, and perhaps some horsemen, who have fought very well for us against the crown. I need a few days to summon aid."
|
||||
# msg1b_6="The defenses are now summoned."
|
||||
# msg1b_7="Geeee!! Too many mages, we had better retreat now!"
|
||||
# msg1b_8="Thank you for the help, friends."
|
||||
# msg1b_9="We are seeking transport to the isle of Anduin."
|
||||
msg1_9="Haha! We snijden die vieze Elven aan stukjes!"
|
||||
msg1b_1="Het zou mogelijk moeten zijn om aan boord van een schip te komen in de Zwartwater haven, maar het lijkt er op dat de Orks ook deze kant op komen. Een van mijn oude leerlingen heeft zich hier gevestigd - Ik weet zeker dat hij ons wil helpen."
|
||||
msg1b_10="Ik can u een schip aanbieden - ik heb het naar de open zee gestuurd met de ouderen en de kinderen, maar het zal snel weer terug zijn."
|
||||
msg1b_11="Dank U, meneer."
|
||||
msg1b_11b="Ik hoop alleen dat we het de volgende keer ook zo goed doen, als die vuile Orks ons weer aanvallen."
|
||||
msg1b_12="We moeten nu aan boord."
|
||||
msg1b_13="Ik heb gefaald voor de mensen van de Zwartwater haven...."
|
||||
msg1b_14="Zonder zijn hulp, kunnen de schepen niet krijgen. Er is geen hoop..."
|
||||
msg1b_2="Defaldor, sommige Orks volgen ons spoor! We moeten opschieten!"
|
||||
msg1b_3="Delfaldor, my oude meester, Uw komst brengt ons het licht van hoop. We hoorden dat de Orks in het Elvenbos aanvielen en dat sommige ook hier naar toe kwamen om ons aan te vallen. Onze verdediging is alleen nog zwak."
|
||||
msg1b_4="We zullen je helpen hen te bevechten."
|
||||
msg1b_5a="Ik zal een van mijn magiër sturen om jullie te helpen. Huur meer magiërs in, en misschien wat paardrijders, die voor ons zeer goed tegen de troon hebben gevochten. Ik zal een paar dagen nodig hebben om hulp te regelen."
|
||||
msg1b_6="The defenses are now summoned."
|
||||
msg1b_7="Waaaah!! Veel te veel magiërs, we moeten terugtrekken!"
|
||||
msg1b_8="Dank voor de hulp, vrienden."
|
||||
msg1b_9="We zoeken transport naar het eiland van Anduin."
|
||||
# msg2_1="And so the party landed on the Isle of Anduin..."
|
||||
# msg2_10="Have you not heard? Many mermen have been captured, and are being farmed as pearl harvesters at the Bay of Pearls. If only someone would rescue them!"
|
||||
# msg2_11="Let us go and rescue them then!"
|
||||
|
@ -736,7 +734,7 @@ We heard the news that the orcs were attacking the elvish woods and some of them
|
|||
# msg3_10="But...but...how can this be happening to me?"
|
||||
# msg3_11="Who was that idiot?"
|
||||
# msg3_12="Free at last! Now death to the Orcs!"
|
||||
# msg3_13="Now that we are free, together we can defeat our oppressors!"
|
||||
# msg3_13="Now that we are free, together we can Verslagen our oppressors!"
|
||||
# msg3_13a="Death to the orcs! Come, let us all fight them men!"
|
||||
# msg3_14="Freedom! Now where are those Orcs? Let me at em!"
|
||||
# msg3_15="Thank you for rescuing us! Now we can help you fight the evil Orcs!
|
||||
|
@ -767,14 +765,14 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg4_1="But the road to Elensefar was a treacherous one. Konrad and his men were set upon by the fiends of the undead."
|
||||
# msg4_10="Surprise! Searching for Mages, all I get is elves!"
|
||||
# msg4_11="The temple seems to be empty."
|
||||
# msg4_12a="It has been an honor to have helped you defeat the undead, my lord. I must now return to my home. I feel that our paths may cross again one day, perhaps when your need against the undead hordes is greater still."
|
||||
# msg4_12a="It has been an honor to have helped you Verslagen the undead, my lord. I must now return to my home. I feel that our paths may cross again one day, perhaps when your need against the undead hordes is greater still."
|
||||
# msg4_2="My lord! In yonder ruins there seems to be some movement!"
|
||||
# msg4_3="It looks like there are the undead there! Prepare for battle men!"
|
||||
# msg4_4="To arms!"
|
||||
# msg4_5="Ahh, a party of Elves approaches. Soon we shall have Elven zombies serving us!"
|
||||
# msg4_6="There are some ancient temples to the north-west, I wonder what might be inside them!"
|
||||
# msg4_7="Looks like there is somebody hidden in the temple."
|
||||
# msg4_8="I was hiding in this holy place planning how to defeat the evil undeads, now I with your help, we can destroy them."
|
||||
# msg4_8="I was hiding in this holy place planning how to Verslagen the evil undeads, now I with your help, we can destroy them."
|
||||
# msg4_9="Looks like there is somebody hidden in the temple."
|
||||
# msg4_moredie="Fight on against the undead without me, friends!"
|
||||
# msg5_1="The party arrived at Elensefar at last, but found that the city had already fallen to the evil Orcs."
|
||||
|
@ -824,7 +822,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg6_22="You get paid to kill them, so go!"
|
||||
# msg6_23="Somebody! Kill these intruders, now!"
|
||||
# msg6_24="Uggh will kill the slims!"
|
||||
# msg6_25="Ogres! I need more ogres to defeat them!"
|
||||
# msg6_25="Ogres! I need more ogres to Verslagen them!"
|
||||
# msg6_26="Surely an ogre will crush them!"
|
||||
# msg6_27="I surrender! Don't hurt me, imposter."
|
||||
# msg6_28="I said before I'm not an imposter, but if you yield, I will spare your life."
|
||||
|
@ -837,8 +835,8 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg6_34="Good day, princess. Come men, to the northern road!"
|
||||
# msg6_35="(hehe, little do they know just how many undead have wandered the northern road of late. Surely they are doomed!)"
|
||||
# msg6_36="No! It can't end like this!"
|
||||
# msg6_37="Argh! I have been defeated!"
|
||||
# msg6_38="With Kalenz slain, it is hopeless. We are defeated."
|
||||
# msg6_37="Argh! I have been Verslagened!"
|
||||
# msg6_38="With Kalenz slain, it is hopeless. We are Verslagened."
|
||||
# msg6_4="I'm no imposter, it seems that your mother has lied to you about it."
|
||||
# msg6_5="It's no use reasoning. There is only one thing she will understand. To arms!"
|
||||
# msg6_6="This is taking too much time, I best call some reinforcements!"
|
||||
|
@ -873,7 +871,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg8_5b="Well, let's start climbing that mountain!"
|
||||
# msg8_5c="It appears we are not the only ones who are interested in this mountain. Once again the Queen opposes us!"
|
||||
# msg8_5d="Quickly men! Onward!"
|
||||
# msg8_6="We have defeated them! Now what do we do?"
|
||||
# msg8_6="We have Verslagened them! Now what do we do?"
|
||||
# msg8_7="We must continue north. It is too late to return to the safety of Elensefar or Anduin before winter befalls us. Thus we must cross the great river and continue toward the land of the Dwarves. Come let us go!"
|
||||
# msg8_8="With these gryphon eggs we should be able to breed gryphons that will serve us. That will let us hire gryphon riders!"
|
||||
# msg8_9b="Let us continue onward!"
|
||||
|
@ -891,7 +889,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg9_2="Really? So what happened, Delfador?"
|
||||
# msg9_20a="Not her again! Quick, we must make haste!"
|
||||
# msg9_3="The forces of the king were encamped here. The forces of the north were camped on the north side of the river. For three days and three nights the armies faced each other, neither one willing to ford the river. On the fourth day, the northern armies crossed the river, and attacked us."
|
||||
# msg9_4b="And then....we were defeated?"
|
||||
# msg9_4b="And then....we were Verslagened?"
|
||||
# msg9_5="We were winning the battle. We were repelling them."
|
||||
# msg9_6="Until the king's son, in the heat of battle, until he turned on the king!"
|
||||
# msg9_7b="But you avenged the murder. You killed the prince, right Delfador?"
|
||||
|
@ -905,10 +903,10 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msg9_a6="They have made it away! I cannot believe it! We must make chase after them over the river! We will meet again, foul imposter!"
|
||||
# msg9_a7="Do you think she's really going to chase us Delfador?"
|
||||
# msg9_a8="It surely looks like she will try, but the sea creatures will make it difficult for her. We must continue onward. If she makes it across before winter, then so be it!"
|
||||
# msg_delfador_die="No! This is the end! We have been defeated!"
|
||||
# msg_delfador_die="No! This is the end! We have been Verslagened!"
|
||||
# msg_doors_lisar="Whew! We make our way through the dangerous fog of the mountains, and now there is all this chaos before us! Come on men! We must make it into the mines, for they are still ahead of us!"
|
||||
# msg_kalenz_die="Argh! I am finished with!"
|
||||
# msg_konrad_die="We are vanquished, for I have been defeated!"
|
||||
# msg_konrad_die="We are vanquished, for I have been Verslagened!"
|
||||
# msg_lisar_die="I can't believe it should end like this!"
|
||||
# msgcrossroads1="Stay on the path!"
|
||||
# msgcrossroads2="Stay out of the forrest!"
|
||||
|
@ -926,7 +924,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# msgsnowplains2="This sword may prove useful on our journy ahead. It must be in one of the towns before us."
|
||||
# msgswamp1="This land is cursed. The Lichen have lived here for years amassing great armies and fortunes."
|
||||
# msgswamp2="The Lichen are all over this swamp. I hope I have made a wise choice to come down this path."
|
||||
# msgswamp3="Each of the Lichen leaders will have a pile of gold you can take, if they are defeated. Don't stretch you armies to thin though, we still must pass threw this swamp to the north."
|
||||
# msgswamp3="Each of the Lichen leaders will have a pile of gold you can take, if they are Verslagened. Don't stretch you armies to thin though, we still must pass threw this swamp to the north."
|
||||
multiplayer1="The Isle of Anduin"
|
||||
multiplayer2="The Three Rivers"
|
||||
multiplayer3="The Valley of Death"
|
||||
|
@ -980,7 +978,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
remote_host="Kies een connectie"
|
||||
rename_unit="Hernoem manschap"
|
||||
replay_game_message="Laat een herhaling zien tot het punt van opslaan?"
|
||||
retained_gold="Overgebleven goud ....Retaining"
|
||||
retained_gold="Behouden goud"
|
||||
road="Weg"
|
||||
sand="Zand"
|
||||
save_confirm_message="Het spel is opgeslagen"
|
||||
|
@ -1034,7 +1032,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
tut10="Ja, precies! Het is ook belangrijk om dorpen, die van mij zijn, af te pakken"
|
||||
tut11="Goed mannen, naar de dorpen dan!"
|
||||
tut12="Welke type manschappen moet ik inhuren, Delfador?"
|
||||
tut13="Je moet goed naar hun vaardigheden kijken. Eerst wil je snelle manschappen, die voor je zo veel mogelijk dorpen veroveren. Daarna maken waarschijnlijk de elf-soldaten het grootste gedeelte van je leger uit. Denk er aan dat elven heel goed vechten in het bos. Paardrijders zijn prima op open grond. Magiërs zijn een goede ondersteuning en kunnen bijna hetzelfde worden ingezet als boogmannen. Als magiërs meer ervaren worden, dan worden ze erg machtig."
|
||||
tut13="Je moet goed naar hun vaardigheden kijken. Eerst wil je snelle manschappen, die voor je zo veel mogelijk dorpen veroveren. Daarna maken waarschijnlijk de elf-soldaten het grootste gedeelte van je leger uit. Denk er aan dat elven heel goed vechten in het bos. Paardrijders zijn prima op open grond. Magiërs zijn een goede ondersteuning en kunnen bijna hetzelfde worden ingezet als boogschutters. Als magiërs meer ervaren worden, dan worden ze erg machtig."
|
||||
tut14="Als je een vijand aanvalt, dan kan je kiezen welk wapen je wil gebruiken. Je kan dan de kans bekijken op raken en geraakt worden en hoeveel schade dat doet."
|
||||
tut15="Leuk geprobeert, Konrad, maar er moet nog wel wat verbeterd worden."
|
||||
tut16="Je hebt me verslagen, Konrad. Gefeliciteerd met je vechtkunst. Je bent geslaagd voor deze test."
|
||||
|
@ -1048,7 +1046,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
tut9="Dus het is belangrijk om de controle over veel dorpen te krijgen, zodat ik veel geld krijg om veel soldaten in te huren?"
|
||||
tutorial_button="Oefeningen"
|
||||
# und1_1="As the sun set over a land far removed from the war that was happening in Wesnoth, a new war was brewing, between brothers..."
|
||||
# und1_10="I... have failed to win this battle, I am defeated. I will not believe it."
|
||||
# und1_10="I... have failed to win this battle, I am Verslagened. I will not believe it."
|
||||
# und1_11="Die, yes die, and go to the Land of the Dead. Perhaps one day you will be back under my command!"
|
||||
# und1_12="Didn't I tell you so?!"
|
||||
# und1_13="And by my own hands you died!"
|
||||
|
@ -1135,7 +1133,7 @@ The main cage where they keep most of the mermen is in the south-east!"
|
|||
# weapon_special_charge="charge"
|
||||
weapon_special_drain="uitzuiging"
|
||||
weapon_special_magical="magisch"
|
||||
# weapon_special_marksman="specialist/vakman"
|
||||
# weapon_special_marksman="boogschutter"
|
||||
weapon_special_plague="plaag"
|
||||
weapon_special_poison="gif"
|
||||
weapon_special_slow="traag"
|
||||
|
|
|
@ -122,7 +122,7 @@ choose_campaign="Choose the campaign you want to play:"
|
|||
|
||||
difficulty_level="Select difficulty level:"
|
||||
EASY="Fighter (easy)"
|
||||
NORMAL="Hero (medium)"
|
||||
NORMAL="*Hero (medium)"
|
||||
HARD="Champion (hard)"
|
||||
|
||||
no_leader_to_recruit="You don't have a leader to recruit with."
|
||||
|
@ -194,6 +194,7 @@ create_new_game="Create Game"
|
|||
name_of_game="Name of game"
|
||||
map_to_play="Map to play"
|
||||
village_gold="Village Gold"
|
||||
turns="Turns"
|
||||
|
||||
login="Login"
|
||||
must_login="You must log in to this server"
|
||||
|
@ -204,6 +205,7 @@ advance_unit_heading="Advance Unit"
|
|||
advance_unit_message="What should our victorious unit become?"
|
||||
version_save_message="This save is from a different version of the game. Do you want to try to load it?"
|
||||
bad_save_message="The file you have tried to load is corrupt"
|
||||
not_multiplayer_save_message="This is not a multiplayer save"
|
||||
no_saves_heading="No Saved Games"
|
||||
no_saves_message="There are no saved games to load.
|
||||
(Games are saved automatically when you complete a scenario)"
|
||||
|
@ -235,12 +237,15 @@ upkeep="Upkeep"
|
|||
income="Income"
|
||||
|
||||
name="Name"
|
||||
type="Type"
|
||||
hp="HP"
|
||||
xp="XP"
|
||||
moves="Moves"
|
||||
location="Location"
|
||||
level="level"
|
||||
|
||||
message="Message"
|
||||
speak="Speak"
|
||||
describe_unit="Describe Unit"
|
||||
rename_unit="Rename Unit"
|
||||
scenario_objectives="Scenario Objectives"
|
||||
|
|
1167
data/translations/norwegian.cfg
Normal file
|
@ -4,6 +4,8 @@
|
|||
turns=28
|
||||
|
||||
id=tutorial
|
||||
next_scenario=tutorial2
|
||||
music=wesnoth-4.ogg
|
||||
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
|
@ -25,7 +27,7 @@ Defeat:
|
|||
experience=0
|
||||
side=1
|
||||
canrecruit=1
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Scout
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Scout, Elvish Shaman
|
||||
facing=reverse
|
||||
enemy=2
|
||||
gold=200
|
||||
|
@ -39,7 +41,7 @@ Defeat:
|
|||
experience=0
|
||||
side=2
|
||||
canrecruit=1
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Elvish Shaman
|
||||
gold=60
|
||||
enemy=1
|
||||
[/side]
|
||||
|
|
183
data/tutorial2.cfg
Normal file
|
@ -0,0 +1,183 @@
|
|||
[tutorial]
|
||||
name=The Elven Training Grounds (part II)
|
||||
map=map-tutorial
|
||||
turns=28
|
||||
|
||||
id=tutorial2
|
||||
next_scenario=null
|
||||
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
{AFTERNOON}
|
||||
{DUSK}
|
||||
{FIRST_WATCH}
|
||||
{SECOND_WATCH}
|
||||
|
||||
objectives="Victory:
|
||||
@Defeat Delfador
|
||||
Defeat:
|
||||
#Death of Konrad
|
||||
#Turns run out"
|
||||
|
||||
[side]
|
||||
race=Elves
|
||||
type=Fighter
|
||||
description=Konrad
|
||||
experience=0
|
||||
side=1
|
||||
canrecruit=1
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Scout,Elvish Shaman
|
||||
facing=reverse
|
||||
enemy=2
|
||||
controller=human
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
type=Elder Mage
|
||||
description=Delfador
|
||||
experience=0
|
||||
side=2
|
||||
canrecruit=1
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Elvish Shaman
|
||||
gold=70
|
||||
enemy=1
|
||||
[/side]
|
||||
|
||||
[event]
|
||||
name=start
|
||||
[message]
|
||||
id=tut2_1
|
||||
description=Delfador
|
||||
message="Now, we have swapped places. I'm going to teach you about recall."
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_2
|
||||
description=Korad
|
||||
message="Recall?"
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_3
|
||||
description=Delfador
|
||||
message="Soldiers that have fighted for you in past battles and survived could be called again to serve you."
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_4
|
||||
description=Konrad
|
||||
message="Ahhh, I see so I can have more experienced soldiers at my side."
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_5
|
||||
description=Delfador
|
||||
message="Yes, that's the point."
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=turn 3
|
||||
[command]
|
||||
[message]
|
||||
id=tut2_6
|
||||
description=Delfador
|
||||
message="I will recall some experienced friends of mine too."
|
||||
[/message]
|
||||
|
||||
[/command]
|
||||
[command]
|
||||
[unit]
|
||||
description=Lumonieth
|
||||
type=Elvish Captain
|
||||
side=2
|
||||
x=11
|
||||
y=18
|
||||
facing=reverse
|
||||
[/unit]
|
||||
[/command]
|
||||
[command]
|
||||
[message]
|
||||
id=tut2_7
|
||||
description=Lumonieth
|
||||
message="Greetings, Konrad!"
|
||||
[/message]
|
||||
[message]
|
||||
id=tut2_8
|
||||
description=Delfador
|
||||
message="Experienced units are more powerfull and usually have special skills too."
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_9
|
||||
description=Konrad
|
||||
message="Hi, Lumonieth, special skills?"
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_10
|
||||
description=Lumonieth
|
||||
message="I was trained to lead troops, I can make all soldiers around me fight better."
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_11
|
||||
description=Delfador
|
||||
message="XXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
[/message]
|
||||
|
||||
[/command]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=turn 3
|
||||
[message]
|
||||
id=tut2_12
|
||||
description=Konrad
|
||||
message=""
|
||||
[/message]
|
||||
|
||||
[message]
|
||||
id=tut2_13
|
||||
description=Delfador
|
||||
message=""
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=attack
|
||||
[filter]
|
||||
side=2
|
||||
[/filter]
|
||||
[message]
|
||||
id=tut2_14
|
||||
description=Delfador
|
||||
message=""
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Konrad
|
||||
[/filter]
|
||||
[message]
|
||||
id=tut2_15
|
||||
description=Delfador
|
||||
message="A nice try, Konrad, but it seems your skills have much to be improved still."
|
||||
[/message]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=die
|
||||
[filter]
|
||||
description=Delfador
|
||||
[/filter]
|
||||
[message]
|
||||
id=tut2_16
|
||||
description=Delfador
|
||||
message="You have bested me, Konrad. Congratulations on your skill. You have passed the second training test."
|
||||
[/message]
|
||||
[/event]
|
||||
[/tutorial]
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
name=Ancient Lich
|
||||
race=undead
|
||||
image=undead-ancient-lich.png
|
||||
image_defensive=ancient-lich-defend.png
|
||||
hitpoints=80
|
||||
movement_type=undeadfoot
|
||||
movement=6
|
||||
|
@ -17,9 +18,14 @@ get_hit_sound=groan.wav
|
|||
name=touch
|
||||
type=cold
|
||||
range=short
|
||||
damage=10
|
||||
damage=9
|
||||
number=4
|
||||
special=drain
|
||||
[frame]
|
||||
begin=-100
|
||||
end=100
|
||||
image=undead-ancient-lich-attack.png
|
||||
[/frame]
|
||||
[/attack]
|
||||
[attack]
|
||||
name=magic
|
||||
|
@ -28,6 +34,11 @@ get_hit_sound=groan.wav
|
|||
range=long
|
||||
damage=15
|
||||
number=5
|
||||
[frame]
|
||||
begin=-250
|
||||
end=0
|
||||
image=undead-ancient-lich-attack.png
|
||||
[/frame]
|
||||
[missile_frame]
|
||||
begin=-200
|
||||
end=0
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
name=Arch Mage
|
||||
race=human
|
||||
image=arch-mage.png
|
||||
image_defensive=arch-mage-defend.png
|
||||
hitpoints=58
|
||||
movement_type=smallfoot
|
||||
[resistance]
|
||||
|
@ -31,10 +32,23 @@ get_hit_sound=groan.wav
|
|||
special=magical
|
||||
damage=12
|
||||
number=4
|
||||
[missile_frame]
|
||||
[sound]
|
||||
time=-200
|
||||
sound=fire.wav
|
||||
[/sound]
|
||||
[frame]
|
||||
begin=-250
|
||||
end=-100
|
||||
image=arch-mage-attack2.png
|
||||
[/frame]
|
||||
[frame]
|
||||
begin=-100
|
||||
end=0
|
||||
image=arch-mage.png
|
||||
[/frame]
|
||||
|
||||
[/missile_frame]
|
||||
[missile_frame]
|
||||
begin=-100
|
||||
end=0
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
[unit]
|
||||
name=Dark Adept
|
||||
race=undead
|
||||
race=human
|
||||
image=undead-adept.png
|
||||
image_defensive=undead-adept-defend.png
|
||||
hitpoints=28
|
||||
movement_type=undeadfoot
|
||||
movement_type=smallfoot
|
||||
movement=5
|
||||
experience=48
|
||||
level=1
|
||||
|
|
|
@ -35,5 +35,11 @@ get_hit_sound=groan.wav
|
|||
range=long
|
||||
damage=6
|
||||
number=2
|
||||
[missile_frame]
|
||||
begin=-100
|
||||
end=0
|
||||
image=missiledagger-n.png
|
||||
image_diagonal=missiledagger-ne.png
|
||||
[/missile_frame]
|
||||
[/attack]
|
||||
[/unit]
|
||||
|
|
|
@ -46,6 +46,21 @@ get_hit_sound=groan.wav
|
|||
range=long
|
||||
damage=4
|
||||
number=2
|
||||
[sound]
|
||||
time=-100
|
||||
sound=firearrow.wav
|
||||
[/sound]
|
||||
[sound]
|
||||
time=0
|
||||
sound=arrow-hit.wav
|
||||
sound_miss=arrow-miss.wav
|
||||
[/sound]
|
||||
[missile_frame]
|
||||
begin=-100
|
||||
end=0
|
||||
image=missile-n.png
|
||||
image_diagonal=missile-ne.png
|
||||
[/missile_frame]
|
||||
[/attack]
|
||||
[/unit]
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
[unit]
|
||||
name=Necromancer
|
||||
race=undead
|
||||
race=human
|
||||
image=undead-necromancer.png
|
||||
image_defensive=undead-necromancer-defend.png
|
||||
hitpoints=58
|
||||
movement_type=undeadfoot
|
||||
movement_type=smallfoot
|
||||
movement=5
|
||||
experience=48
|
||||
level=2
|
||||
|
|
|
@ -28,5 +28,11 @@ get_hit_sound=groan.wav
|
|||
damage=5
|
||||
number=4
|
||||
special=poison
|
||||
[missile_frame]
|
||||
begin=-100
|
||||
end=0
|
||||
image=missiledagger-n.png
|
||||
image_diagonal=missiledagger-ne.png
|
||||
[/missile_frame]
|
||||
[/attack]
|
||||
[/unit]
|
||||
|
|
|
@ -11,7 +11,7 @@ alignment=chaotic
|
|||
advanceto=Rogue
|
||||
cost=12
|
||||
usage=fighter
|
||||
unit_description="Thieves are deft of foot, and elusive, making them diffult to hit. Being skilled at backstabbing, thieves do double damage when attacking an enemy that has an ally of the thief on the opposite side of him. Being of chaotic disposition, thieves fight better at night than at day."
|
||||
unit_description="Thieves are deft of foot, and elusive, making them difficult to hit. Being skilled at backstabbing, thieves do double damage when attacking an enemy that has an ally of the thief on the opposite side of him. Being of chaotic disposition, thieves fight better at night than at day."
|
||||
get_hit_sound=groan.wav
|
||||
[attack]
|
||||
name=dagger
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
name=Walking Corpse
|
||||
race=undead
|
||||
image=undead-zombie.png
|
||||
image_defensive==undead-zombie-attack.png
|
||||
hitpoints=16
|
||||
movement_type=undeadfoot
|
||||
movement=4
|
||||
|
|
|
@ -11,7 +11,7 @@ alignment=chaotic
|
|||
advanceto=Goblin Knight,Goblin Pillager
|
||||
cost=17
|
||||
usage=scout
|
||||
unit_desc="Being smaller and weaker than the orcs, the goblins train large wolfs to mount and use as fast scouts for the goblinoid army. Having being raised in the orcs dark caverns, the wolfs and their riders can even brave the mountains, unlike most other mounted units."
|
||||
unit_description="Being smaller and weaker than the orcs, the goblins train large wolfs to mount and use as fast scouts for the goblinoid army. Having being raised in the orcs dark caverns, the wolfs and their riders can even brave the mountains, unlike most other mounted units."
|
||||
get_hit_sound=groan.wav
|
||||
[attack]
|
||||
name=fangs
|
||||
|
|
17
icons/Makefile.am
Normal file
|
@ -0,0 +1,17 @@
|
|||
appicondir = $(datadir)/icons
|
||||
appicon_DATA = ../images/wesnoth-icon.png
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
dist_desktop_DATA = wesnoth.desktop
|
||||
|
||||
if GNOME1
|
||||
gnome1desktopdir = @GNOME1_DESKTOP@
|
||||
gnome1desktop_DATA = $(dist_desktop_DATA)
|
||||
endif
|
||||
|
||||
if KDE
|
||||
kdedesktopdir = @KDE_DESKTOP@
|
||||
kdedesktop_DATA = $(dist_desktop_DATA)
|
||||
kdeicondir = @KDE_ICON@
|
||||
kdeicon_DATA = $(appicon_DATA)
|
||||
endif
|
395
icons/Makefile.in
Normal file
|
@ -0,0 +1,395 @@
|
|||
# Makefile.in generated by automake 1.7.8 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIR = @DATADIR@
|
||||
DATA_FILES = @DATA_FILES@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EDITOR_FALSE = @EDITOR_FALSE@
|
||||
EDITOR_TRUE = @EDITOR_TRUE@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FONT_FILES = @FONT_FILES@
|
||||
GNOME1_DESKTOP = @GNOME1_DESKTOP@
|
||||
GNOME1_FALSE = @GNOME1_FALSE@
|
||||
GNOME1_TRUE = @GNOME1_TRUE@
|
||||
GNOME_CONFIG = @GNOME_CONFIG@
|
||||
IMAGE_FILES = @IMAGE_FILES@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
KDE_CONFIG = @KDE_CONFIG@
|
||||
KDE_DESKTOP = @KDE_DESKTOP@
|
||||
KDE_FALSE = @KDE_FALSE@
|
||||
KDE_ICON = @KDE_ICON@
|
||||
KDE_TRUE = @KDE_TRUE@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANUAL_FILES = @MANUAL_FILES@
|
||||
MUSIC_FILES = @MUSIC_FILES@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
SDL_CFLAGS = @SDL_CFLAGS@
|
||||
SDL_CONFIG = @SDL_CONFIG@
|
||||
SDL_IMAGE_LIBS = @SDL_IMAGE_LIBS@
|
||||
SDL_LIBS = @SDL_LIBS@
|
||||
SDL_MIXER_LIBS = @SDL_MIXER_LIBS@
|
||||
SDL_NET_LIBS = @SDL_NET_LIBS@
|
||||
SDL_TTF_LIBS = @SDL_TTF_LIBS@
|
||||
SERVER_FALSE = @SERVER_FALSE@
|
||||
SERVER_TRUE = @SERVER_TRUE@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SOUND_FILES = @SOUND_FILES@
|
||||
STRIP = @STRIP@
|
||||
TOOLS_FALSE = @TOOLS_FALSE@
|
||||
TOOLS_TRUE = @TOOLS_TRUE@
|
||||
UTIL_FILES = @UTIL_FILES@
|
||||
VERSION = @VERSION@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
bindir = @bindir@
|
||||
build_alias = @build_alias@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host_alias = @host_alias@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
appicondir = $(datadir)/icons
|
||||
appicon_DATA = ../images/wesnoth-icon.png
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
dist_desktop_DATA = wesnoth.desktop
|
||||
|
||||
@GNOME1_TRUE@gnome1desktopdir = @GNOME1_DESKTOP@
|
||||
@GNOME1_TRUE@gnome1desktop_DATA = $(dist_desktop_DATA)
|
||||
|
||||
@KDE_TRUE@kdedesktopdir = @KDE_DESKTOP@
|
||||
@KDE_TRUE@kdedesktop_DATA = $(dist_desktop_DATA)
|
||||
@KDE_TRUE@kdeicondir = @KDE_ICON@
|
||||
@KDE_TRUE@kdeicon_DATA = $(appicon_DATA)
|
||||
subdir = icons
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_SOURCES =
|
||||
DATA = $(appicon_DATA) $(dist_desktop_DATA) $(gnome1desktop_DATA) \
|
||||
$(kdedesktop_DATA) $(kdeicon_DATA)
|
||||
|
||||
DIST_COMMON = $(dist_desktop_DATA) $(srcdir)/Makefile.in Makefile.am
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu icons/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
uninstall-info-am:
|
||||
appiconDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-appiconDATA: $(appicon_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(appicondir)
|
||||
@list='$(appicon_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(appiconDATA_INSTALL) $$d$$p $(DESTDIR)$(appicondir)/$$f"; \
|
||||
$(appiconDATA_INSTALL) $$d$$p $(DESTDIR)$(appicondir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-appiconDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(appicon_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(appicondir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(appicondir)/$$f; \
|
||||
done
|
||||
dist_desktopDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-dist_desktopDATA: $(dist_desktop_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(desktopdir)
|
||||
@list='$(dist_desktop_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(dist_desktopDATA_INSTALL) $$d$$p $(DESTDIR)$(desktopdir)/$$f"; \
|
||||
$(dist_desktopDATA_INSTALL) $$d$$p $(DESTDIR)$(desktopdir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-dist_desktopDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(dist_desktop_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(desktopdir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(desktopdir)/$$f; \
|
||||
done
|
||||
gnome1desktopDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-gnome1desktopDATA: $(gnome1desktop_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(gnome1desktopdir)
|
||||
@list='$(gnome1desktop_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(gnome1desktopDATA_INSTALL) $$d$$p $(DESTDIR)$(gnome1desktopdir)/$$f"; \
|
||||
$(gnome1desktopDATA_INSTALL) $$d$$p $(DESTDIR)$(gnome1desktopdir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-gnome1desktopDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(gnome1desktop_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(gnome1desktopdir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(gnome1desktopdir)/$$f; \
|
||||
done
|
||||
kdedesktopDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-kdedesktopDATA: $(kdedesktop_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(kdedesktopdir)
|
||||
@list='$(kdedesktop_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(kdedesktopDATA_INSTALL) $$d$$p $(DESTDIR)$(kdedesktopdir)/$$f"; \
|
||||
$(kdedesktopDATA_INSTALL) $$d$$p $(DESTDIR)$(kdedesktopdir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-kdedesktopDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(kdedesktop_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(kdedesktopdir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(kdedesktopdir)/$$f; \
|
||||
done
|
||||
kdeiconDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-kdeiconDATA: $(kdeicon_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(kdeicondir)
|
||||
@list='$(kdeicon_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(kdeiconDATA_INSTALL) $$d$$p $(DESTDIR)$(kdeicondir)/$$f"; \
|
||||
$(kdeiconDATA_INSTALL) $$d$$p $(DESTDIR)$(kdeicondir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-kdeiconDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(kdeicon_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(kdeicondir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(kdeicondir)/$$f; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
ctags: CTAGS
|
||||
CTAGS:
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(DATA)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(appicondir) $(DESTDIR)$(desktopdir) $(DESTDIR)$(gnome1desktopdir) $(DESTDIR)$(kdedesktopdir) $(DESTDIR)$(kdeicondir)
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-appiconDATA install-dist_desktopDATA \
|
||||
install-gnome1desktopDATA install-kdedesktopDATA \
|
||||
install-kdeiconDATA
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-appiconDATA uninstall-dist_desktopDATA \
|
||||
uninstall-gnome1desktopDATA uninstall-info-am \
|
||||
uninstall-kdedesktopDATA uninstall-kdeiconDATA
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic distclean \
|
||||
distclean-generic distdir dvi dvi-am info info-am install \
|
||||
install-am install-appiconDATA install-data install-data-am \
|
||||
install-dist_desktopDATA install-exec install-exec-am \
|
||||
install-gnome1desktopDATA install-info install-info-am \
|
||||
install-kdedesktopDATA install-kdeiconDATA install-man \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
|
||||
uninstall-appiconDATA uninstall-dist_desktopDATA \
|
||||
uninstall-gnome1desktopDATA uninstall-info-am \
|
||||
uninstall-kdedesktopDATA uninstall-kdeiconDATA
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
12
icons/wesnoth.desktop
Normal file
|
@ -0,0 +1,12 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Encoding=UTF-8
|
||||
Type=Application
|
||||
Name=Battle for Wesnoth
|
||||
GenericName=Strategy Game
|
||||
Comment=A fantasy turn-based strategy game
|
||||
Icon=wesnoth.png
|
||||
FilePattern=wesnoth
|
||||
TryExec=wesnoth
|
||||
Exec=wesnoth
|
||||
Category=Application;Game;StrategyGame;
|
BIN
images/arch-mage-attack2.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
images/arch-mage-defend.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 589 B After Width: | Height: | Size: 1.3 KiB |
BIN
images/cockatrice-attack1.png
Normal file
After Width: | Height: | Size: 661 B |
BIN
images/cockatrice-attack2.png
Normal file
After Width: | Height: | Size: 684 B |
BIN
images/cockatrice.png
Normal file
After Width: | Height: | Size: 671 B |
BIN
images/cross.png
BIN
images/human-battleprincess.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
images/icon.png
BIN
images/undead-ancient-lich-attack.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
images/undead-ancient-lich-defend.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
images/wesnoth-icon.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
music/wesnoth-7.ogg
Normal file
BIN
music/wesnoth-8.ogg
Normal file
|
@ -43,6 +43,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
language.cpp \
|
||||
log.cpp \
|
||||
map.cpp \
|
||||
mapgen.cpp \
|
||||
mouse.cpp \
|
||||
multiplayer.cpp \
|
||||
multiplayer_client.cpp \
|
||||
|
@ -68,6 +69,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
widgets/menu.cpp \
|
||||
widgets/slider.cpp \
|
||||
widgets/textbox.cpp \
|
||||
widgets/widget.cpp \
|
||||
about.hpp \
|
||||
actions.hpp \
|
||||
ai.hpp \
|
||||
|
@ -90,6 +92,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
language.hpp \
|
||||
log.hpp \
|
||||
map.hpp \
|
||||
mapgen.hpp \
|
||||
mouse.hpp \
|
||||
multiplayer.hpp \
|
||||
multiplayer_client.hpp \
|
||||
|
@ -116,7 +119,8 @@ wesnoth_SOURCES = about.cpp \
|
|||
widgets/combo.hpp \
|
||||
widgets/menu.hpp \
|
||||
widgets/slider.hpp \
|
||||
widgets/textbox.hpp
|
||||
widgets/textbox.hpp \
|
||||
widgets/widget.hpp
|
||||
|
||||
#############################################################################
|
||||
# Editor #
|
||||
|
@ -143,6 +147,7 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
language.cpp \
|
||||
log.cpp \
|
||||
map.cpp \
|
||||
mapgen.cpp \
|
||||
mouse.cpp \
|
||||
network.cpp \
|
||||
pathfind.cpp \
|
||||
|
@ -164,6 +169,7 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
widgets/menu.cpp \
|
||||
widgets/textbox.cpp \
|
||||
widgets/slider.cpp \
|
||||
widgets/widget.cpp \
|
||||
actions.hpp \
|
||||
ai.hpp \
|
||||
ai_attack.hpp \
|
||||
|
@ -184,6 +190,7 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
language.hpp \
|
||||
log.hpp \
|
||||
map.hpp \
|
||||
mapgen.hpp \
|
||||
mouse.hpp \
|
||||
network.hpp \
|
||||
pathfind.hpp \
|
||||
|
@ -204,4 +211,5 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
widgets/button.hpp \
|
||||
widgets/menu.hpp \
|
||||
widgets/textbox.hpp \
|
||||
widgets/slider.hpp
|
||||
widgets/slider.hpp \
|
||||
widgets/widget.hpp
|
||||
|
|
|
@ -168,6 +168,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
language.cpp \
|
||||
log.cpp \
|
||||
map.cpp \
|
||||
mapgen.cpp \
|
||||
mouse.cpp \
|
||||
multiplayer.cpp \
|
||||
multiplayer_client.cpp \
|
||||
|
@ -215,6 +216,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
language.hpp \
|
||||
log.hpp \
|
||||
map.hpp \
|
||||
mapgen.hpp \
|
||||
mouse.hpp \
|
||||
multiplayer.hpp \
|
||||
multiplayer_client.hpp \
|
||||
|
@ -269,6 +271,7 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
language.cpp \
|
||||
log.cpp \
|
||||
map.cpp \
|
||||
mapgen.cpp \
|
||||
mouse.cpp \
|
||||
network.cpp \
|
||||
pathfind.cpp \
|
||||
|
@ -310,6 +313,7 @@ wesnoth_editor_SOURCES = editor/editor.cpp \
|
|||
language.hpp \
|
||||
log.hpp \
|
||||
map.hpp \
|
||||
mapgen.hpp \
|
||||
mouse.hpp \
|
||||
network.hpp \
|
||||
pathfind.hpp \
|
||||
|
@ -348,14 +352,15 @@ am_wesnoth_OBJECTS = about.$(OBJEXT) actions.$(OBJEXT) ai.$(OBJEXT) \
|
|||
game_config.$(OBJEXT) game_events.$(OBJEXT) \
|
||||
gamestatus.$(OBJEXT) hotkeys.$(OBJEXT) image.$(OBJEXT) \
|
||||
intro.$(OBJEXT) key.$(OBJEXT) language.$(OBJEXT) log.$(OBJEXT) \
|
||||
map.$(OBJEXT) mouse.$(OBJEXT) multiplayer.$(OBJEXT) \
|
||||
multiplayer_client.$(OBJEXT) multiplayer_lobby.$(OBJEXT) \
|
||||
network.$(OBJEXT) pathfind.$(OBJEXT) playlevel.$(OBJEXT) \
|
||||
playturn.$(OBJEXT) preferences.$(OBJEXT) race.$(OBJEXT) \
|
||||
replay.$(OBJEXT) sdl_utils.$(OBJEXT) show_dialog.$(OBJEXT) \
|
||||
sound.$(OBJEXT) team.$(OBJEXT) terrain.$(OBJEXT) \
|
||||
tooltips.$(OBJEXT) unit.$(OBJEXT) unit_types.$(OBJEXT) \
|
||||
video.$(OBJEXT) button.$(OBJEXT) combo.$(OBJEXT) menu.$(OBJEXT) \
|
||||
map.$(OBJEXT) mapgen.$(OBJEXT) mouse.$(OBJEXT) \
|
||||
multiplayer.$(OBJEXT) multiplayer_client.$(OBJEXT) \
|
||||
multiplayer_lobby.$(OBJEXT) network.$(OBJEXT) \
|
||||
pathfind.$(OBJEXT) playlevel.$(OBJEXT) playturn.$(OBJEXT) \
|
||||
preferences.$(OBJEXT) race.$(OBJEXT) replay.$(OBJEXT) \
|
||||
sdl_utils.$(OBJEXT) show_dialog.$(OBJEXT) sound.$(OBJEXT) \
|
||||
team.$(OBJEXT) terrain.$(OBJEXT) tooltips.$(OBJEXT) \
|
||||
unit.$(OBJEXT) unit_types.$(OBJEXT) video.$(OBJEXT) \
|
||||
button.$(OBJEXT) combo.$(OBJEXT) menu.$(OBJEXT) \
|
||||
slider.$(OBJEXT) textbox.$(OBJEXT)
|
||||
wesnoth_OBJECTS = $(am_wesnoth_OBJECTS)
|
||||
wesnoth_LDADD = $(LDADD)
|
||||
|
@ -368,14 +373,14 @@ am_wesnoth_editor_OBJECTS = editor.$(OBJEXT) actions.$(OBJEXT) \
|
|||
game_config.$(OBJEXT) game_events.$(OBJEXT) \
|
||||
gamestatus.$(OBJEXT) hotkeys.$(OBJEXT) image.$(OBJEXT) \
|
||||
intro.$(OBJEXT) key.$(OBJEXT) language.$(OBJEXT) log.$(OBJEXT) \
|
||||
map.$(OBJEXT) mouse.$(OBJEXT) network.$(OBJEXT) \
|
||||
pathfind.$(OBJEXT) playlevel.$(OBJEXT) playturn.$(OBJEXT) \
|
||||
preferences.$(OBJEXT) race.$(OBJEXT) replay.$(OBJEXT) \
|
||||
sdl_utils.$(OBJEXT) show_dialog.$(OBJEXT) sound.$(OBJEXT) \
|
||||
team.$(OBJEXT) terrain.$(OBJEXT) tooltips.$(OBJEXT) \
|
||||
unit.$(OBJEXT) unit_types.$(OBJEXT) video.$(OBJEXT) \
|
||||
button.$(OBJEXT) menu.$(OBJEXT) textbox.$(OBJEXT) \
|
||||
slider.$(OBJEXT)
|
||||
map.$(OBJEXT) mapgen.$(OBJEXT) mouse.$(OBJEXT) \
|
||||
network.$(OBJEXT) pathfind.$(OBJEXT) playlevel.$(OBJEXT) \
|
||||
playturn.$(OBJEXT) preferences.$(OBJEXT) race.$(OBJEXT) \
|
||||
replay.$(OBJEXT) sdl_utils.$(OBJEXT) show_dialog.$(OBJEXT) \
|
||||
sound.$(OBJEXT) team.$(OBJEXT) terrain.$(OBJEXT) \
|
||||
tooltips.$(OBJEXT) unit.$(OBJEXT) unit_types.$(OBJEXT) \
|
||||
video.$(OBJEXT) button.$(OBJEXT) menu.$(OBJEXT) \
|
||||
textbox.$(OBJEXT) slider.$(OBJEXT)
|
||||
wesnoth_editor_OBJECTS = $(am_wesnoth_editor_OBJECTS)
|
||||
wesnoth_editor_LDADD = $(LDADD)
|
||||
wesnoth_editor_DEPENDENCIES =
|
||||
|
@ -397,8 +402,8 @@ am__depfiles_maybe = depfiles
|
|||
@AMDEP_TRUE@ ./$(DEPDIR)/image.Po ./$(DEPDIR)/intro.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/key.Po ./$(DEPDIR)/language.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/log.Po ./$(DEPDIR)/map.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/menu.Po ./$(DEPDIR)/mouse.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/multiplayer.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/mapgen.Po ./$(DEPDIR)/menu.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/mouse.Po ./$(DEPDIR)/multiplayer.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/multiplayer_client.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/multiplayer_lobby.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/network.Po ./$(DEPDIR)/pathfind.Po \
|
||||
|
@ -501,6 +506,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/language.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapgen.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menu.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multiplayer.Po@am__quote@
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "events.hpp"
|
||||
#include "font.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "key.hpp"
|
||||
#include "language.hpp"
|
||||
|
@ -38,7 +39,7 @@ void show_about(display& disp)
|
|||
0,0,0,1.0,disp.video().getSurface());
|
||||
update_whole_screen();
|
||||
|
||||
const scoped_sdl_surface map_image(image::get_image("misc/map.png",image::UNSCALED));
|
||||
const scoped_sdl_surface map_image(image::get_image(game_config::map_image,image::UNSCALED));
|
||||
SDL_Rect map_rect;
|
||||
map_rect.x = disp.x()/2 - map_image->w/2;
|
||||
map_rect.y = disp.y()/2 - map_image->h/2;
|
||||
|
@ -97,7 +98,7 @@ void show_about(display& disp)
|
|||
text.push_back("-web developer");
|
||||
text.push_back("-artwork and graphics designer");
|
||||
text.push_back("Joseph Toscano (zhaymusic.com)");
|
||||
text.push_back("-music and sound designer");
|
||||
text.push_back("-music");
|
||||
text.push_back("Justin Zaun (jzaun)");
|
||||
text.push_back("-developer");
|
||||
text.push_back("-scenario designer");
|
||||
|
@ -109,7 +110,9 @@ void show_about(display& disp)
|
|||
text.push_back("-internationalization manager");
|
||||
text.push_back("-translator");
|
||||
text.push_back("Pau Congost");
|
||||
text.push_back("-music and sound designer");
|
||||
text.push_back("-music");
|
||||
text.push_back("Fredrik Lindroth");
|
||||
text.push_back("-music");
|
||||
text.push_back("Slainte");
|
||||
text.push_back("-artwork and graphics designer");
|
||||
text.push_back("Zas");
|
||||
|
@ -141,7 +144,7 @@ void show_about(display& disp)
|
|||
int line = startline;
|
||||
for(int cur_line=0;cur_line<12;cur_line++)
|
||||
{
|
||||
if(line>text.size()-1)
|
||||
if(size_t(line) > text.size()-1)
|
||||
line=0;
|
||||
SDL_Rect tr = font::draw_text(&disp,disp.screen_area(),24,font::BLACK_COLOUR,
|
||||
text[line], -1,height);
|
||||
|
@ -154,7 +157,7 @@ void show_about(display& disp)
|
|||
timer = 0;
|
||||
startline++;
|
||||
}
|
||||
if(startline == text.size())
|
||||
if(size_t(startline) == text.size())
|
||||
startline = 0;
|
||||
|
||||
if(close.process(mousex,mousey,left_button)) {
|
||||
|
|
|
@ -264,14 +264,15 @@ battle_stats evaluate_battle_stats(
|
|||
res.defend_special = defender_attacks[defend].special();
|
||||
}
|
||||
|
||||
if(defender_attacks[defend].special() == drain_string) {
|
||||
//if the defender drains, and the attacker is a living creature, then
|
||||
//the defender will drain for half the damage it does
|
||||
if(defender_attacks[defend].special() == drain_string && !a->second.type().not_living()) {
|
||||
res.amount_defender_drains = res.damage_attacker_takes/2;
|
||||
} else {
|
||||
res.amount_defender_drains = 0;
|
||||
}
|
||||
|
||||
res.defender_plague =
|
||||
(defender_attacks[defend].special() == plague_string);
|
||||
res.defender_plague = (defender_attacks[defend].special() == plague_string);
|
||||
}
|
||||
|
||||
if(attack.special() == magical_string)
|
||||
|
@ -291,7 +292,9 @@ battle_stats evaluate_battle_stats(
|
|||
if(under_leadership(units,attacker))
|
||||
res.damage_defender_takes += res.damage_defender_takes/8 + 1;
|
||||
|
||||
if(attack.special() == drain_string) {
|
||||
//if the attacker drains, and the defender is a living creature, then
|
||||
//the attacker will drain for half the damage it does
|
||||
if(attack.special() == drain_string && !d->second.type().not_living()) {
|
||||
res.amount_attacker_drains = res.damage_defender_takes/2;
|
||||
} else {
|
||||
res.amount_attacker_drains = 0;
|
||||
|
@ -1057,6 +1060,9 @@ void clear_shroud_unit(const gamemap& map, const game_data& gamedata,
|
|||
clear_shroud_loc(map,teams[team],i->first,&cleared_locations);
|
||||
}
|
||||
|
||||
//clear the location the unit is at
|
||||
clear_shroud_loc(map,teams[team],loc,&cleared_locations);
|
||||
|
||||
for(std::vector<gamemap::location>::const_iterator it =
|
||||
cleared_locations.begin(); it != cleared_locations.end(); ++it) {
|
||||
if(units.count(*it)) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "filesystem.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "log.hpp"
|
||||
#include "scoped_resource.hpp"
|
||||
|
||||
bool operator<(const line_source& a, const line_source& b)
|
||||
{
|
||||
|
@ -58,37 +59,53 @@ line_source get_line_source(const std::vector<line_source>& line_src, int line)
|
|||
return res;
|
||||
}
|
||||
|
||||
std::string read_file_internal(const std::string& fname)
|
||||
struct close_FILE
|
||||
{
|
||||
std::ifstream file(fname.c_str());
|
||||
std::string res;
|
||||
char c;
|
||||
while(file.get(c)) {
|
||||
res.resize(res.size()+1);
|
||||
res[res.size()-1] = c;
|
||||
void operator()(FILE* f) const { if(f != NULL) { fclose(f); } }
|
||||
};
|
||||
|
||||
void read_file_internal(const std::string& fname, std::string& res)
|
||||
{
|
||||
res.resize(0);
|
||||
|
||||
const util::scoped_resource<FILE*,close_FILE> file(fopen(fname.c_str(),"rb"));
|
||||
if(file == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
return res;
|
||||
const int block_size = 4096;
|
||||
char buf[block_size];
|
||||
|
||||
for(;;) {
|
||||
size_t nbytes = fread(buf,1,block_size,file);
|
||||
res.resize(res.size()+nbytes);
|
||||
std::copy(buf,buf+nbytes,res.end()-nbytes);
|
||||
|
||||
if(nbytes < block_size) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //end anon namespace
|
||||
|
||||
std::string read_file(const std::string& fname)
|
||||
{
|
||||
log_scope("reading file");
|
||||
|
||||
//if we have a path to the data,
|
||||
//convert any filepath which is relative
|
||||
if(!fname.empty() && fname[0] != '/' && !game_config::path.empty()) {
|
||||
std::cerr << "trying to read file: '" <<
|
||||
game_config::path << "/" << fname << "'\n";
|
||||
const std::string& res =
|
||||
read_file_internal(game_config::path + "/" + fname);
|
||||
std::string res;
|
||||
read_file_internal(game_config::path + "/" + fname,res);
|
||||
if(!res.empty()) {
|
||||
std::cerr << "success\n";
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return read_file_internal(fname);
|
||||
std::string res;
|
||||
read_file_internal(fname,res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void write_file(const std::string& fname, const std::string& data)
|
||||
|
|
|
@ -166,4 +166,15 @@ std::string load_game_dialog(display& disp, bool* show_replay)
|
|||
return games[res].name;
|
||||
}
|
||||
|
||||
void unit_speak(const config& message_info, display& disp, const unit_map& units)
|
||||
{
|
||||
for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if(i->second.matches_filter(message_info)) {
|
||||
disp.scroll_to_tile(i->first.x,i->first.y);
|
||||
const scoped_sdl_surface surface(image::get_image(i->second.type().image_profile(),image::UNSCALED));
|
||||
gui::show_dialog(disp,surface,i->second.underlying_description(),message_info["message"],gui::MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //end namespace dialogs
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
#define DIALOGS_H_INCLUDED
|
||||
|
||||
#include "actions.hpp"
|
||||
#include "config.hpp"
|
||||
#include "display.hpp"
|
||||
#include "show_dialog.hpp"
|
||||
#include "unit.hpp"
|
||||
|
||||
namespace dialogs
|
||||
{
|
||||
|
@ -38,6 +40,8 @@ int get_save_name(display & disp, const std::string& caption,
|
|||
//the user will not be asked if they want to show a replay.
|
||||
std::string load_game_dialog(display& disp, bool* show_replay);
|
||||
|
||||
void unit_speak(const config& message_info, display& disp, const unit_map& units);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
145
src/display.cpp
|
@ -88,9 +88,6 @@ namespace {
|
|||
const size_t Minimap_h = 146;
|
||||
const size_t TimeOfDay_x = 13;
|
||||
const size_t TimeOfDay_y = 167;
|
||||
|
||||
const std::string RightSideTop = "misc/rightside.png";
|
||||
const std::string RightSideBot = "misc/rightside-bottom.png";
|
||||
}
|
||||
|
||||
display::display(unit_map& units, CVideo& video, const gamemap& map,
|
||||
|
@ -424,10 +421,10 @@ void display::draw(bool update,bool force)
|
|||
{
|
||||
if(!sideBarBgDrawn_ && !teams_.empty()) {
|
||||
SDL_Surface* const screen = screen_.getSurface();
|
||||
const scoped_sdl_surface image_top(image::get_image(RightSideTop,image::UNSCALED));
|
||||
const scoped_sdl_surface image_top(image::get_image(game_config::rightside_image,image::UNSCALED));
|
||||
|
||||
const scoped_sdl_surface image(image_top != NULL ?
|
||||
image::get_image_dim(RightSideBot,image_top->w,screen->h-image_top->h) : NULL);
|
||||
image::get_image_dim(game_config::rightside_image_bot,image_top->w,screen->h-image_top->h) : NULL);
|
||||
if(image_top != NULL && image != NULL && image_top->h < screen->h) {
|
||||
|
||||
SDL_Rect dstrect;
|
||||
|
@ -553,7 +550,7 @@ void display::draw_game_status(int x, int y)
|
|||
|
||||
if(gameStatusRect_.w > 0) {
|
||||
SDL_Surface* const screen = screen_.getSurface();
|
||||
const scoped_sdl_surface background(image::get_image(RightSideTop,image::UNSCALED));
|
||||
const scoped_sdl_surface background(image::get_image(game_config::rightside_image,image::UNSCALED));
|
||||
|
||||
if(background == NULL)
|
||||
return;
|
||||
|
@ -615,8 +612,7 @@ void display::draw_game_status(int x, int y)
|
|||
}
|
||||
|
||||
if(unit_selected != units_.end() && map_.on_board(mouseoverHex_)) {
|
||||
const gamemap::TERRAIN terrain =
|
||||
map_[mouseoverHex_.x][mouseoverHex_.y];
|
||||
const gamemap::TERRAIN terrain = map_[mouseoverHex_.x][mouseoverHex_.y];
|
||||
|
||||
const unit& u = unit_selected->second;
|
||||
const int move_cost = u.movement_cost(map_,terrain);
|
||||
|
@ -653,8 +649,8 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
|
|||
|
||||
SDL_Rect clipRect = clip_rect != NULL ? *clip_rect : screen_area();
|
||||
|
||||
const scoped_sdl_surface background(image::get_image(RightSideTop,image::UNSCALED));
|
||||
const scoped_sdl_surface background_bot(image::get_image(RightSideBot,image::UNSCALED));
|
||||
const scoped_sdl_surface background(image::get_image(game_config::rightside_image,image::UNSCALED));
|
||||
const scoped_sdl_surface background_bot(image::get_image(game_config::rightside_image_bot,image::UNSCALED));
|
||||
|
||||
if(background == NULL || background_bot == NULL)
|
||||
return;
|
||||
|
@ -914,8 +910,8 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
|
|||
const bool is_shrouded = shrouded(x,y);
|
||||
gamemap::TERRAIN terrain = gamemap::VOID_TERRAIN;
|
||||
|
||||
if(map_.on_board(loc) && !is_shrouded) {
|
||||
terrain = map_[x][y];
|
||||
if(!is_shrouded) {
|
||||
terrain = map_.get_terrain(loc);
|
||||
}
|
||||
|
||||
image::TYPE image_type = image::SCALED;
|
||||
|
@ -1020,26 +1016,37 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
|
|||
const int unit_move = it->second.movement_left();
|
||||
const int unit_total_move = it->second.total_movement();
|
||||
|
||||
const char* energy_file = NULL;
|
||||
const std::string* energy_file = NULL;
|
||||
|
||||
if(size_t(it->second.side()) != currentTeam_+1) {
|
||||
if(team_valid() &&
|
||||
teams_[currentTeam_].is_enemy(it->second.side())) {
|
||||
energy_file = "enemy-energy.png";
|
||||
energy_file = &game_config::enemy_energy_image;
|
||||
} else {
|
||||
energy_file = "ally-energy.png";
|
||||
energy_file = &game_config::ally_energy_image;
|
||||
}
|
||||
} else {
|
||||
if(activeTeam_ == currentTeam_ && unit_move == unit_total_move) {
|
||||
energy_file = "unmoved-energy.png";
|
||||
energy_file = &game_config::unmoved_energy_image;
|
||||
} else if(activeTeam_ == currentTeam_ && unit_can_move(loc,units_,map_,teams_)) {
|
||||
energy_file = "partmoved-energy.png";
|
||||
energy_file = &game_config::partmoved_energy_image;
|
||||
} else {
|
||||
energy_file = "moved-energy.png";
|
||||
energy_file = &game_config::moved_energy_image;
|
||||
}
|
||||
}
|
||||
|
||||
energy_image.assign(image::get_image(energy_file));
|
||||
assert(energy_file != NULL);
|
||||
if(energy_file == NULL) {
|
||||
std::cerr << "energy file is NULL\n";
|
||||
return;
|
||||
}
|
||||
|
||||
energy_image.assign(image::get_image(*energy_file));
|
||||
if(energy_image.get() == NULL) {
|
||||
std::cerr << "failed to get energy image: '" << *energy_file << "'\n";
|
||||
return;
|
||||
}
|
||||
|
||||
unit_energy = double(it->second.hitpoints()) /
|
||||
double(it->second.max_hitpoints());
|
||||
|
||||
|
@ -1215,7 +1222,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
|
|||
}
|
||||
|
||||
if(game_config::debug && debugHighlights_.count(gamemap::location(x,y))) {
|
||||
const scoped_sdl_surface cross(image::get_image("cross.png"));
|
||||
const scoped_sdl_surface cross(image::get_image(game_config::cross_image));
|
||||
if(cross != NULL)
|
||||
draw_unit(xpos-xsrc,ypos-ysrc,cross,face_left,false,
|
||||
debugHighlights_[loc],0);
|
||||
|
@ -1240,8 +1247,11 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
|
|||
highlight_ratio = advancingAmount_;
|
||||
}
|
||||
|
||||
draw_unit(xpos-xsrc,ypos-ysrc,unit_image,face_left,false,
|
||||
highlight_ratio,blend_with);
|
||||
const int height_adjust = it->second.is_flying() ? 0 : map_.get_terrain_info(terrain).unit_height_adjust()*(zoom_/DefaultZoom);
|
||||
const double submerge = it->second.is_flying() ? 0.0 : map_.get_terrain_info(terrain).unit_submerge();
|
||||
|
||||
draw_unit(xpos-xsrc,ypos-ysrc - height_adjust,unit_image,face_left,false,
|
||||
highlight_ratio,blend_with,submerge);
|
||||
}
|
||||
|
||||
const bool energy_uses_alpha = highlight_ratio < 1.0 && blend_with == 0;
|
||||
|
@ -1336,10 +1346,10 @@ void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc)
|
|||
}
|
||||
}
|
||||
|
||||
static const std::string left_nw("misc/foot-left-nw.png");
|
||||
static const std::string left_n("misc/foot-left-n.png");
|
||||
static const std::string right_nw("misc/foot-right-nw.png");
|
||||
static const std::string right_n("misc/foot-right-n.png");
|
||||
static const std::string left_nw(game_config::foot_left_nw);
|
||||
static const std::string left_n(game_config::foot_left_n);
|
||||
static const std::string right_nw(game_config::foot_right_nw);
|
||||
static const std::string right_n(game_config::foot_right_n);
|
||||
|
||||
const std::string* image_str = &left_nw;
|
||||
|
||||
|
@ -1408,19 +1418,16 @@ std::vector<SDL_Surface*> display::getAdjacentTerrain(int x, int y,
|
|||
std::vector<SDL_Surface*> res;
|
||||
gamemap::location loc(x,y);
|
||||
|
||||
const gamemap::TERRAIN current_terrain = map_.on_board(loc) ? map_[x][y]:0;
|
||||
const gamemap::TERRAIN current_terrain = map_.get_terrain(loc);
|
||||
|
||||
gamemap::location adjacent[6];
|
||||
get_adjacent_tiles(loc,adjacent);
|
||||
int tiles[6];
|
||||
for(int i = 0; i != 6; ++i) {
|
||||
tiles[i] = map_.on_board(adjacent[i]) ?
|
||||
(int)map_[adjacent[i].x][adjacent[i].y] :
|
||||
(int)gamemap::VOID_TERRAIN;
|
||||
tiles[i] = map_.get_terrain(adjacent[i]);
|
||||
}
|
||||
|
||||
const std::vector<gamemap::TERRAIN>& precedence =
|
||||
map_.get_terrain_precedence();
|
||||
const std::vector<gamemap::TERRAIN>& precedence = map_.get_terrain_precedence();
|
||||
std::vector<gamemap::TERRAIN>::const_iterator terrain =
|
||||
std::find(precedence.begin(),precedence.end(),current_terrain);
|
||||
|
||||
|
@ -1485,11 +1492,6 @@ SDL_Surface* display::getTerrain(gamemap::TERRAIN terrain,image::TYPE image_type
|
|||
map_.get_terrain_info(terrain).image(x,y) :
|
||||
map_.get_terrain_info(terrain).adjacent_image());
|
||||
|
||||
if(terrain == gamemap::CASTLE &&
|
||||
map_.is_starting_position(gamemap::location(x,y)) != -1) {
|
||||
image = "terrain/keep";
|
||||
}
|
||||
|
||||
//see if there is a time-of-day specific version of this image
|
||||
if(direction == "") {
|
||||
const time_of_day& tod = status_.get_time_of_day();
|
||||
|
@ -1646,10 +1648,9 @@ double display::get_location_x(const gamemap::location& loc) const
|
|||
double display::get_location_y(const gamemap::location& loc) const
|
||||
{
|
||||
return static_cast<double>(loc.y)*zoom_ - ypos_ +
|
||||
((loc.x % 2) == 1 ? zoom_/2.0 : 0.0);
|
||||
(is_odd(loc.x) ? zoom_/2.0 : 0.0);
|
||||
}
|
||||
|
||||
|
||||
bool display::unit_attack_ranged(const gamemap::location& a,
|
||||
const gamemap::location& b, int damage,
|
||||
const attack_type& attack)
|
||||
|
@ -1771,8 +1772,8 @@ bool display::unit_attack_ranged(const gamemap::location& a,
|
|||
= attack.get_frame(missile_frame,NULL,
|
||||
attack_type::MISSILE_FRAME,dir);
|
||||
|
||||
static const std::string default_missile("missile-n.png");
|
||||
static const std::string default_diag_missile("missile-ne.png");
|
||||
static const std::string default_missile(game_config::missile_n_image);
|
||||
static const std::string default_diag_missile(game_config::missile_ne_image);
|
||||
if(missile_image == NULL) {
|
||||
if(dir == attack_type::VERTICAL)
|
||||
missile_image = &default_missile;
|
||||
|
@ -1940,6 +1941,15 @@ bool display::unit_attack(const gamemap::location& a,
|
|||
|
||||
hiddenUnit_ = a;
|
||||
|
||||
const gamemap::TERRAIN src_terrain = map_.get_terrain(a);
|
||||
const gamemap::TERRAIN dst_terrain = map_.get_terrain(b);
|
||||
|
||||
const double src_height_adjust = attacker.is_flying() ? 0 : map_.get_terrain_info(src_terrain).unit_height_adjust() * (zoom_/DefaultZoom);
|
||||
const double dst_height_adjust = attacker.is_flying() ? 0 : map_.get_terrain_info(dst_terrain).unit_height_adjust() * (zoom_/DefaultZoom);
|
||||
|
||||
const double src_submerge = attacker.is_flying() ? 0 : map_.get_terrain_info(src_terrain).unit_submerge();
|
||||
const double dst_submerge = attacker.is_flying() ? 0 : map_.get_terrain_info(dst_terrain).unit_submerge();
|
||||
|
||||
for(int i = begin_at; i < end_at; i += time_resolution*acceleration) {
|
||||
events::pump();
|
||||
|
||||
|
@ -2000,8 +2010,11 @@ bool display::unit_attack(const gamemap::location& a,
|
|||
const int posx = int(pos*xsrc + (1.0-pos)*xdst) + xoffset;
|
||||
const int posy = int(pos*ysrc + (1.0-pos)*ydst);
|
||||
|
||||
const int height_adjust = int(src_height_adjust*pos + dst_height_adjust*(1.0-pos));
|
||||
const double submerge = src_submerge*pos + dst_submerge*(1.0-pos);
|
||||
|
||||
if(image != NULL && !hide)
|
||||
draw_unit(posx,posy,image,attacker.facing_left());
|
||||
draw_unit(posx,posy-height_adjust,image,attacker.facing_left(),false,1.0,0,submerge);
|
||||
|
||||
const int wait_time = ticks + time_resolution - SDL_GetTicks();
|
||||
if(wait_time > 0 && !hide)
|
||||
|
@ -2040,6 +2053,15 @@ void display::move_unit_between(const gamemap::location& a,
|
|||
double xdst = get_location_x(b);
|
||||
double ydst = get_location_y(b);
|
||||
|
||||
const gamemap::TERRAIN src_terrain = map_.get_terrain(a);
|
||||
const gamemap::TERRAIN dst_terrain = map_.get_terrain(b);
|
||||
|
||||
const int src_height_adjust = u.is_flying() ? 0 : map_.get_terrain_info(src_terrain).unit_height_adjust() * (zoom_/DefaultZoom);
|
||||
const int dst_height_adjust = u.is_flying() ? 0 : map_.get_terrain_info(dst_terrain).unit_height_adjust() * (zoom_/DefaultZoom);
|
||||
|
||||
const double src_submerge = u.is_flying() ? 0 : map_.get_terrain_info(src_terrain).unit_submerge();
|
||||
const double dst_submerge = u.is_flying() ? 0 : map_.get_terrain_info(dst_terrain).unit_submerge();
|
||||
|
||||
const double nsteps = turbo() ? 3.0 : 10.0;
|
||||
const double xstep = (xdst - xsrc)/nsteps;
|
||||
const double ystep = (ydst - ysrc)/nsteps;
|
||||
|
@ -2110,8 +2132,11 @@ void display::move_unit_between(const gamemap::location& a,
|
|||
draw_tile(adjacent[tile].x,adjacent[tile].y);
|
||||
}
|
||||
|
||||
const int height_adjust = src_height_adjust + (dst_height_adjust-src_height_adjust)*(i/nsteps);
|
||||
const double submerge = src_submerge + (dst_submerge-src_submerge)*(i/nsteps);
|
||||
|
||||
draw(false);
|
||||
draw_unit((int)xloc,(int)yloc,image,face_left);
|
||||
draw_unit((int)xloc,(int)yloc - height_adjust,image,face_left,false,1.0,0,submerge);
|
||||
|
||||
const int new_ticks = SDL_GetTicks();
|
||||
const int wait_time = time_between_frames - (new_ticks - ticks);
|
||||
|
@ -2132,8 +2157,11 @@ void display::move_unit_between(const gamemap::location& a,
|
|||
|
||||
void display::draw_unit(int x, int y, SDL_Surface* image,
|
||||
bool reverse, bool upside_down,
|
||||
double alpha, Pixel blendto)
|
||||
double alpha, Pixel blendto, double submerged)
|
||||
{
|
||||
//the alpha value to use for submerged units
|
||||
static const double unit_submerged_alpha = 0.2;
|
||||
|
||||
if(updatesLocked_) {
|
||||
return;
|
||||
}
|
||||
|
@ -2150,7 +2178,10 @@ void display::draw_unit(int x, int y, SDL_Surface* image,
|
|||
surface_lock srclock(image);
|
||||
const Pixel* src = srclock.pixels();
|
||||
|
||||
const int endy = (y + image->h) < h ? (y + image->h) : h;
|
||||
const int height = image->h; //*(1.0 - submerged);
|
||||
const int submerge_height = y + image->h*(1.0 - submerged);
|
||||
|
||||
const int endy = (y + height) < h ? (y + height) : h;
|
||||
const int endx = (x + image->w) < w ? (x + image->w) : w;
|
||||
if(endx < x)
|
||||
return;
|
||||
|
@ -2191,6 +2222,11 @@ void display::draw_unit(int x, int y, SDL_Surface* image,
|
|||
for(; y != endy; ++y, src += src_increment) {
|
||||
Pixel* dst = screen_lock.pixels() + y*screen->w + x;
|
||||
|
||||
if(y == submerge_height && alpha > unit_submerged_alpha) {
|
||||
alpha = unit_submerged_alpha;
|
||||
blendto = 0;
|
||||
}
|
||||
|
||||
if(alpha == 1.0) {
|
||||
if(reverse) {
|
||||
for(int i = xoffset; i != len; ++i) {
|
||||
|
@ -2249,7 +2285,7 @@ const std::pair<int,int>& display::calculate_energy_bar()
|
|||
int first_row = -1;
|
||||
int last_row = -1;
|
||||
|
||||
const scoped_sdl_surface image(image::get_image("unmoved-energy.png"));
|
||||
const scoped_sdl_surface image(image::get_image(game_config::unmoved_energy_image));
|
||||
|
||||
surface_lock image_lock(image);
|
||||
const short* const begin = image_lock.pixels();
|
||||
|
@ -2273,7 +2309,7 @@ const std::pair<int,int>& display::calculate_energy_bar()
|
|||
|
||||
void display::invalidate(const gamemap::location& loc)
|
||||
{
|
||||
if(!invalidateAll_ && loc.valid()) {
|
||||
if(!invalidateAll_) {
|
||||
invalidated_.insert(loc);
|
||||
}
|
||||
}
|
||||
|
@ -2313,6 +2349,16 @@ void display::remove_overlay(const gamemap::location& loc)
|
|||
overlays_.erase(loc);
|
||||
}
|
||||
|
||||
void display::write_overlays(config& cfg) const
|
||||
{
|
||||
for(std::multimap<gamemap::location,std::string>::const_iterator i = overlays_.begin();
|
||||
i != overlays_.end(); ++i) {
|
||||
config& item = cfg.add_child("item");
|
||||
i->first.write(item);
|
||||
item["image"] = i->second;
|
||||
}
|
||||
}
|
||||
|
||||
void display::set_team(size_t team)
|
||||
{
|
||||
assert(team < teams_.size());
|
||||
|
@ -2401,3 +2447,8 @@ size_t display::viewing_team() const
|
|||
{
|
||||
return currentTeam_;
|
||||
}
|
||||
|
||||
size_t display::playing_team() const
|
||||
{
|
||||
return activeTeam_;
|
||||
}
|
|
@ -193,6 +193,9 @@ public:
|
|||
void add_overlay(const gamemap::location& loc, const std::string& image);
|
||||
void remove_overlay(const gamemap::location& loc);
|
||||
|
||||
//function to serialize overlay data
|
||||
void write_overlays(config& cfg) const;
|
||||
|
||||
//function which draws the details of the unit at the given location, at
|
||||
//(x,y) on-screen. xprofile and yprofile are the size of the unit's image.
|
||||
//this function is suitable for drawing a unit's details on the sidebar,
|
||||
|
@ -247,7 +250,10 @@ public:
|
|||
|
||||
bool fogged(int x, int y) const;
|
||||
|
||||
//the viewing team is the team currently viewing the game. The playing team
|
||||
//is the team whose turn it is
|
||||
size_t viewing_team() const;
|
||||
size_t playing_team() const;
|
||||
|
||||
private:
|
||||
display(const display&);
|
||||
|
@ -257,9 +263,19 @@ private:
|
|||
const gamemap::location& b,
|
||||
const unit& u);
|
||||
|
||||
//function to draw the image of a unit at a certain location
|
||||
//x,y: pixel location on screen to draw the unit
|
||||
//image: the image of the unit
|
||||
//reverse: if the unit should be flipped across the y axis
|
||||
//upside_down: if the unit should be flipped across the x axis
|
||||
//alpha: the merging to use with the background
|
||||
//blendto: if blendto is not 0, then the alpha parameter will be used
|
||||
// to blend to this colour, instead of the background
|
||||
//submerged: the amount of the unit out of 1.0 that is submerged
|
||||
// (presumably under water) and thus shouldn't be drawn
|
||||
void draw_unit(int x, int y, SDL_Surface* image,
|
||||
bool reverse, bool upside_down=false,
|
||||
double alpha=1.0, short blendto=0);
|
||||
double alpha=1.0, short blendto=0, double submerged=0.0);
|
||||
|
||||
void unit_die(const gamemap::location& loc, SDL_Surface* image=NULL);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <stack>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -26,22 +27,50 @@ resize_lock::~resize_lock()
|
|||
--disallow_resize;
|
||||
}
|
||||
|
||||
std::vector<handler*> event_handlers;
|
||||
//this object stores all the event handlers. It is a stack of event 'contexts'.
|
||||
//a new event context is created when e.g. a modal dialog is opened, and then
|
||||
//closed when that dialog is closed. Each context contains a list of the handlers
|
||||
//in that context. The current context is the one on the top of the stack
|
||||
std::stack<std::vector<handler*> > event_contexts;
|
||||
|
||||
event_context::event_context()
|
||||
{
|
||||
event_contexts.push(std::vector<handler*>());
|
||||
}
|
||||
|
||||
event_context::~event_context()
|
||||
{
|
||||
assert(event_contexts.empty() == false);
|
||||
assert(event_contexts.top().empty());
|
||||
|
||||
event_contexts.pop();
|
||||
}
|
||||
|
||||
handler::handler() : unicode_(SDL_EnableUNICODE(1))
|
||||
{
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
event_handlers.push_back(this);
|
||||
event_contexts.top().push_back(this);
|
||||
}
|
||||
|
||||
handler::~handler()
|
||||
{
|
||||
assert(!event_handlers.empty());
|
||||
if(event_handlers.back() == this) {
|
||||
event_handlers.pop_back();
|
||||
assert(event_contexts.empty() == false);
|
||||
|
||||
std::vector<handler*>& handlers = event_contexts.top();
|
||||
|
||||
assert(handlers.empty() == false);
|
||||
|
||||
//the handler is most likely on the back of the events array,
|
||||
//so look there first, otherwise do a complete search.
|
||||
if(handlers.back() == this) {
|
||||
handlers.pop_back();
|
||||
} else {
|
||||
event_handlers.erase(std::find(event_handlers.begin(),
|
||||
event_handlers.end(),this));
|
||||
const std::vector<handler*>::iterator i = std::find(handlers.begin(),handlers.end(),this);
|
||||
if(i != handlers.end()) {
|
||||
handlers.erase(i);
|
||||
} else {
|
||||
std::cerr << "CRITICAL ERROR: Could not find event handler in events array\n";
|
||||
}
|
||||
}
|
||||
|
||||
SDL_EnableUNICODE(unicode_);
|
||||
|
@ -59,16 +88,20 @@ void pump()
|
|||
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
//events may cause more event handlers to be added and/or removed,
|
||||
//so we must use indexes instead of iterators here.
|
||||
for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
|
||||
event_handlers[i1]->handle_event(event);
|
||||
if(event_contexts.empty() == false) {
|
||||
|
||||
const std::vector<handler*>& event_handlers = event_contexts.top();
|
||||
|
||||
//events may cause more event handlers to be added and/or removed,
|
||||
//so we must use indexes instead of iterators here.
|
||||
for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
|
||||
event_handlers[i1]->handle_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
switch(event.type) {
|
||||
case SDL_VIDEORESIZE: {
|
||||
const SDL_ResizeEvent* const resize
|
||||
= reinterpret_cast<SDL_ResizeEvent*>(&event);
|
||||
const SDL_ResizeEvent* const resize = reinterpret_cast<SDL_ResizeEvent*>(&event);
|
||||
|
||||
if(resize->w < 800 || resize->h < 600) {
|
||||
resize_dimensions.first = 0;
|
||||
|
@ -127,4 +160,32 @@ void pump()
|
|||
}
|
||||
}
|
||||
|
||||
void raise_process_event()
|
||||
{
|
||||
if(event_contexts.empty() == false) {
|
||||
|
||||
const std::vector<handler*>& event_handlers = event_contexts.top();
|
||||
|
||||
//events may cause more event handlers to be added and/or removed,
|
||||
//so we must use indexes instead of iterators here.
|
||||
for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
|
||||
event_handlers[i1]->process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void raise_draw_event()
|
||||
{
|
||||
if(event_contexts.empty() == false) {
|
||||
|
||||
const std::vector<handler*>& event_handlers = event_contexts.top();
|
||||
|
||||
//events may cause more event handlers to be added and/or removed,
|
||||
//so we must use indexes instead of iterators here.
|
||||
for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
|
||||
event_handlers[i1]->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,14 +17,18 @@ struct resize_lock {
|
|||
};
|
||||
|
||||
//any classes that derive from this class will automatically
|
||||
//receive sdl events through the handle function for their lifetime
|
||||
//note that handlers should *always* be allocated as automatic variables
|
||||
//(never on the free store or in static memory), as the event mechanism
|
||||
//relies on handlers being created and destroyed in LIFO ordering.
|
||||
//receive sdl events through the handle function for their lifetime,
|
||||
//while the event context they were created in is active.
|
||||
//
|
||||
//NOTE: an event_context object must be initialized before a handler object
|
||||
//can be initialized, and the event_context must be destroyed after
|
||||
//the handler is destroyed.
|
||||
class handler
|
||||
{
|
||||
public:
|
||||
virtual void handle_event(const SDL_Event& event) = 0;
|
||||
virtual void process() {}
|
||||
virtual void draw() const {}
|
||||
protected:
|
||||
handler();
|
||||
virtual ~handler();
|
||||
|
@ -33,8 +37,26 @@ private:
|
|||
const int unicode_;
|
||||
};
|
||||
|
||||
//event_context objects control the handler objects that SDL events are sent
|
||||
//to. When an event_context is created, it will become the current event context.
|
||||
//event_context objects MUST be created in LIFO ordering in relation to each other,
|
||||
//and in relation to handler objects. That is, all event_context objects should be
|
||||
//created as automatic/stack variables.
|
||||
//
|
||||
//handler objects need not be created as automatic variables (e.g. you could put
|
||||
//them in a vector) however you must guarantee that handler objects are destroyed
|
||||
//before their context is destroyed
|
||||
struct event_context
|
||||
{
|
||||
event_context();
|
||||
~event_context();
|
||||
};
|
||||
|
||||
//causes events to be dispatched to all handler objects.
|
||||
void pump();
|
||||
|
||||
void raise_process_event();
|
||||
void raise_draw_event();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -229,7 +229,10 @@ bool is_directory_internal(const std::string& fname)
|
|||
|
||||
#else
|
||||
struct stat dir_stat;
|
||||
::stat(fname.c_str(), &dir_stat);
|
||||
if(::stat(fname.c_str(), &dir_stat) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR(dir_stat.st_mode);
|
||||
#endif
|
||||
}
|
||||
|
@ -258,6 +261,8 @@ bool file_exists(const std::string& name)
|
|||
time_t file_create_time(const std::string& fname)
|
||||
{
|
||||
struct stat buf;
|
||||
::stat(fname.c_str(),&buf);
|
||||
if(::stat(fname.c_str(),&buf) == -1)
|
||||
return 0;
|
||||
|
||||
return buf.st_mtime;
|
||||
}
|
||||
|
|
61
src/game.cpp
|
@ -19,6 +19,7 @@
|
|||
#include "config.hpp"
|
||||
#include "dialogs.hpp"
|
||||
#include "display.hpp"
|
||||
#include "events.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "font.hpp"
|
||||
#include "game_config.hpp"
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include "gamestatus.hpp"
|
||||
#include "key.hpp"
|
||||
#include "language.hpp"
|
||||
#include "mapgen.hpp"
|
||||
#include "multiplayer.hpp"
|
||||
#include "multiplayer_client.hpp"
|
||||
#include "network.hpp"
|
||||
|
@ -55,7 +57,22 @@ LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
|
|||
if(type.empty())
|
||||
type = "scenario";
|
||||
|
||||
config* scenario = game_config.find_child(type,"id",state.scenario);
|
||||
config* scenario = NULL;
|
||||
|
||||
config starting_pos;
|
||||
|
||||
//see if we load the scenario from the scenario data -- if there is
|
||||
//no snapshot data available from a save, or if the user has selected
|
||||
//to view the replay from scratch
|
||||
if(state.starting_pos.child("side") == NULL || !recorder.at_end()) {
|
||||
scenario = game_config.find_child(type,"id",state.scenario);
|
||||
} else {
|
||||
//load from a save-snapshot.
|
||||
starting_pos = state.starting_pos;
|
||||
scenario = &starting_pos;
|
||||
state = read_game(units_data,&state.starting_pos);
|
||||
}
|
||||
|
||||
while(scenario != NULL) {
|
||||
|
||||
const config::child_list& story = scenario->get_children("story");
|
||||
|
@ -78,6 +95,8 @@ LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
|
|||
video,state,story);
|
||||
}
|
||||
|
||||
state.starting_pos = config();
|
||||
|
||||
//ask to save a replay of the game
|
||||
if(res == VICTORY || res == DEFEAT) {
|
||||
const std::string orig_scenario = state.scenario;
|
||||
|
@ -90,7 +109,8 @@ LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
|
|||
string_table["save_game_label"],
|
||||
&label);
|
||||
if(should_save == 0) {
|
||||
recorder.save_game(units_data,label);
|
||||
config starting_pos;
|
||||
recorder.save_game(units_data,label,starting_pos);
|
||||
}
|
||||
|
||||
state.scenario = orig_scenario;
|
||||
|
@ -103,13 +123,16 @@ LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
|
|||
return res;
|
||||
}
|
||||
} catch(gamestatus::load_game_failed& e) {
|
||||
gui::show_dialog(disp,NULL,"","The game could not be loaded: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "The game could not be loaded: " << e.message << "\n";
|
||||
return QUIT;
|
||||
} catch(gamestatus::game_error& e) {
|
||||
gui::show_dialog(disp,NULL,"","An error occurred while playing the game: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "An error occurred while playing the game: "
|
||||
<< e.message << "\n";
|
||||
return QUIT;
|
||||
} catch(gamemap::incorrect_format_exception& e) {
|
||||
gui::show_dialog(disp,NULL,"",e.msg_,gui::OK_ONLY);
|
||||
std::cerr << "The game map could not be loaded: " << e.msg_ << "\n";
|
||||
return QUIT;
|
||||
}
|
||||
|
@ -145,11 +168,14 @@ LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
|
|||
|
||||
int play_game(int argc, char** argv)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
CVideo video;
|
||||
const font::manager font_manager;
|
||||
const sound::manager sound_manager;
|
||||
const preferences::manager prefs_manager;
|
||||
const image::manager image_manager;
|
||||
const events::event_context main_event_context;
|
||||
|
||||
bool test_mode = false;
|
||||
|
||||
|
@ -197,14 +223,17 @@ int play_game(int argc, char** argv)
|
|||
defines_map["NORMAL"] = preproc_define();
|
||||
std::vector<line_source> line_src;
|
||||
|
||||
std::string game_cfg = preprocess_file("data/game.cfg",&defines_map,
|
||||
&line_src);
|
||||
std::string game_cfg = preprocess_file("data/game.cfg",&defines_map,&line_src);
|
||||
|
||||
config game_config(game_cfg,&line_src);
|
||||
|
||||
//clear game_cfg so it doesn't take up memory
|
||||
std::string().swap(game_cfg);
|
||||
|
||||
game_config::load_config(game_config.child("game_config"));
|
||||
|
||||
const map_generator::manager map_generation_manager(game_config);
|
||||
|
||||
const config::child_list& units = game_config.get_children("units");
|
||||
if(units.empty()) {
|
||||
std::cerr << "Could not find units configuration\n";
|
||||
|
@ -296,7 +325,7 @@ int play_game(int argc, char** argv)
|
|||
SDL_WM_SetCaption(string_table["game_title"].c_str(), NULL);
|
||||
|
||||
for(;;) {
|
||||
sound::play_music("wesnoth-1.ogg");
|
||||
sound::play_music(game_config::title_music);
|
||||
|
||||
game_state state;
|
||||
|
||||
|
@ -313,11 +342,12 @@ int play_game(int argc, char** argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
recorder.clear();
|
||||
|
||||
gui::TITLE_RESULT res = gui::show_title(disp);
|
||||
if(res == gui::QUIT_GAME) {
|
||||
return 0;
|
||||
} else if(res == gui::LOAD_GAME) {
|
||||
srand(SDL_GetTicks());
|
||||
|
||||
bool show_replay;
|
||||
|
||||
|
@ -352,7 +382,14 @@ int play_game(int argc, char** argv)
|
|||
}
|
||||
|
||||
recorder = replay(state.replay_data);
|
||||
if(!recorder.empty()) {
|
||||
|
||||
//only play replay data if the user has selected to view the replay,
|
||||
//or if there is no starting position data to use.
|
||||
if(!show_replay && state.starting_pos.child("side") == NULL) {
|
||||
recorder.set_to_end();
|
||||
}
|
||||
|
||||
if(!recorder.at_end()) {
|
||||
//set whether the replay is to be skipped or not
|
||||
if(show_replay) {
|
||||
recorder.set_skip(0);
|
||||
|
@ -450,15 +487,20 @@ int play_game(int argc, char** argv)
|
|||
play_multiplayer_client(disp,units_data,game_config,state);
|
||||
}
|
||||
} catch(gamestatus::load_game_failed& e) {
|
||||
std::cerr << "error loading the game: " << e.message
|
||||
<< "\n";
|
||||
gui::show_dialog(disp,NULL,"","error loading the game: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "error loading the game: " << e.message << "\n";
|
||||
return 0;
|
||||
} catch(gamestatus::game_error& e) {
|
||||
gui::show_dialog(disp,NULL,"","error while playing the game: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "error while playing the game: "
|
||||
<< e.message << "\n";
|
||||
return 0;
|
||||
} catch(network::error& e) {
|
||||
gui::show_dialog(disp,NULL,"",e.message,gui::OK_ONLY);
|
||||
} catch(gamemap::incorrect_format_exception& e) {
|
||||
gui::show_dialog(disp,NULL,"",std::string("The game map could not be loaded: ") + e.msg_,gui::OK_ONLY);
|
||||
std::cerr << "The game map could not be loaded: " << e.msg_ << "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -476,6 +518,7 @@ int play_game(int argc, char** argv)
|
|||
} else if(res == gui::EDIT_PREFERENCES) {
|
||||
const preferences::display_manager disp_manager(&disp);
|
||||
preferences::show_preferences_dialog(disp);
|
||||
|
||||
disp.redraw_everything();
|
||||
continue;
|
||||
} else if(res == gui::SHOW_ABOUT) {
|
||||
|
|
|
@ -12,23 +12,85 @@
|
|||
*/
|
||||
#include "game_config.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace game_config
|
||||
{
|
||||
const int unit_cost = 1;
|
||||
const int base_income = 2;
|
||||
const int tower_income = 1;
|
||||
const int heal_amount = 4;
|
||||
const int healer_heals_per_turn = 8;
|
||||
const int cure_amount = 8;
|
||||
const int curer_heals_per_turn = 18;
|
||||
const int recall_cost = 20;
|
||||
const int kill_experience = 8;
|
||||
const std::string version = "0.6.1";
|
||||
int base_income = 2;
|
||||
int tower_income = 1;
|
||||
int heal_amount = 4;
|
||||
int healer_heals_per_turn = 8;
|
||||
int cure_amount = 8;
|
||||
int curer_heals_per_turn = 18;
|
||||
int recall_cost = 20;
|
||||
int kill_experience = 8;
|
||||
const std::string version = "0.6.2-CVS";
|
||||
bool debug = false;
|
||||
|
||||
std::string game_icon, game_title, title_music;
|
||||
|
||||
std::string missile_n_image, missile_ne_image;
|
||||
|
||||
std::string map_image = "misc/map.png";
|
||||
std::string rightside_image = "misc/rightside.png";
|
||||
std::string rightside_image_bot = "misc/rightside-bottom.png";
|
||||
|
||||
std::string moved_energy_image = "moved-energy.png";
|
||||
std::string unmoved_energy_image = "unmoved-energy.png";
|
||||
std::string partmoved_energy_image = "partmoved-energy.png";
|
||||
std::string enemy_energy_image = "enemy-energy.png";
|
||||
std::string ally_energy_image = "ally-energy.png";
|
||||
|
||||
std::string dot_image = "misc/dot.png";
|
||||
std::string cross_image = "misc/cross.png";
|
||||
|
||||
std::string foot_left_nw, foot_left_n, foot_right_nw, foot_right_n;
|
||||
|
||||
#ifdef WESNOTH_PATH
|
||||
std::string path = WESNOTH_PATH;
|
||||
#else
|
||||
std::string path = "";
|
||||
#endif
|
||||
|
||||
void load_config(const config* cfg)
|
||||
{
|
||||
if(cfg == NULL)
|
||||
return;
|
||||
|
||||
const config& v = *cfg;
|
||||
|
||||
base_income = atoi(v["base_income"].c_str());
|
||||
tower_income = atoi(v["village_income"].c_str());
|
||||
heal_amount = atoi(v["heal_amount"].c_str());
|
||||
healer_heals_per_turn = atoi(v["healer_heals_per_turn"].c_str());
|
||||
cure_amount = atoi(v["cure_amount"].c_str());
|
||||
curer_heals_per_turn = atoi(v["curer_heals_per_turn"].c_str());
|
||||
recall_cost = atoi(v["recall_cost"].c_str());
|
||||
kill_experience = atoi(v["kill_experience"].c_str());
|
||||
|
||||
game_icon = v["icon"];
|
||||
game_title = v["title"];
|
||||
title_music = v["title_music"];
|
||||
|
||||
map_image = v["map_image"];
|
||||
rightside_image = v["sidebar_image"];
|
||||
rightside_image_bot = v["sidebar_image_bottom"];
|
||||
|
||||
moved_energy_image = v["moved_energy_image"];
|
||||
unmoved_energy_image = v["unmoved_energy_image"];
|
||||
partmoved_energy_image = v["partmoved_energy_image"];
|
||||
enemy_energy_image = v["enemy_energy_image"];
|
||||
ally_energy_image = v["ally_energy_image"];
|
||||
|
||||
cross_image = v["cross_image"];
|
||||
dot_image = v["dot_image"];
|
||||
|
||||
foot_left_nw = v["footprint_left_nw"];
|
||||
foot_left_n = v["footprint_left_n"];
|
||||
foot_right_nw = v["footprint_right_nw"];
|
||||
foot_right_n = v["footprint_right_n"];
|
||||
|
||||
missile_n_image = v["missile_n_image"];
|
||||
missile_ne_image = v["missile_ne_image"];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,25 +13,35 @@
|
|||
#ifndef GAME_CONFIG_H_INCLUDED
|
||||
#define GAME_CONFIG_H_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
//basic game configuration information is here.
|
||||
namespace game_config
|
||||
{
|
||||
extern const int unit_cost;
|
||||
extern const int base_income;
|
||||
extern const int tower_income;
|
||||
extern const int heal_amount;
|
||||
extern const int healer_heals_per_turn;
|
||||
extern const int cure_amount;
|
||||
extern const int curer_heals_per_turn;
|
||||
extern const int recall_cost;
|
||||
extern const int kill_experience;
|
||||
extern int base_income;
|
||||
extern int tower_income;
|
||||
extern int heal_amount;
|
||||
extern int healer_heals_per_turn;
|
||||
extern int cure_amount;
|
||||
extern int curer_heals_per_turn;
|
||||
extern int recall_cost;
|
||||
extern int kill_experience;
|
||||
extern const std::string version;
|
||||
|
||||
extern bool debug;
|
||||
|
||||
extern std::string path;
|
||||
|
||||
extern std::string game_icon, game_title, title_music, map_image, rightside_image, rightside_image_bot,
|
||||
moved_energy_image, unmoved_energy_image, partmoved_energy_image,
|
||||
enemy_energy_image,ally_energy_image,
|
||||
dot_image,cross_image,
|
||||
foot_left_nw,foot_left_n,foot_right_nw,foot_right_n,
|
||||
missile_n_image,missile_ne_image;
|
||||
|
||||
void load_config(const config* cfg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,6 +162,13 @@ public:
|
|||
cfg_(cfg)
|
||||
{}
|
||||
|
||||
void write(config& cfg) const {
|
||||
if(cfg_ == NULL || disabled_)
|
||||
return;
|
||||
|
||||
cfg = *cfg_;
|
||||
}
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
bool first_time_only() const { return first_time_only_; }
|
||||
|
@ -914,6 +921,35 @@ manager::manager(config& cfg, display& gui_, gamemap& map_,
|
|||
game_data_ptr = &game_data_;
|
||||
|
||||
used_items.clear();
|
||||
const std::string& used = cfg["used_items"];
|
||||
if(!used.empty()) {
|
||||
const std::vector<std::string>& v = config::split(used);
|
||||
for(std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
used_items.insert(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_events(config& cfg)
|
||||
{
|
||||
for(std::multimap<std::string,event_handler>::const_iterator i = events_map.begin(); i != events_map.end(); ++i) {
|
||||
if(!i->second.disabled()) {
|
||||
i->second.write(cfg.add_child("event"));
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream used;
|
||||
for(std::set<std::string>::const_iterator u = used_items.begin(); u != used_items.end(); ++u) {
|
||||
if(u != used_items.begin())
|
||||
used << ",";
|
||||
|
||||
used << *u;
|
||||
}
|
||||
|
||||
cfg["used_items"] = used.str();
|
||||
|
||||
if(screen != NULL)
|
||||
screen->write_overlays(cfg);
|
||||
}
|
||||
|
||||
manager::~manager() {
|
||||
|
|
|
@ -49,6 +49,8 @@ struct manager {
|
|||
~manager();
|
||||
};
|
||||
|
||||
void write_events(config& cfg);
|
||||
|
||||
//function to fire an event. Events may have up to two arguments, both of
|
||||
//which must be locations.
|
||||
bool fire(const std::string& event,
|
||||
|
|
|
@ -33,9 +33,34 @@ time_of_day::time_of_day(const config& cfg)
|
|||
name = lang_name;
|
||||
}
|
||||
|
||||
void time_of_day::write(config& cfg) const
|
||||
{
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",lawful_bonus);
|
||||
cfg["lawful_bonus"] = buf;
|
||||
|
||||
sprintf(buf,"%d",red);
|
||||
cfg["red"] = buf;
|
||||
|
||||
sprintf(buf,"%d",green);
|
||||
cfg["green"] = buf;
|
||||
|
||||
sprintf(buf,"%d",blue);
|
||||
cfg["blue"] = buf;
|
||||
|
||||
cfg["image"] = image;
|
||||
cfg["name"] = name;
|
||||
cfg["id"] = id;
|
||||
}
|
||||
|
||||
gamestatus::gamestatus(config& time_cfg, int num_turns) :
|
||||
turn_(1),numTurns_(num_turns)
|
||||
{
|
||||
const std::string& turn_at = time_cfg["turn_at"];
|
||||
if(turn_at.empty() == false) {
|
||||
turn_ = atoi(turn_at.c_str());
|
||||
}
|
||||
|
||||
const config::child_list& times = time_cfg.get_children("time");
|
||||
config::child_list::const_iterator t;
|
||||
for(t = times.begin(); t != times.end(); ++t) {
|
||||
|
@ -50,6 +75,25 @@ gamestatus::gamestatus(config& time_cfg, int num_turns) :
|
|||
}
|
||||
}
|
||||
|
||||
void gamestatus::write(config& cfg) const
|
||||
{
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",turn_);
|
||||
cfg["turn_at"] = buf;
|
||||
|
||||
sprintf(buf,"%d",numTurns_);
|
||||
cfg["turns"] = buf;
|
||||
|
||||
std::vector<time_of_day>::const_iterator t;
|
||||
for(t = times_.begin(); t != times_.end(); ++t) {
|
||||
t->write(cfg.add_child("time"));
|
||||
}
|
||||
|
||||
for(t = illuminatedTimes_.begin(); t != illuminatedTimes_.end(); ++t) {
|
||||
t->write(cfg.add_child("illuminated_time"));
|
||||
}
|
||||
}
|
||||
|
||||
const time_of_day& gamestatus::get_time_of_day(bool illuminated) const
|
||||
{
|
||||
if(illuminated && illuminatedTimes_.empty() == false) {
|
||||
|
@ -79,7 +123,7 @@ bool gamestatus::next_turn()
|
|||
return turn_ <= numTurns_;
|
||||
}
|
||||
|
||||
game_state read_game(game_data& data, config* cfg)
|
||||
game_state read_game(game_data& data, const config* cfg)
|
||||
{
|
||||
log_scope("read_game");
|
||||
game_state res;
|
||||
|
@ -151,7 +195,7 @@ void write_game(const game_state& game, config& cfg)
|
|||
cfg.add_child("unit",new_cfg);
|
||||
}
|
||||
|
||||
if(game.replay_data.children.empty() == false) {
|
||||
if(game.replay_data.child("replay") == NULL) {
|
||||
cfg.add_child("replay",game.replay_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
struct time_of_day
|
||||
{
|
||||
explicit time_of_day(const config& cfg);
|
||||
void write(config& cfg) const;
|
||||
|
||||
//the % bonus lawful units receive. chaotic units will
|
||||
//receive -lawful_bonus.
|
||||
|
@ -46,6 +47,7 @@ class gamestatus
|
|||
{
|
||||
public:
|
||||
gamestatus(config& time_cfg, int num_turns);
|
||||
void write(config& cfg) const;
|
||||
|
||||
const time_of_day& get_time_of_day(bool illuminated=false) const;
|
||||
size_t turn() const;
|
||||
|
@ -113,6 +115,9 @@ struct save_info {
|
|||
//function to get a list of available saves.
|
||||
std::vector<save_info> get_saves_list();
|
||||
|
||||
game_state read_game(game_data& data, const config* cfg);
|
||||
void write_game(const game_state& game, config& cfg);
|
||||
|
||||
// function returns true iff there is already savegame with that name
|
||||
bool save_game_exists(const std::string & name);
|
||||
|
||||
|
|
|
@ -134,8 +134,7 @@ manager::~manager()
|
|||
|
||||
void set_wm_icon()
|
||||
{
|
||||
//this code seems to only display the top part of the icon in Windows XP
|
||||
scoped_sdl_surface icon(get_image("icon.png",UNSCALED));
|
||||
scoped_sdl_surface icon(get_image(game_config::game_icon,UNSCALED));
|
||||
if(icon != NULL) {
|
||||
std::cerr << "setting icon...\n";
|
||||
::SDL_WM_SetIcon(icon,NULL);
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
|
||||
#include "events.hpp"
|
||||
#include "font.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "intro.hpp"
|
||||
#include "key.hpp"
|
||||
#include "language.hpp"
|
||||
#include "show_dialog.hpp"
|
||||
#include "sound.hpp"
|
||||
#include "util.hpp"
|
||||
#include "video.hpp"
|
||||
#include "widgets/button.hpp"
|
||||
|
@ -45,6 +47,11 @@ void show_intro(display& screen, const config& data)
|
|||
skip_button.set_x(screen.x()-200);
|
||||
skip_button.set_y(screen.y()-100);
|
||||
|
||||
const std::string& music = data["music"];
|
||||
if(music != "") {
|
||||
sound::play_music(music);
|
||||
}
|
||||
|
||||
const config::child_list& parts = data.get_children("part");
|
||||
|
||||
for(config::child_list::const_iterator i = parts.begin(); i != parts.end(); ++i){
|
||||
|
@ -192,9 +199,12 @@ void show_map_scene(display& screen, config& data)
|
|||
const std::string& image_file = cfg["image"];
|
||||
|
||||
const scoped_sdl_surface image(image::get_image(image_file,image::UNSCALED));
|
||||
const scoped_sdl_surface dot_image(image::get_image("misc/dot.png",image::UNSCALED));
|
||||
const scoped_sdl_surface cross_image(image::get_image("misc/cross.png",image::UNSCALED));
|
||||
const scoped_sdl_surface dot_image(image::get_image(game_config::dot_image,image::UNSCALED));
|
||||
const scoped_sdl_surface cross_image(image::get_image(game_config::cross_image,image::UNSCALED));
|
||||
if(image == NULL || dot_image == NULL || cross_image == NULL) {
|
||||
std::cerr << "could not find map image: '" << image_file << "': " << (image == NULL ? "failed" : "ok") << "\n"
|
||||
<< "'" << game_config::dot_image << "': " << (dot_image == NULL ? "failed" : "ok") << "\n"
|
||||
<< "'" << game_config::cross_image << "': " << (cross_image == NULL ? "failed" : "ok") << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
53
src/map.cpp
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
#include "game.hpp"
|
||||
#include "map.hpp"
|
||||
#include "pathfind.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -78,6 +79,15 @@ gamemap::location::location(const config& cfg) : x(-1), y(-1)
|
|||
y = atoi(ystr.c_str()) - 1;
|
||||
}
|
||||
|
||||
void gamemap::location::write(config& cfg) const
|
||||
{
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",x+1);
|
||||
cfg["x"] = buf;
|
||||
sprintf(buf,"%d",y+1);
|
||||
cfg["y"] = buf;
|
||||
}
|
||||
|
||||
bool gamemap::location::operator==(const gamemap::location& a) const
|
||||
{
|
||||
return x == a.x && y == a.y;
|
||||
|
@ -126,7 +136,7 @@ gamemap::gamemap(config& cfg, const std::string& data) : tiles_(1)
|
|||
if(letterToTerrain_.count(c) == 0) {
|
||||
if(isdigit(*i)) {
|
||||
startingPositions_[c - '0'] = location(x,y);
|
||||
c = CASTLE;
|
||||
c = KEEP;
|
||||
} else {
|
||||
std::cerr << "Illegal character in map: (" << int(c) << ") '" << c << "'\n";
|
||||
throw incorrect_format_exception("Illegal character");
|
||||
|
@ -190,6 +200,47 @@ const std::vector<gamemap::TERRAIN>& gamemap::operator[](int index) const
|
|||
return tiles_[index];
|
||||
}
|
||||
|
||||
gamemap::TERRAIN gamemap::get_terrain(const gamemap::location& loc) const
|
||||
{
|
||||
if(on_board(loc))
|
||||
return tiles_[loc.x][loc.y];
|
||||
|
||||
const std::map<location,TERRAIN>::const_iterator itor = borderCache_.find(loc);
|
||||
if(itor != borderCache_.end())
|
||||
return itor->second;
|
||||
|
||||
//if not on the board, decide based on what surrounding terrain is
|
||||
TERRAIN items[6];
|
||||
int nitems = 0;
|
||||
|
||||
location adj[6];
|
||||
get_adjacent_tiles(loc,adj);
|
||||
for(int n = 0; n != 6; ++n) {
|
||||
if(on_board(adj[n])) {
|
||||
items[nitems] = tiles_[adj[n].x][adj[n].y];
|
||||
++nitems;
|
||||
}
|
||||
}
|
||||
|
||||
//count all the terrain types found, and see which one
|
||||
//is the most common, and use it.
|
||||
TERRAIN used_terrain = 0;
|
||||
int terrain_count = 0;
|
||||
for(int i = 0; i != nitems; ++i) {
|
||||
if(items[i] != used_terrain) {
|
||||
const int c = std::count(items+i+1,items+nitems,items[i]) + 1;
|
||||
if(c > terrain_count) {
|
||||
used_terrain = items[i];
|
||||
terrain_count = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
borderCache_.insert(std::pair<location,TERRAIN>(loc,used_terrain));
|
||||
|
||||
return used_terrain;
|
||||
}
|
||||
|
||||
const gamemap::location& gamemap::starting_position(int n) const
|
||||
{
|
||||
return startingPositions_[n];
|
||||
|
|
14
src/map.hpp
|
@ -33,7 +33,7 @@ public:
|
|||
//in dynamically because they're special. It's asserted that there will
|
||||
//be corresponding entries for these types of terrain in the terrain
|
||||
//configuration file.
|
||||
enum { VOID_TERRAIN = ' ', CASTLE = 'C', TOWER = 't', FOREST = 'f' };
|
||||
enum { VOID_TERRAIN = ' ', KEEP = 'K', CASTLE = 'C', TOWER = 't', FOREST = 'f' };
|
||||
|
||||
//the name of the terrain is the terrain itself, the underlying terrain
|
||||
//is the name of the terrain for game-logic purposes. I.e. if the terrain
|
||||
|
@ -59,6 +59,8 @@ public:
|
|||
location(int x, int y) : x(x), y(y) {}
|
||||
location(const config& cfg);
|
||||
|
||||
void write(config& cfg) const;
|
||||
|
||||
bool valid() const { return x >= 0 && y >= 0; }
|
||||
|
||||
int x, y;
|
||||
|
@ -76,8 +78,7 @@ public:
|
|||
//data should be a series of lines, with each character representing
|
||||
//one hex on the map. Starting locations are represented by numbers,
|
||||
//and will be of type keep.
|
||||
gamemap(config& terrain_cfg,
|
||||
const std::string& data); //throw(incorrect_format_exception)
|
||||
gamemap(config& terrain_cfg, const std::string& data); //throw(incorrect_format_exception)
|
||||
|
||||
std::string write() const;
|
||||
|
||||
|
@ -88,6 +89,11 @@ public:
|
|||
//allows lookup of terrain at a particular location.
|
||||
const std::vector<TERRAIN>& operator[](int index) const;
|
||||
|
||||
//looks up terrain at a particular location. Hexes off the map
|
||||
//may be looked up, and their 'emulated' terrain will also be returned.
|
||||
//this allows proper drawing of the edges of the map
|
||||
TERRAIN get_terrain(const location& loc) const;
|
||||
|
||||
//functions to manipulate starting positions of the different sides.
|
||||
const location& starting_position(int side) const;
|
||||
int num_starting_positions() const;
|
||||
|
@ -129,6 +135,8 @@ private:
|
|||
std::vector<std::vector<TERRAIN> > tiles_;
|
||||
std::vector<location> towers_;
|
||||
location startingPositions_[10];
|
||||
|
||||
mutable std::map<location,TERRAIN> borderCache_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
743
src/mapgen.cpp
Normal file
|
@ -0,0 +1,743 @@
|
|||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
|
||||
#include "mapgen.hpp"
|
||||
#include "pathfind.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
//function to generate a random map, from a string which describes
|
||||
//the generator to use and its arguments
|
||||
std::string random_generate_map(const std::string& parms)
|
||||
{
|
||||
//the first token is the name of the generator, tokens after
|
||||
//that are arguments to the generator
|
||||
std::vector<std::string> parameters = config::split(parms,' ');
|
||||
map_generator* const generator = get_map_generator(parameters.front());
|
||||
if(generator == NULL) {
|
||||
std::cerr << "could not find map generator '" << parameters.front() << "'\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
parameters.erase(parameters.begin());
|
||||
return generator->create_map(parameters);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::vector<std::vector<int> > height_map;
|
||||
typedef std::vector<std::vector<char> > terrain_map;
|
||||
|
||||
//see http://216.239.39.104/search?q=cache:H2MSHn0AwBIJ:www.cosc.brocku.ca/Offerings/4V98/seminars/Terrain.ppt+height+map+algorithms&hl=en&ie=UTF-8 under
|
||||
//'Hill Algorithm' for a description of this algorithm
|
||||
//basically we generate alot of hills, each hill being centered at a certain point, with a certain radius - being a half sphere.
|
||||
//Hills are combined additively to form a bumpy surface
|
||||
//The size of each hill varies randomly from 1-hill_size.
|
||||
//we generate 'iterations' hills in total.
|
||||
//the range of heights is normalized to 0-1000
|
||||
height_map generate_height_map(size_t width, size_t height,
|
||||
size_t iterations, size_t hill_size)
|
||||
{
|
||||
height_map res(width,std::vector<int>(height,0));
|
||||
|
||||
for(size_t i = 0; i != iterations; ++i) {
|
||||
|
||||
//(x1,y1) is the location of the hill, and 'radius' is the radius of the hill.
|
||||
//we iterate over all points, (x2,y2). The formula for the amount the height
|
||||
//is increased by is radius - sqrt((x2-x1)^2 + (y2-y1)^2) with negative values
|
||||
//ignored.
|
||||
//
|
||||
//rather than iterate over every single point, we can reduce the points to
|
||||
//a rectangle that contains all the positive values for this formula --
|
||||
//the rectangle is given by min_x,max_x,min_y,max_y
|
||||
|
||||
const int x1 = int(rand()%width);
|
||||
const int y1 = int(rand()%height);
|
||||
const int radius = rand()%hill_size + 1;
|
||||
|
||||
const int min_x = x1 - radius > 0 ? x1 - radius : 0;
|
||||
const int max_x = x1 + radius < res.size() ? x1 + radius : res.size();
|
||||
const int min_y = y1 - radius > 0 ? y1 - radius : 0;
|
||||
const int max_y = y1 + radius < res.front().size() ? y1 + radius : res.front().size();
|
||||
|
||||
for(int x2 = min_x; size_t(x2) != max_x; ++x2) {
|
||||
for(int y2 = min_y; size_t(y2) != max_y; ++y2) {
|
||||
const int xdiff = (x2-x1);
|
||||
const int ydiff = (y2-y1);
|
||||
const int height = radius - int(sqrt(double(xdiff*xdiff + ydiff*ydiff)));
|
||||
if(height > 0) {
|
||||
res[x2][y2] += height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//find the heighest and lowest points on the map for normalization
|
||||
int heighest = 0, lowest = 100000, x;
|
||||
for(x = 0; size_t(x) != res.size(); ++x) {
|
||||
for(int y = 0; size_t(y) != res[x].size(); ++y) {
|
||||
if(res[x][y] > heighest)
|
||||
heighest = res[x][y];
|
||||
|
||||
if(res[x][y] < lowest)
|
||||
lowest = res[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
//normalize the heights to the range 0-1000
|
||||
heighest -= lowest;
|
||||
for(x = 0; size_t(x) != res.size(); ++x) {
|
||||
for(int y = 0; size_t(y) != res[x].size(); ++y) {
|
||||
res[x][y] -= lowest;
|
||||
res[x][y] *= 1000;
|
||||
if(heighest != 0)
|
||||
res[x][y] /= heighest;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//function to generate a lake. It will create water at (x,y), and then have
|
||||
//'lake_fall_off' % chance to make another water tile in each of the directions n,s,e,w.
|
||||
//In each of the directions it does make another water tile, it will have 'lake_fall_off'/2 %
|
||||
//chance to make another water tile in each of the directions. This will continue recursively.
|
||||
void generate_lake(terrain_map& terrain, int x, int y, int lake_fall_off)
|
||||
{
|
||||
if(x < 0 || y < 0 || size_t(x) >= terrain.size() || size_t(y) >= terrain.front().size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
terrain[x][y] = 'c';
|
||||
|
||||
if((rand()%100) < lake_fall_off) {
|
||||
generate_lake(terrain,x+1,y,lake_fall_off/2);
|
||||
}
|
||||
|
||||
if((rand()%100) < lake_fall_off) {
|
||||
generate_lake(terrain,x-1,y,lake_fall_off/2);
|
||||
}
|
||||
|
||||
if((rand()%100) < lake_fall_off) {
|
||||
generate_lake(terrain,x,y+1,lake_fall_off/2);
|
||||
}
|
||||
|
||||
if((rand()%100) < lake_fall_off) {
|
||||
generate_lake(terrain,x,y-1,lake_fall_off/2);
|
||||
}
|
||||
}
|
||||
|
||||
typedef gamemap::location location;
|
||||
|
||||
//river generation:
|
||||
//rivers have a source, and then keep on flowing until they meet another body of water,
|
||||
//which they flow into, or until they reach the edge of the map. Rivers will always flow
|
||||
//downhill, except that they can flow a maximum of 'river_uphill' uphill - this is to
|
||||
//represent the water eroding the higher ground lower.
|
||||
//
|
||||
//Every possible path for a river will be attempted, in random order, and the first river
|
||||
//path that can be found that makes the river flow into another body of water or off the map
|
||||
//will be used. If no path can be found, then the river's generation will be aborted, and
|
||||
//false will be returned. true is returned if the river is generated successfully.
|
||||
bool generate_river_internal(const height_map& heights, terrain_map& terrain, int x, int y, std::vector<location>& river, std::set<location>& seen_locations, int river_uphill)
|
||||
{
|
||||
const bool on_map = x >= 0 && y >= 0 && x < heights.size() && y < heights.back().size();
|
||||
|
||||
if(on_map && !river.empty() && heights[x][y] > heights[river.back().x][river.back().y] + river_uphill) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if we're at the end of the river
|
||||
if(!on_map || terrain[x][y] == 'c' || terrain[x][y] == 's') {
|
||||
std::cerr << "generating river...\n";
|
||||
|
||||
//generate the river
|
||||
for(std::vector<location>::const_iterator i = river.begin();
|
||||
i != river.end(); ++i) {
|
||||
terrain[i->x][i->y] = 'c';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
location current_loc(x,y);
|
||||
location adj[6];
|
||||
get_adjacent_tiles(current_loc,adj);
|
||||
static int items[6] = {0,1,2,3,4,5};
|
||||
std::random_shuffle(items,items+4);
|
||||
|
||||
//mark that we have attempted from this location
|
||||
seen_locations.insert(current_loc);
|
||||
river.push_back(current_loc);
|
||||
for(int a = 0; a != 6; ++a) {
|
||||
const location& loc = adj[items[a]];
|
||||
if(seen_locations.count(loc) == 0) {
|
||||
const bool res = generate_river_internal(heights,terrain,loc.x,loc.y,river,seen_locations,river_uphill);
|
||||
if(res) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
river.pop_back();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void generate_river(const height_map& heights, terrain_map& terrain, int x, int y, int river_uphill)
|
||||
{
|
||||
std::vector<location> river;
|
||||
std::set<location> seen_locations;
|
||||
generate_river_internal(heights,terrain,x,y,river,seen_locations,river_uphill);
|
||||
}
|
||||
|
||||
//function to return a random tile at one of the borders of a map that is
|
||||
//of the given dimensions.
|
||||
location point_at_side(size_t width, size_t height)
|
||||
{
|
||||
const int side = rand()%4;
|
||||
if(side < 2) {
|
||||
const int x = rand()%width;
|
||||
const int y = side == 0 ? 0 : height-1;
|
||||
return location(x,y);
|
||||
} else {
|
||||
const int y = rand()%height;
|
||||
const int x = side == 2 ? 0 : width-1;
|
||||
return location(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
//function which, given the map will output it in a valid format.
|
||||
std::string output_map(const terrain_map& terrain)
|
||||
{
|
||||
std::stringstream res;
|
||||
|
||||
//remember that we only want the middle 1/9th of the map. All other
|
||||
//segments of the map are there only to give the important middle part
|
||||
//some context.
|
||||
const size_t begin_x = terrain.size()/3;
|
||||
const size_t end_x = begin_x*2;
|
||||
const size_t begin_y = terrain.front().size()/3;
|
||||
const size_t end_y = begin_y*2;
|
||||
|
||||
for(size_t y = begin_y; y != end_y; ++y) {
|
||||
for(size_t x = begin_x; x != end_x; ++x) {
|
||||
res << terrain[x][y];
|
||||
}
|
||||
|
||||
res << "\n";
|
||||
}
|
||||
|
||||
return res.str();
|
||||
}
|
||||
|
||||
//an object that will calculate the cost of building a road over terrain
|
||||
//for use in the a_star_search algorithm.
|
||||
struct road_path_calculator
|
||||
{
|
||||
road_path_calculator(const terrain_map& terrain, const config& cfg)
|
||||
: map_(terrain), cfg_(cfg),
|
||||
|
||||
//find out how windy roads should be.
|
||||
windiness_(maximum<int>(1,atoi(cfg["road_windiness"].c_str()))) {}
|
||||
double cost(const location& loc, double so_far) const;
|
||||
private:
|
||||
const terrain_map& map_;
|
||||
const config& cfg_;
|
||||
int windiness_;
|
||||
mutable std::map<char,double> cache_;
|
||||
};
|
||||
|
||||
double road_path_calculator::cost(const location& loc, double so_far) const
|
||||
{
|
||||
if(loc.x < 0 || loc.y < 0 || loc.x >= map_.size() || loc.y >= map_.front().size())
|
||||
return 100000.0;
|
||||
|
||||
//we multiply the cost by a random amount depending upon how 'windy' the road should
|
||||
//be. If windiness is 1, that will mean that the cost is always genuine, and so
|
||||
//the road always takes the shortest path. If windiness is greater than 1, we sometimes
|
||||
//over-report costs for some segments, to make the road wind a little.
|
||||
const double windiness = (double(rand()%windiness_) + 1.0);
|
||||
|
||||
const char c = map_[loc.x][loc.y];
|
||||
const std::map<char,double>::const_iterator itor = cache_.find(c);
|
||||
if(itor != cache_.end())
|
||||
return itor->second*windiness;
|
||||
|
||||
static std::string terrain(1,'x');
|
||||
terrain[0] = c;
|
||||
|
||||
const config* const child = cfg_.find_child("road_cost","terrain",terrain);
|
||||
double res = 100000.0;
|
||||
if(child != NULL) {
|
||||
res = double(atoi((*child)["cost"].c_str()));
|
||||
}
|
||||
|
||||
cache_.insert(std::pair<char,double>(c,res));
|
||||
return windiness*res;
|
||||
}
|
||||
|
||||
//function to generate the map.
|
||||
std::string generate_map(size_t width, size_t height,
|
||||
size_t iterations, size_t hill_size,
|
||||
size_t max_lakes, size_t nvillages, size_t nplayers,
|
||||
const config& cfg)
|
||||
{
|
||||
//find out what the 'flatland' on this map is. i.e. grassland.
|
||||
std::string flatland = cfg["default_flatland"];
|
||||
if(flatland == "") {
|
||||
flatland = "g";
|
||||
}
|
||||
|
||||
const char grassland = flatland[0];
|
||||
|
||||
//we want to generate a map that is 9 times bigger than the
|
||||
//actual size desired. Only the middle part of the map will be
|
||||
//used, but the rest is so that the map we end up using can
|
||||
//have a context (e.g. rivers flowing from out of the map into
|
||||
//the map, same for roads, etc etc)
|
||||
width *= 3;
|
||||
height *= 3;
|
||||
|
||||
//generate the height of everything.
|
||||
const height_map heights = generate_height_map(width,height,iterations,hill_size);
|
||||
|
||||
//the configuration file should contain a number of [height] tags:
|
||||
//[height]
|
||||
//height=n
|
||||
//terrain=x
|
||||
//[/height]
|
||||
//these should be in descending order of n. They are checked sequentially, and if
|
||||
//height is greater than n for that tile, then the tile is set to terrain type x.
|
||||
terrain_map terrain(width,std::vector<char>(height,grassland));
|
||||
size_t x, y;
|
||||
for(x = 0; x != heights.size(); ++x) {
|
||||
for(y = 0; y != heights[x].size(); ++y) {
|
||||
const int val = heights[x][y];
|
||||
const config::child_list& items = cfg.get_children("height");
|
||||
for(config::child_list::const_iterator i = items.begin(); i != items.end(); ++i) {
|
||||
const int height = atoi((**i)["height"].c_str());
|
||||
if(val >= height) {
|
||||
const std::string& c = (**i)["terrain"];
|
||||
terrain[x][y] = c.empty() ? 'g' : c[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now that we have our basic set of flatland/hills/mountains/water, we can place lakes
|
||||
//and rivers on the map. All rivers are sourced at a lake. Lakes must be in high land -
|
||||
//at least 'min_lake_height'. (Note that terrain below a certain altitude may be made
|
||||
//into bodies of water in the code above - i.e. 'sea', but these are not considered 'lakes' because
|
||||
//they are not sources of rivers).
|
||||
//
|
||||
//we attempt to place 'max_lakes' lakes. Each lake will be placed at a random location,
|
||||
//if that random location meets the minimum terrain requirements for a lake.
|
||||
//We will also attempt to source a river from each lake.
|
||||
const int nlakes = max_lakes > 0 ? (rand()%max_lakes) : 0;
|
||||
for(size_t lake = 0; lake != nlakes; ++lake) {
|
||||
for(int tries = 0; tries != 100; ++tries) {
|
||||
const int x = rand()%width;
|
||||
const int y = rand()%height;
|
||||
if(heights[x][y] > atoi(cfg["min_lake_height"].c_str())) {
|
||||
generate_river(heights,terrain,x,y,atoi(cfg["river_frequency"].c_str()));
|
||||
generate_lake(terrain,x,y,atoi(cfg["lake_size"].c_str()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//convert grassland terrain to other types of flat terrain.
|
||||
//we generate a 'temperature map' which uses the height generation algorithm to
|
||||
//generate the temperature levels all over the map. Then we can use a combination
|
||||
//of height and terrain to divide flatland up into more interesting types than the default
|
||||
const height_map temperature_map = generate_height_map(width,height,
|
||||
atoi(cfg["temperature_iterations"].c_str()),
|
||||
atoi(cfg["temperature_size"].c_str()));
|
||||
|
||||
//iterate over every flatland tile, and determine what type of flatland it is,
|
||||
//based on our [flatland] tags.
|
||||
for(x = 0; x != width; ++x) {
|
||||
for(y = 0; y != width; ++y) {
|
||||
if(terrain[x][y] != grassland)
|
||||
continue;
|
||||
|
||||
const int temperature = temperature_map[x][y];
|
||||
const int height = heights[x][y];
|
||||
|
||||
//iterate over our list of [flatland] tags. Each tag specifies ranges
|
||||
//for temperature and height, and if that range is met, then the terrain
|
||||
//becomes the type specified. For instance, a tag to put snow in
|
||||
//high areas with low temperature would look like:
|
||||
//[flatland]
|
||||
//max_temp=200
|
||||
//min_height=600
|
||||
//[/flatland]
|
||||
const config::child_list& items = cfg.get_children("flatland");
|
||||
for(config::child_list::const_iterator i = items.begin(); i != items.end(); ++i) {
|
||||
const std::string& min_temp = (**i)["min_temperature"];
|
||||
const std::string& max_temp = (**i)["max_temperature"];
|
||||
const std::string& min_height = (**i)["min_height"];
|
||||
const std::string& max_height = (**i)["max_height"];
|
||||
|
||||
if(min_temp.empty() == false && atoi(min_temp.c_str()) > temperature)
|
||||
continue;
|
||||
|
||||
if(max_temp.empty() == false && atoi(max_temp.c_str()) < temperature)
|
||||
continue;
|
||||
|
||||
if(min_height.empty() == false && atoi(min_height.c_str()) > height)
|
||||
continue;
|
||||
|
||||
if(max_height.empty() == false && atoi(max_height.c_str()) < height)
|
||||
continue;
|
||||
|
||||
//we are in the right range, so set the terrain and go
|
||||
//on to the next tile.
|
||||
const std::string& set_to = (**i)["terrain"];
|
||||
if(set_to.empty() == false)
|
||||
terrain[x][y] = set_to[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//place roads. We select two tiles at random locations on the borders of the map,
|
||||
//and try to build roads between them.
|
||||
const size_t nroads = atoi(cfg["roads"].c_str());
|
||||
for(size_t road = 0; road != nroads; ++road) {
|
||||
|
||||
//we want the locations to be on the portion of the map we're actually going
|
||||
//to use, since roads on other parts of the map won't have any influence,
|
||||
//and doing it like this will be quicker.
|
||||
location src = point_at_side(width/3 + 2,height/3 + 2);
|
||||
location dst = point_at_side(width/3 + 2,height/3 + 2);
|
||||
src.x += width/3 - 1;
|
||||
src.y += height/3 - 1;
|
||||
dst.x += width/3 - 1;
|
||||
dst.y += height/3 - 1;
|
||||
|
||||
//if the road isn't very interesting (on the same border), don't draw it
|
||||
if(src.x == dst.x || src.y == dst.y) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const road_path_calculator calc(terrain,cfg);
|
||||
if(calc.cost(src,0.0) >= 1000.0 || calc.cost(dst,0.0) >= 1000.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//search a path out for the road
|
||||
const paths::route rt = a_star_search(src,dst,1000.0,calc);
|
||||
|
||||
//draw the road. If the search failed, rt.steps will simply be empty
|
||||
for(std::vector<location>::const_iterator step = rt.steps.begin(); step != rt.steps.end(); ++step) {
|
||||
const int x = step->x;
|
||||
const int y = step->y;
|
||||
|
||||
if(x < 0 || y < 0 || x >= width || y >= height)
|
||||
continue;
|
||||
|
||||
//find the configuration which tells us what to convert this tile to
|
||||
//to make it into a road.
|
||||
const std::string str(1,terrain[x][y]);
|
||||
const config* const child = cfg.find_child("road_cost","terrain",str);
|
||||
if(child != NULL) {
|
||||
//convert to bridge means that we want to convert depending
|
||||
//upon the direction the road is going.
|
||||
//typically it will be in a format like,
|
||||
//convert_to_bridge=|,/,\
|
||||
// '|' will be used if the road is going north-south
|
||||
// '/' will be used if the road is going south west-north east
|
||||
// '\' will be used if the road is going south east-north west
|
||||
//the terrain will be left unchanged otherwise (if there is no clear
|
||||
//direction)
|
||||
const std::string& convert_to_bridge = (*child)["convert_to_bridge"];
|
||||
if(convert_to_bridge.empty() == false) {
|
||||
if(step == rt.steps.begin() || step+1 == rt.steps.end())
|
||||
continue;
|
||||
|
||||
const location& last = *(step-1);
|
||||
const location& next = *(step+1);
|
||||
|
||||
location adj[6];
|
||||
get_adjacent_tiles(*step,adj);
|
||||
|
||||
size_t direction = 0;
|
||||
|
||||
//if we are going north-south
|
||||
if(last == adj[0] && next == adj[3] || last == adj[3] && next == adj[0]) {
|
||||
direction = 0;
|
||||
}
|
||||
|
||||
//if we are going south west-north east
|
||||
else if(last == adj[1] && next == adj[4] || last == adj[4] && next == adj[1]) {
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
//if we are going south east-north west
|
||||
else if(last == adj[2] && next == adj[5] || last == adj[5] && next == adj[2]) {
|
||||
direction = 2;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<std::string> items = config::split(convert_to_bridge);
|
||||
if(direction < items.size() && items[direction].empty() == false) {
|
||||
terrain[x][y] = items[direction][0];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//just a plain terrain substitution for a road
|
||||
const std::string& convert_to = (*child)["convert_to"];
|
||||
if(convert_to.empty() == false)
|
||||
terrain[x][y] = convert_to[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//place villages. We attempt to place nvillages, all at random locations.
|
||||
//After a location is chosen, we can through [village] tags to see
|
||||
//what kind of village we should place on that type of terrain. If no
|
||||
//[village] tag is found for the terrain type (e.g. deep water) no village
|
||||
//will be placed.
|
||||
std::set<location> villages;
|
||||
for(size_t village = 0; village != nvillages; ++village) {
|
||||
const int x = rand()%height;
|
||||
const int y = rand()%width;
|
||||
const std::string str(1,terrain[x][y]);
|
||||
const config* const child = cfg.find_child("village","terrain",str);
|
||||
if(child != NULL) {
|
||||
const std::string& convert_to = (*child)["convert_to"];
|
||||
if(convert_to.empty() == false)
|
||||
terrain[x][y] = convert_to[0];
|
||||
}
|
||||
}
|
||||
|
||||
//try to find configuration for castles.
|
||||
const config* const castle_config = cfg.child("castle");
|
||||
if(castle_config == NULL) {
|
||||
std::cerr << "Could not find castle configuration\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
//castle configuration tag contains a 'valid_terrain' attribute which is a list of
|
||||
//terrains that the castle may appear on.
|
||||
const std::vector<std::string> castle_terrains = config::split((*castle_config)["valid_terrain"]);
|
||||
|
||||
//attempt to place castles at random. Once we have placed castles, we run a sanity
|
||||
//check to make sure that the castles are well-placed. If the castles are not well-placed,
|
||||
//we try again. Definition of 'well-placed' is if no two castles are closer than
|
||||
//'min_distance' hexes from each other, and the castles appear on a terrain listed
|
||||
//in 'valid_terrain'.
|
||||
int ntries = 0;
|
||||
bool placing_bad = true;
|
||||
while(placing_bad) {
|
||||
if(++ntries > 5000) {
|
||||
std::cerr << "could not sanely place castles. Aborting.\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::vector<location> castles;
|
||||
for(size_t player = 0; player != nplayers; ++player) {
|
||||
const int x = (rand()%(height/3)) + height/3;
|
||||
const int y = (rand()%(width/3)) + width/3;
|
||||
|
||||
castles.push_back(location(x,y));
|
||||
}
|
||||
|
||||
//make sure all castles are placed on valid terrain. Check the castle tile
|
||||
//itself, and all surrounding tiles
|
||||
placing_bad = false;
|
||||
std::vector<location>::const_iterator c;
|
||||
for(c = castles.begin(); c != castles.end(); ++c) {
|
||||
const int x = c->x;
|
||||
const int y = c->y;
|
||||
const char terrains[] = {terrain[x][y],terrain[x+1][y],terrain[x-1][y],
|
||||
terrain[x][y+1],terrain[x+1][y+1],terrain[x-1][y+1],
|
||||
terrain[x][y-1],terrain[x+1][y-1],terrain[x-1][y-1]};
|
||||
|
||||
for(int n = 0; n != sizeof(terrains)/sizeof(*terrains); ++n) {
|
||||
const std::string t(1,terrains[n]);
|
||||
if(std::find(castle_terrains.begin(),castle_terrains.end(),t) == castle_terrains.end()) {
|
||||
placing_bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(placing_bad) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(placing_bad)
|
||||
continue;
|
||||
|
||||
//make sure all castles are a minimum distance away from each other
|
||||
const int min_distance = atoi((*castle_config)["min_distance"].c_str());
|
||||
for(std::vector<location>::const_iterator c1 = castles.begin(); c1 != castles.end(); ++c1) {
|
||||
for(std::vector<location>::const_iterator c2 = c1+1; c2 != castles.end(); ++c2) {
|
||||
if(distance_between(*c1,*c2) < min_distance) {
|
||||
placing_bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(placing_bad)
|
||||
continue;
|
||||
|
||||
//plonk down the castles.
|
||||
for(c = castles.begin(); c != castles.end(); ++c) {
|
||||
const int x = c->x;
|
||||
const int y = c->y;
|
||||
const int player = c - castles.begin();
|
||||
terrain[x][y] = '1' + player;
|
||||
terrain[x-1][y] = 'C';
|
||||
terrain[x+1][y] = 'C';
|
||||
terrain[x][y-1] = 'C';
|
||||
terrain[x][y+1] = 'C';
|
||||
terrain[x-1][y-1] = 'C';
|
||||
terrain[x-1][y+1] = 'C';
|
||||
terrain[x+1][y-1] = 'C';
|
||||
terrain[x+1][y+1] = 'C';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return output_map(terrain);
|
||||
}
|
||||
|
||||
typedef std::map<std::string,map_generator*> generator_map;
|
||||
generator_map generators;
|
||||
|
||||
}
|
||||
|
||||
map_generator::manager::manager(const config& game_config)
|
||||
{
|
||||
map_generator* const gen = new default_map_generator(game_config);
|
||||
assert(generators.count(gen->name()) == 0);
|
||||
generators[gen->name()] = gen;
|
||||
}
|
||||
|
||||
map_generator::manager::~manager()
|
||||
{
|
||||
for(generator_map::iterator i = generators.begin(); i != generators.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
|
||||
generators.clear();
|
||||
}
|
||||
|
||||
map_generator* get_map_generator(const std::string& name)
|
||||
{
|
||||
const generator_map::iterator i = generators.find(name);
|
||||
if(i != generators.end())
|
||||
return i->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
default_map_generator::default_map_generator(const config& game_config)
|
||||
: width_(40), height_(40), iterations_(1000), hill_size_(10), max_lakes_(20),
|
||||
nvillages_(300), nplayers_(2), cfg_(NULL)
|
||||
{
|
||||
const config* const cfg = game_config.find_child("map_generator","name",name());
|
||||
if(cfg != NULL) {
|
||||
cfg_ = cfg;
|
||||
|
||||
const int width = ::atoi((*cfg)["width"].c_str());
|
||||
if(width > 0)
|
||||
width_ = width;
|
||||
|
||||
const int height = ::atoi((*cfg)["height"].c_str());
|
||||
if(height > 0)
|
||||
height_ = height;
|
||||
|
||||
const int iterations = ::atoi((*cfg)["iterations"].c_str());
|
||||
if(iterations > 0)
|
||||
iterations_ = iterations;
|
||||
|
||||
const int hill_size = ::atoi((*cfg)["hill_size"].c_str());
|
||||
if(hill_size > 0)
|
||||
hill_size_ = hill_size;
|
||||
|
||||
const int max_lakes = ::atoi((*cfg)["max_lakes"].c_str());
|
||||
if(max_lakes > 0)
|
||||
max_lakes_ = max_lakes;
|
||||
|
||||
const int nvillages = ::atoi((*cfg)["villages"].c_str());
|
||||
if(nvillages > 0)
|
||||
nvillages_ = nvillages;
|
||||
|
||||
const int nplayers = ::atoi((*cfg)["players"].c_str());
|
||||
if(nplayers > 0)
|
||||
nplayers_ = nplayers;
|
||||
}
|
||||
}
|
||||
|
||||
bool default_map_generator::allow_user_config() const { return false; }
|
||||
|
||||
void default_map_generator::user_config(display& disp) {}
|
||||
|
||||
std::string default_map_generator::name() const { return "default"; }
|
||||
|
||||
std::string default_map_generator::create_map(const std::vector<std::string>& args) const
|
||||
{
|
||||
if(cfg_ != NULL)
|
||||
return generate_map(width_,height_,iterations_,hill_size_,max_lakes_,nvillages_,nplayers_,*cfg_);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef TEST_MAPGEN
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int x = 50, y = 50, iterations = 50, hill_size = 50, lakes=3,
|
||||
nvillages = 500, nplayers = 2;
|
||||
if(argc >= 2) {
|
||||
x = atoi(argv[1]);
|
||||
}
|
||||
|
||||
if(argc >= 3) {
|
||||
y = atoi(argv[2]);
|
||||
}
|
||||
|
||||
if(argc >= 4) {
|
||||
iterations = atoi(argv[3]);
|
||||
}
|
||||
|
||||
if(argc >= 5) {
|
||||
hill_size = atoi(argv[4]);
|
||||
}
|
||||
|
||||
if(argc >= 6) {
|
||||
lakes = atoi(argv[5]);
|
||||
}
|
||||
|
||||
if(argc >= 7) {
|
||||
nvillages = atoi(argv[6]);
|
||||
}
|
||||
|
||||
if(argc >= 8) {
|
||||
nplayers = atoi(argv[7]);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
std::cout << generate_map(x,y,iterations,hill_size,lakes,nvillages,nplayers) << "\n";
|
||||
}
|
||||
|
||||
#endif
|
58
src/mapgen.hpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#ifndef MAP_GEN_HPP_INCLUDED
|
||||
#define MAP_GEN_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "display.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string random_generate_map(const std::string& parms);
|
||||
|
||||
class map_generator
|
||||
{
|
||||
public:
|
||||
|
||||
//returns true iff the map generator has an interactive screen
|
||||
//which allows the user to modify how the generator behaves
|
||||
virtual bool allow_user_config() const = 0;
|
||||
|
||||
//display the interactive screen which allows the user to
|
||||
//modify how the generator behaves. (This function will not
|
||||
//be called if allow_user_config() returns false)
|
||||
virtual void user_config(display& disp) = 0;
|
||||
|
||||
//returns a string identifying the generator by name. The name should
|
||||
//not contain spaces.
|
||||
virtual std::string name() const = 0;
|
||||
|
||||
//creates a new map and returns it. args may contain arguments to
|
||||
//the map generator
|
||||
virtual std::string create_map(const std::vector<std::string>& args) const = 0;
|
||||
|
||||
struct manager
|
||||
{
|
||||
manager(const config& game_config);
|
||||
~manager();
|
||||
};
|
||||
};
|
||||
|
||||
map_generator* get_map_generator(const std::string& name);
|
||||
|
||||
class default_map_generator : public map_generator
|
||||
{
|
||||
public:
|
||||
default_map_generator(const config& game_config);
|
||||
|
||||
bool allow_user_config() const;
|
||||
void user_config(display& disp);
|
||||
|
||||
std::string name() const;
|
||||
|
||||
std::string create_map(const std::vector<std::string>& args) const;
|
||||
|
||||
private:
|
||||
size_t width_, height_, iterations_, hill_size_, max_lakes_, nvillages_, nplayers_;
|
||||
const config* cfg_;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,6 +16,7 @@
|
|||
#include "language.hpp"
|
||||
#include "log.hpp"
|
||||
#include "image.hpp"
|
||||
#include "mapgen.hpp"
|
||||
#include "multiplayer.hpp"
|
||||
#include "multiplayer_client.hpp"
|
||||
#include "network.hpp"
|
||||
|
@ -286,7 +287,7 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
|
||||
string_table["name_of_game"] + ":",(disp.x()-width)/2+10,(disp.y()-height)/2+38);
|
||||
gui::textbox name_entry(disp,width-20,string_table["game_prefix"] + preferences::login() + string_table["game_postfix"]);
|
||||
name_entry.set_location((disp.x()-width)/2+10,(disp.y()-height)/2+55);
|
||||
name_entry.set_position((disp.x()-width)/2+10,(disp.y()-height)/2+55);
|
||||
|
||||
//Maps
|
||||
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
|
||||
|
@ -317,9 +318,9 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
rect.h = 12;
|
||||
SDL_Surface* village_bg=get_surface_portion(disp.video().getSurface(), rect);
|
||||
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
|
||||
"Turns: 50",rect.x,rect.y);
|
||||
string_table["turns"] + ": 50",rect.x,rect.y);
|
||||
rect.y = (disp.y()-height)/2+100;
|
||||
rect.h = name_entry.width();
|
||||
rect.h = name_entry.location().w;
|
||||
|
||||
gui::slider turns_slider(disp,rect,0.38);
|
||||
|
||||
|
@ -329,9 +330,9 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
rect.w = ((disp.x()-width)/2+width)-((disp.x()-width)/2+(int)(width*0.4)+maps_menu.width()+19)-10;
|
||||
rect.h = 12;
|
||||
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
|
||||
"Village Gold: 1",rect.x,rect.y);
|
||||
string_table["village_gold"] + ": 1",rect.x,rect.y);
|
||||
rect.y = (disp.y()-height)/2+147;
|
||||
rect.h = name_entry.width();
|
||||
rect.h = name_entry.location().w;
|
||||
gui::slider villagegold_slider(disp,rect,0.0);
|
||||
|
||||
//FOG of war
|
||||
|
@ -403,15 +404,12 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
load_game(units_data,game,state);
|
||||
|
||||
if(state.campaign_type != "multiplayer") {
|
||||
gui::show_dialog(disp,NULL,"",
|
||||
"This is not a multiplayer save",gui::OK_ONLY);
|
||||
gui::show_dialog(disp,NULL,"",string_table["not_multiplayer_save_message"],gui::OK_ONLY);
|
||||
break;
|
||||
}
|
||||
|
||||
if(state.version != game_config::version) {
|
||||
const int res = gui::show_dialog(disp,NULL,"",
|
||||
string_table["version_save_message"],
|
||||
gui::YES_NO);
|
||||
const int res = gui::show_dialog(disp,NULL,"",string_table["version_save_message"],gui::YES_NO);
|
||||
if(res == 1)
|
||||
break;
|
||||
}
|
||||
|
@ -430,6 +428,10 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
|
||||
recorder = replay(state.replay_data);
|
||||
|
||||
//if this is a snapshot save, we don't want to use the replay data
|
||||
if(loaded_level["snapshot"] == "yes")
|
||||
recorder.set_to_end();
|
||||
|
||||
//add the replay data under the level data so clients can
|
||||
//receive it
|
||||
level_ptr->clear_children("replay");
|
||||
|
@ -791,7 +793,9 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
fog_game.process(mousex,mousey,left_button);
|
||||
shroud_game.process(mousex,mousey,left_button);
|
||||
observers_game.process(mousex,mousey,left_button);
|
||||
name_entry.process();
|
||||
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
||||
//Game turns are 20 to 99
|
||||
//FIXME: Should never be a - number, but it is sometimes
|
||||
|
@ -839,6 +843,16 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
|
|||
map_data = read_file("data/maps/" + (*level_ptr)["map"]);
|
||||
}
|
||||
|
||||
//if the map should be randomly generated
|
||||
if(map_data == "" && (*level_ptr)["map_generation"] != "") {
|
||||
map_data = random_generate_map((*level_ptr)["map_generation"]);
|
||||
|
||||
//record the map data of the map, so that when we send to
|
||||
//remote clients, they will use the given map, and won't try
|
||||
//to generate their own.
|
||||
(*level_ptr)["map_data"] = map_data;
|
||||
}
|
||||
|
||||
gamemap map(cfg,map_data);
|
||||
|
||||
const scoped_sdl_surface mini(image::getMinimap(175,175,map));
|
||||
|
|
|
@ -97,7 +97,7 @@ RESULT enter(display& disp, config& game_data)
|
|||
join_game.set_xy(19,545);
|
||||
new_game.set_xy(19+join_game.width()+5,545);
|
||||
quit_game.set_xy(19+join_game.width()+5+new_game.width()+5,545);
|
||||
message_entry.set_location(19,725);
|
||||
message_entry.set_position(19,725);
|
||||
message_entry.set_width(832);
|
||||
|
||||
update_whole_screen();
|
||||
|
@ -153,7 +153,8 @@ RESULT enter(display& disp, config& game_data)
|
|||
return QUIT;
|
||||
}
|
||||
|
||||
message_entry.process();
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
||||
config data;
|
||||
|
||||
|
|
|
@ -174,19 +174,20 @@ connection receive_data(config& cfg, connection connection_num, int timeout)
|
|||
|
||||
const int starting_ticks = SDL_GetTicks();
|
||||
|
||||
std::cerr << "checking sockets...\n";
|
||||
const int res = SDLNet_CheckSockets(socket_set,timeout);
|
||||
if(res <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(sockets_list::const_iterator i = sockets.begin();
|
||||
i != sockets.end(); ++i) {
|
||||
for(sockets_list::const_iterator i = sockets.begin(); i != sockets.end(); ++i) {
|
||||
if(SDLNet_SocketReady(*i)) {
|
||||
std::string buffer;
|
||||
|
||||
for(;;) {
|
||||
char c;
|
||||
const int len = SDLNet_TCP_Recv(*i,&c,1);
|
||||
|
||||
if(len == 0) {
|
||||
break;
|
||||
} else if(len < 0) {
|
||||
|
@ -248,8 +249,6 @@ void send_data(const config& cfg, connection connection_num)
|
|||
return;
|
||||
}
|
||||
|
||||
std::cerr << "a\n";
|
||||
|
||||
assert(connection_num != server_socket);
|
||||
|
||||
std::string value = cfg.write();
|
||||
|
@ -264,4 +263,15 @@ void send_data(const config& cfg, connection connection_num)
|
|||
}
|
||||
}
|
||||
|
||||
void send_data_all_except(const config& cfg, connection connection_num)
|
||||
{
|
||||
for(sockets_list::const_iterator i = sockets.begin(); i != sockets.end(); ++i) {
|
||||
if(*i == connection_num)
|
||||
continue;
|
||||
|
||||
assert(*i && *i != server_socket);
|
||||
send_data(cfg,*i);
|
||||
}
|
||||
}
|
||||
|
||||
} //end namespace network
|
||||
|
|
|
@ -74,6 +74,9 @@ connection receive_data(config& cfg, connection connection_num=0,
|
|||
//to all peers if connection_num is 0. throws error.
|
||||
void send_data(const config& cfg, connection connection_num=0);
|
||||
|
||||
//function to send data to all peers except 'connection_num'
|
||||
void send_data_all_except(const config& cfg, connection connection_num);
|
||||
|
||||
struct error
|
||||
{
|
||||
error(const std::string& msg, connection sock=0)
|
||||
|
|
|
@ -78,19 +78,19 @@ void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res)
|
|||
res->y = a.y-1;
|
||||
++res;
|
||||
res->x = a.x+1;
|
||||
res->y = a.y - is_even(a.x);
|
||||
res->y = a.y - (is_even(a.x) ? 1:0);
|
||||
++res;
|
||||
res->x = a.x+1;
|
||||
res->y = a.y + is_odd(a.x);
|
||||
res->y = a.y + (is_odd(a.x) ? 1:0);
|
||||
++res;
|
||||
res->x = a.x;
|
||||
res->y = a.y+1;
|
||||
++res;
|
||||
res->x = a.x-1;
|
||||
res->y = a.y + is_odd(a.x);
|
||||
res->y = a.y + (is_odd(a.x) ? 1:0);
|
||||
++res;
|
||||
res->x = a.x-1;
|
||||
res->y = a.y - is_even(a.x);
|
||||
res->y = a.y - (is_even(a.x) ? 1:0);
|
||||
}
|
||||
|
||||
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
|
||||
|
@ -102,7 +102,7 @@ bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
|
|||
const int xdiff = abs(a.x - b.x);
|
||||
const int ydiff = abs(a.y - b.y);
|
||||
return ydiff == 1 && a.x == b.x || xdiff == 1 && a.y == b.y ||
|
||||
xdiff == 1 && ydiff == 1 && (a.y > b.y ? (a.x%2) == 1 : (b.x%2) == 1);
|
||||
xdiff == 1 && ydiff == 1 && (a.y > b.y ? is_odd(a.x) : is_odd(b.x));
|
||||
}
|
||||
|
||||
size_t distance_between(const gamemap::location& a, const gamemap::location& b)
|
||||
|
|
|
@ -154,8 +154,10 @@ paths::route a_star_search(const gamemap::location& src,
|
|||
using namespace detail;
|
||||
typedef gamemap::location location;
|
||||
std::list<node> open_list, closed_list;
|
||||
std::map<location,double> lowest_f;
|
||||
|
||||
open_list.push_back(node(src,dst,0.0,NULL,teleports));
|
||||
lowest_f.insert(std::pair<location,double>(src,0.0));
|
||||
|
||||
while(!open_list.empty()) {
|
||||
|
||||
|
@ -206,24 +208,15 @@ paths::route a_star_search(const gamemap::location& src,
|
|||
const node nd(locs[j],dst,lowest->g+obj.cost(locs[j],lowest->g),
|
||||
&*lowest,teleports);
|
||||
|
||||
for(i = open_list.begin(); i != open_list.end(); ++i) {
|
||||
if(i->loc == nd.loc && i->f <= nd.f) {
|
||||
break;
|
||||
const std::map<location,double>::iterator current = lowest_f.find(nd.loc);
|
||||
if(current != lowest_f.end()) {
|
||||
if(current->second <= nd.f) {
|
||||
continue;
|
||||
} else {
|
||||
current->second = nd.f;
|
||||
}
|
||||
}
|
||||
|
||||
if(i != open_list.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i = closed_list.begin(); i != closed_list.end(); ++i) {
|
||||
if(i != lowest && i->loc == nd.loc && i->f <= nd.f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i != closed_list.end()) {
|
||||
continue;
|
||||
} else {
|
||||
lowest_f.insert(std::pair<location,double>(nd.loc,nd.f));
|
||||
}
|
||||
|
||||
open_list.push_back(nd);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "hotkeys.hpp"
|
||||
#include "intro.hpp"
|
||||
#include "language.hpp"
|
||||
#include "mapgen.hpp"
|
||||
#include "network.hpp"
|
||||
#include "playlevel.hpp"
|
||||
#include "playturn.hpp"
|
||||
|
@ -40,6 +41,11 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
map_data = read_file("data/maps/" + (*level)["map"]);
|
||||
}
|
||||
|
||||
//if the map should be randomly generated
|
||||
if(map_data == "" && (*level)["map_generation"] != "") {
|
||||
map_data = random_generate_map((*level)["map_generation"]);
|
||||
}
|
||||
|
||||
gamemap map(terrain_config,map_data);
|
||||
|
||||
CKey key;
|
||||
|
@ -51,17 +57,6 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
|
||||
const config::child_list& unit_cfg = level->get_children("side");
|
||||
for(config::child_list::const_iterator ui = unit_cfg.begin(); ui != unit_cfg.end(); ++ui) {
|
||||
unit new_unit(gameinfo, **ui);
|
||||
if(ui == unit_cfg.begin()) {
|
||||
for(std::vector<unit>::iterator it = state_of_game.available_units.begin();
|
||||
it != state_of_game.available_units.end(); ++it) {
|
||||
if(it->can_recruit()) {
|
||||
new_unit = *it;
|
||||
state_of_game.available_units.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string gold = (**ui)["gold"];
|
||||
if(gold.empty())
|
||||
|
@ -73,15 +68,33 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
ngold = state_of_game.gold;
|
||||
}
|
||||
|
||||
const gamemap::location& start_pos = map.starting_position(new_unit.side());
|
||||
//if this side tag describes the leader of the side
|
||||
if((**ui)["no_leader"] != "yes") {
|
||||
unit new_unit(gameinfo, **ui);
|
||||
|
||||
if(!start_pos.valid() && new_unit.side() == 1) {
|
||||
throw gamestatus::load_game_failed("No starting position for side 1");
|
||||
}
|
||||
//search the recall list for leader units, and if there is
|
||||
//one, use it in place of the config-described unit
|
||||
if(ui == unit_cfg.begin()) {
|
||||
for(std::vector<unit>::iterator it = state_of_game.available_units.begin();
|
||||
it != state_of_game.available_units.end(); ++it) {
|
||||
if(it->can_recruit()) {
|
||||
new_unit = *it;
|
||||
state_of_game.available_units.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(start_pos.valid()) {
|
||||
units.insert(std::pair<gamemap::location,unit>(
|
||||
map.starting_position(new_unit.side()), new_unit));
|
||||
const gamemap::location& start_pos = map.starting_position(new_unit.side());
|
||||
|
||||
if(!start_pos.valid() && new_unit.side() == 1) {
|
||||
throw gamestatus::load_game_failed("No starting position for side 1");
|
||||
}
|
||||
|
||||
if(start_pos.valid()) {
|
||||
units.insert(std::pair<gamemap::location,unit>(
|
||||
map.starting_position(new_unit.side()), new_unit));
|
||||
}
|
||||
}
|
||||
|
||||
teams.push_back(team(**ui,ngold));
|
||||
|
@ -110,10 +123,11 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
const std::string& y = (**su)["y"];
|
||||
|
||||
const gamemap::location loc(**su);
|
||||
if(x.size() == 0 || y.size() == 0 || !map.on_board(loc)) {
|
||||
if(x.empty() || y.empty() || !map.on_board(loc)) {
|
||||
state_of_game.available_units.push_back(new_unit);
|
||||
} else {
|
||||
units.insert(std::pair<gamemap::location,unit>(loc,new_unit));
|
||||
std::cerr << "inserting unit for side " << new_unit.side() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,18 +164,22 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
gui.add_overlay(gamemap::location(**overlay),(**overlay)["image"]);
|
||||
}
|
||||
|
||||
for(unit_map::iterator i = units.begin(); i != units.end(); ++i) {
|
||||
i->second.new_turn();
|
||||
}
|
||||
|
||||
gui.scroll_to_tile(map.starting_position(1).x,map.starting_position(1).y,
|
||||
display::WARP);
|
||||
|
||||
bool replaying = (recorder.empty() == false);
|
||||
|
||||
//if a team is specified whose turn it is, it means we're loading a game
|
||||
//instead of starting a fresh one
|
||||
const bool loading_game = (*level)["playing_team"].empty() == false;
|
||||
int first_player = atoi((*level)["playing_team"].c_str());
|
||||
if(first_player < 0 || first_player >= int(teams.size())) {
|
||||
first_player = 0;
|
||||
}
|
||||
|
||||
int turn = 1;
|
||||
std::cout << "starting main loop\n";
|
||||
for(bool first_time = true; true; first_time = false) {
|
||||
for(bool first_time = true; true; first_time = false, first_player = 0) {
|
||||
try {
|
||||
|
||||
if(first_time) {
|
||||
|
@ -178,7 +196,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
|
||||
std::cerr << "turn: " << turn++ << "\n";
|
||||
|
||||
for(std::vector<team>::iterator team_it = teams.begin();
|
||||
for(std::vector<team>::iterator team_it = teams.begin()+first_player;
|
||||
team_it != teams.end(); ++team_it) {
|
||||
const int player_number = (team_it - teams.begin()) + 1;
|
||||
|
||||
|
@ -186,13 +204,19 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
if(team_units(units,player_number) == 0)
|
||||
continue;
|
||||
|
||||
for(unit_map::iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if(i->second.side() == player_number) {
|
||||
i->second.new_turn();
|
||||
}
|
||||
}
|
||||
//we want to work out if units for this player should get healed, and the
|
||||
//player should get income now. healing/income happen if it's not the first
|
||||
//turn of processing, or if we are loading a game, and this is not the
|
||||
//player it started with.
|
||||
const bool turn_refresh = !first_time || loading_game && team_it != teams.begin()+first_player;
|
||||
|
||||
if(turn_refresh) {
|
||||
for(unit_map::iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if(i->second.side() == player_number) {
|
||||
i->second.new_turn();
|
||||
}
|
||||
}
|
||||
|
||||
if(!first_time) {
|
||||
team_it->new_turn();
|
||||
|
||||
//if the expense is less than the number of villages owned,
|
||||
|
@ -202,17 +226,16 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
if(expense > 0) {
|
||||
team_it->spend_gold(expense);
|
||||
}
|
||||
|
||||
calculate_healing(gui,map,units,player_number);
|
||||
}
|
||||
|
||||
gui.set_playing_team(size_t(player_number-1));
|
||||
|
||||
clear_shroud(gui,map,gameinfo,units,teams,player_number-1);
|
||||
|
||||
calculate_healing(gui,map,units,player_number);
|
||||
|
||||
//scroll the map to the leader
|
||||
const unit_map::iterator leader =
|
||||
find_leader(units,player_number);
|
||||
const unit_map::iterator leader = find_leader(units,player_number);
|
||||
|
||||
if(leader != units.end() && !recorder.skipping()) {
|
||||
const hotkey::basic_handler key_events_handler(gui);
|
||||
|
@ -295,10 +318,14 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
}
|
||||
|
||||
if(res && cfg.child("turn") != NULL) {
|
||||
//forward the data to other peers
|
||||
network::send_data_all_except(cfg,res);
|
||||
break;
|
||||
}
|
||||
|
||||
const int ncommand = recorder.ncommands();
|
||||
turn_data.turn_slice();
|
||||
turn_data.send_data(ncommand);
|
||||
gui.draw();
|
||||
}
|
||||
|
||||
|
@ -315,7 +342,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
gui::YES_NO,NULL,NULL,"",&output);
|
||||
if(res == 0 && output.empty() == false) {
|
||||
recorder.mark_current();
|
||||
recorder.save_game(gameinfo,output);
|
||||
config starting_pos;
|
||||
recorder.save_game(gameinfo,output,starting_pos);
|
||||
}
|
||||
|
||||
return QUIT;
|
||||
|
@ -437,7 +465,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
|||
gui::OK_CANCEL,NULL,NULL,
|
||||
string_table["save_game_label"],&label);
|
||||
if(res == 0) {
|
||||
recorder.save_game(gameinfo,label);
|
||||
config starting_pos;
|
||||
recorder.save_game(gameinfo,label,starting_pos);
|
||||
}
|
||||
|
||||
return QUIT;
|
||||
|
|
|
@ -616,6 +616,11 @@ void turn_info::show_menu()
|
|||
menu.push_back(create_unit_debug);
|
||||
}
|
||||
|
||||
const unit_map::iterator leader = find_leader(units_,gui_.viewing_team()+1);
|
||||
if(network::nconnections() > 0 && leader != units_.end()) {
|
||||
menu.push_back(string_table["speak"]);
|
||||
}
|
||||
|
||||
if(un != units_.end()) {
|
||||
menu.push_back(string_table["describe_unit"]);
|
||||
|
||||
|
@ -634,7 +639,26 @@ void turn_info::show_menu()
|
|||
menu.pop_back();
|
||||
}
|
||||
|
||||
if(result == create_unit_debug) {
|
||||
if(result == string_table["speak"]) {
|
||||
std::string message;
|
||||
const int res = gui::show_dialog(gui_,NULL,"",string_table["speak"],gui::OK_CANCEL,NULL,NULL,
|
||||
string_table["message"] + ":", &message);
|
||||
if(res == 0) {
|
||||
config cfg;
|
||||
cfg["description"] = leader->second.description();
|
||||
cfg["message"] = message;
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",leader->second.side());
|
||||
cfg["side"] = buf;
|
||||
|
||||
recorder.speak(cfg);
|
||||
dialogs::unit_speak(cfg,gui_,units_);
|
||||
|
||||
//speaking is an unretractable operation
|
||||
undo_stack_.clear();
|
||||
redo_stack_.clear();
|
||||
}
|
||||
} else if(result == create_unit_debug) {
|
||||
std::vector<std::string> options;
|
||||
std::vector<unit> unit_choices;
|
||||
for(game_data::unit_type_map::const_iterator i = gameinfo_.unit_types.begin();
|
||||
|
@ -669,7 +693,8 @@ void turn_info::show_menu()
|
|||
} else if(result == string_table["status_table"]) {
|
||||
status_table();
|
||||
} else if(result == string_table["unit_list"]) {
|
||||
const std::string heading = string_table["name"] + "," +
|
||||
const std::string heading = string_table["type"] + "," +
|
||||
string_table["name"] + "," +
|
||||
string_table["hp"] + "," +
|
||||
string_table["xp"] + "," +
|
||||
string_table["moves"] + "," +
|
||||
|
@ -685,7 +710,9 @@ void turn_info::show_menu()
|
|||
continue;
|
||||
|
||||
std::stringstream row;
|
||||
row << i->second.name() << "," << i->second.hitpoints()
|
||||
row << i->second.type().language_name() << ","
|
||||
<< i->second.description() << ","
|
||||
<< i->second.hitpoints()
|
||||
<< "/" << i->second.max_hitpoints() << ","
|
||||
<< i->second.experience() << "/";
|
||||
|
||||
|
@ -764,7 +791,9 @@ void turn_info::end_turn()
|
|||
return;
|
||||
|
||||
end_turn_ = true;
|
||||
recorder.save_game(gameinfo_,string_table["auto_save"]);
|
||||
config start_pos;
|
||||
write_game_snapshot(start_pos);
|
||||
recorder.save_game(gameinfo_,string_table["auto_save"],start_pos);
|
||||
recorder.end_turn();
|
||||
}
|
||||
|
||||
|
@ -1028,11 +1057,57 @@ void turn_info::save_game()
|
|||
const int res = dialogs::get_save_name(gui_,"",string_table["save_game_label"],&label,gui::OK_CANCEL);
|
||||
|
||||
if(res == 0) {
|
||||
recorder.save_game(gameinfo_,label);
|
||||
config start;
|
||||
write_game_snapshot(start);
|
||||
recorder.save_game(gameinfo_,label,start);
|
||||
gui::show_dialog(gui_,NULL,"",string_table["save_confirm_message"], gui::OK_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
void turn_info::write_game_snapshot(config& start) const
|
||||
{
|
||||
start["snapshot"] = "yes";
|
||||
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",gui_.playing_team());
|
||||
start["playing_team"] = buf;
|
||||
|
||||
for(std::vector<team>::const_iterator t = teams_.begin(); t != teams_.end(); ++t) {
|
||||
const int side_num = t - teams_.begin() + 1;
|
||||
|
||||
config& side = start.add_child("side");
|
||||
t->write(side);
|
||||
side["no_leader"] = "yes";
|
||||
sprintf(buf,"%d",side_num);
|
||||
side["side"] = buf;
|
||||
|
||||
for(std::map<gamemap::location,unit>::const_iterator i = units_.begin();
|
||||
i != units_.end(); ++i) {
|
||||
if(i->second.side() == side_num) {
|
||||
config& u = side.add_child("unit");
|
||||
i->first.write(u);
|
||||
i->second.write(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_.write(start);
|
||||
game_events::write_events(start);
|
||||
|
||||
write_game(state_of_game_,start);
|
||||
start["gold"] = "-1000000"; //just make sure gold is read in from the teams
|
||||
|
||||
//copy over important scenario stats
|
||||
start["id"] = (*level_)["id"];
|
||||
start["name"] = (*level_)["name"];
|
||||
start["objectives"] = (*level_)["objectives"];
|
||||
start["next_scenario"] = (*level_)["next_scenario"];
|
||||
start["music"] = (*level_)["music"];
|
||||
|
||||
//write out the current state of the map
|
||||
start["map_data"] = map_.write();
|
||||
}
|
||||
|
||||
void turn_info::toggle_grid()
|
||||
{
|
||||
preferences::set_grid(!preferences::grid());
|
||||
|
@ -1047,6 +1122,9 @@ void turn_info::status_table()
|
|||
<< string_table["units"] << "," << string_table["upkeep"] << ","
|
||||
<< string_table["income"];
|
||||
|
||||
if(game_config::debug)
|
||||
heading << "," << string_table["gold"];
|
||||
|
||||
items.push_back(heading.str());
|
||||
|
||||
//if the player is under shroud or fog, they don't get to see
|
||||
|
@ -1069,6 +1147,9 @@ void turn_info::status_table()
|
|||
<< data.units << "," << data.upkeep << ","
|
||||
<< (data.net_income < 0 ? "#":"") << data.net_income;
|
||||
|
||||
if(game_config::debug)
|
||||
str << "," << teams_[n].gold();
|
||||
|
||||
items.push_back(str.str());
|
||||
}
|
||||
|
||||
|
@ -1208,7 +1289,8 @@ void turn_info::recall()
|
|||
state_of_game_.available_units.begin();
|
||||
unit != state_of_game_.available_units.end(); ++unit) {
|
||||
std::stringstream option;
|
||||
option << unit->type().language_name() << ","
|
||||
const std::string& description = unit->description().empty() ? "-" : unit->description();
|
||||
option << unit->type().language_name() << "," << description << ","
|
||||
<< string_table["level"] << ": "
|
||||
<< unit->type().level() << ","
|
||||
<< string_table["xp"] << ": "
|
||||
|
|
|
@ -71,6 +71,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void write_game_snapshot(config& cfg) const;
|
||||
|
||||
void cycle_units();
|
||||
void end_turn();
|
||||
void goto_leader();
|
||||
|
|
|
@ -359,9 +359,10 @@ void show_preferences_dialog(display& disp)
|
|||
const int height = 400;
|
||||
|
||||
//make sure that the frame buffer is restored to its original state
|
||||
//when the dialog closes
|
||||
//when the dialog closes. Not const, because we might want to cancel
|
||||
//it in the case of video mode changes
|
||||
SDL_Rect dialog_rect = {xpos-10,ypos-10,width+20,height+20};
|
||||
const surface_restorer restorer(disp.video().getSurface(),dialog_rect);
|
||||
surface_restorer restorer(disp.video().getSurface(),dialog_rect);
|
||||
|
||||
SDL_Rect clip_rect = {0,0,disp.x(),disp.y()};
|
||||
SDL_Rect title_rect = font::draw_text(NULL,clip_rect,16,font::NORMAL_COLOUR,
|
||||
|
@ -472,10 +473,9 @@ void show_preferences_dialog(display& disp)
|
|||
break;
|
||||
}
|
||||
|
||||
const double new_music=music_slider.process(mousex,mousey,left_button);
|
||||
const double new_sound=sound_slider.process(mousex,mousey,left_button);
|
||||
const double new_scroll =
|
||||
scroll_slider.process(mousex,mousey,left_button);
|
||||
const double new_music = music_slider.process(mousex,mousey,left_button);
|
||||
const double new_sound = sound_slider.process(mousex,mousey,left_button);
|
||||
const double new_scroll = scroll_slider.process(mousex,mousey,left_button);
|
||||
|
||||
if(new_sound >= 0.0) {
|
||||
set_sound_volume(new_sound);
|
||||
|
@ -490,6 +490,9 @@ void show_preferences_dialog(display& disp)
|
|||
}
|
||||
|
||||
if(fullscreen_button.process(mousex,mousey,left_button)) {
|
||||
//the underlying frame buffer is changing, so cancel
|
||||
//the surface restorer restoring the frame buffer state
|
||||
restorer.cancel();
|
||||
set_fullscreen(fullscreen_button.checked());
|
||||
redraw_all = true;
|
||||
}
|
||||
|
@ -536,7 +539,12 @@ void show_preferences_dialog(display& disp)
|
|||
}
|
||||
|
||||
if(resolution_button.process(mousex,mousey,left_button)) {
|
||||
show_video_mode_dialog(disp);
|
||||
const bool mode_changed = show_video_mode_dialog(disp);
|
||||
if(mode_changed) {
|
||||
//the underlying frame buffer is changing, so cancel
|
||||
//the surface restorer restoring the frame buffer state
|
||||
restorer.cancel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -548,8 +556,7 @@ void show_preferences_dialog(display& disp)
|
|||
set_turn_dialog(turn_dialog_button.checked());
|
||||
}
|
||||
|
||||
if (hotkeys_button.
|
||||
process (mousex, mousey, left_button))
|
||||
if (hotkeys_button.process (mousex, mousey, left_button))
|
||||
{
|
||||
show_hotkeys_dialog (disp);
|
||||
break;
|
||||
|
@ -562,7 +569,7 @@ void show_preferences_dialog(display& disp)
|
|||
}
|
||||
}
|
||||
|
||||
void show_video_mode_dialog(display& disp)
|
||||
bool show_video_mode_dialog(display& disp)
|
||||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
|
||||
|
@ -580,7 +587,7 @@ void show_video_mode_dialog(display& disp)
|
|||
else
|
||||
std::cerr << "No modes supported\n";
|
||||
gui::show_dialog(disp,NULL,"",string_table["video_mode_unavailable"]);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; modes[i] != NULL; ++i) {
|
||||
|
@ -599,7 +606,7 @@ void show_video_mode_dialog(display& disp)
|
|||
|
||||
if(resolutions.size() < 2) {
|
||||
gui::show_dialog(disp,NULL,"",string_table["video_mode_unavailable"]);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const int result = gui::show_dialog(disp,NULL,"",
|
||||
|
@ -607,6 +614,9 @@ void show_video_mode_dialog(display& disp)
|
|||
gui::MESSAGE,&options);
|
||||
if(size_t(result) < resolutions.size()) {
|
||||
set_resolution(resolutions[result]);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace preferences {
|
|||
std::string client_type();
|
||||
|
||||
void show_preferences_dialog(display& disp);
|
||||
void show_video_mode_dialog(display& disp);
|
||||
bool show_video_mode_dialog(display& disp);
|
||||
void show_hotkeys_dialog (display & disp);
|
||||
}
|
||||
|
||||
|
|
103
src/replay.cpp
|
@ -105,14 +105,16 @@ bool replay::skipping() const
|
|||
return skip_ != 0;
|
||||
}
|
||||
|
||||
void replay::save_game(game_data& data, const std::string& label)
|
||||
void replay::save_game(game_data& data, const std::string& label, const config& start_pos)
|
||||
{
|
||||
saveInfo_.starting_pos = start_pos;
|
||||
saveInfo_.replay_data = cfg_;
|
||||
saveInfo_.label = label;
|
||||
|
||||
::save_game(saveInfo_);
|
||||
|
||||
saveInfo_.replay_data = config();
|
||||
saveInfo_.starting_pos = config();
|
||||
}
|
||||
|
||||
void replay::add_recruit(int value, const gamemap::location& loc)
|
||||
|
@ -216,6 +218,11 @@ void replay::end_turn()
|
|||
cmd->add_child("end_turn");
|
||||
}
|
||||
|
||||
void replay::speak(const config& cfg)
|
||||
{
|
||||
add_command()->add_child("speak") = cfg;
|
||||
}
|
||||
|
||||
config replay::get_data_range(int cmd_start, int cmd_end)
|
||||
{
|
||||
log_scope("get_data_range\n");
|
||||
|
@ -240,7 +247,7 @@ void replay::undo()
|
|||
}
|
||||
}
|
||||
|
||||
const config::child_list& replay::commands()
|
||||
const config::child_list& replay::commands() const
|
||||
{
|
||||
return cfg_.get_children("command");
|
||||
}
|
||||
|
@ -321,6 +328,17 @@ config* replay::get_next_action()
|
|||
return current_;
|
||||
}
|
||||
|
||||
bool replay::at_end() const
|
||||
{
|
||||
return pos_ >= commands().size();
|
||||
}
|
||||
|
||||
void replay::set_to_end()
|
||||
{
|
||||
pos_ = commands().size();
|
||||
current_ = NULL;
|
||||
}
|
||||
|
||||
void replay::clear()
|
||||
{
|
||||
cfg_ = config();
|
||||
|
@ -362,25 +380,22 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
for(;;) {
|
||||
config* const cfg = replayer.get_next_action();
|
||||
|
||||
std::map<std::string,std::vector<config*> >::iterator it;
|
||||
config* child;
|
||||
|
||||
//if we are expecting promotions here
|
||||
if(advancing_units.empty() == false) {
|
||||
if(cfg == NULL ||
|
||||
(it = cfg->children.find("choose")) == cfg->children.end()) {
|
||||
if(cfg == NULL || (child = cfg->child("choose")) == NULL) {
|
||||
std::cerr << "promotion expected, but none found\n";
|
||||
throw replay::error();
|
||||
}
|
||||
|
||||
const std::map<gamemap::location,unit>::iterator u =
|
||||
units.find(advancing_units.front());
|
||||
const std::map<gamemap::location,unit>::iterator u = units.find(advancing_units.front());
|
||||
assert(u != units.end());
|
||||
|
||||
const std::string& num = it->second.front()->values["value"];
|
||||
const std::string& num = (*child)["value"];
|
||||
const int val = atoi(num.c_str());
|
||||
|
||||
const std::vector<std::string>& options =
|
||||
u->second.type().advances_to();
|
||||
const std::vector<std::string>& options = u->second.type().advances_to();
|
||||
if(size_t(val) >= options.size()) {
|
||||
std::cerr << "illegal advancement type\n";
|
||||
throw replay::error();
|
||||
|
@ -398,31 +413,28 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
}
|
||||
|
||||
//if there is an end turn directive
|
||||
else if(cfg->children.find("end_turn") != cfg->children.end()) {
|
||||
else if(cfg->child("end_turn") != NULL) {
|
||||
replayer.next_skip();
|
||||
return true;
|
||||
}
|
||||
|
||||
else if((it = cfg->children.find("recruit")) != cfg->children.end()) {
|
||||
assert(!it->second.empty());
|
||||
const std::string& recruit_num=it->second.front()->values["value"];
|
||||
else if((child = cfg->child("recruit")) != NULL) {
|
||||
const std::string& recruit_num = (*child)["value"];
|
||||
const int val = atoi(recruit_num.c_str());
|
||||
|
||||
const gamemap::location loc(*(it->second.front()));
|
||||
const gamemap::location loc(*child);
|
||||
|
||||
const std::set<std::string>& recruits = current_team.recruits();
|
||||
std::set<std::string>::const_iterator itor = recruits.begin();
|
||||
std::advance(itor,val);
|
||||
const std::map<std::string,unit_type>::const_iterator u_type =
|
||||
gameinfo.unit_types.find(*itor);
|
||||
const std::map<std::string,unit_type>::const_iterator u_type = gameinfo.unit_types.find(*itor);
|
||||
if(u_type == gameinfo.unit_types.end()) {
|
||||
std::cerr << "recruiting illegal unit\n";
|
||||
throw replay::error();
|
||||
}
|
||||
|
||||
unit new_unit(&(u_type->second),team_num,true);
|
||||
const std::string& res =
|
||||
recruit_unit(map,team_num,units,new_unit,loc);
|
||||
const std::string& res = recruit_unit(map,team_num,units,new_unit,loc);
|
||||
if(!res.empty()) {
|
||||
std::cerr << "cannot recruit unit: " << res << "\n";
|
||||
throw replay::error();
|
||||
|
@ -431,36 +443,35 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
current_team.spend_gold(u_type->second.cost());
|
||||
}
|
||||
|
||||
else if((it = cfg->children.find("recall")) != cfg->children.end()) {
|
||||
else if((child = cfg->child("recall")) != NULL) {
|
||||
std::sort(state_of_game.available_units.begin(),
|
||||
state_of_game.available_units.end(),
|
||||
compare_unit_values());
|
||||
|
||||
assert(!it->second.empty());
|
||||
const std::string recall_num = it->second.front()->values["value"];
|
||||
const std::string recall_num = (*child)["value"];
|
||||
const int val = atoi(recall_num.c_str());
|
||||
|
||||
const gamemap::location loc(*(it->second.front()));
|
||||
const gamemap::location loc(*child);
|
||||
|
||||
recruit_unit(map,team_num,units,
|
||||
state_of_game.available_units[val],loc);
|
||||
state_of_game.available_units.erase(
|
||||
state_of_game.available_units.begin()+val);
|
||||
recruit_unit(map,team_num,units,state_of_game.available_units[val],loc);
|
||||
state_of_game.available_units.erase(state_of_game.available_units.begin()+val);
|
||||
current_team.spend_gold(game_config::recall_cost);
|
||||
}
|
||||
|
||||
else if((it = cfg->children.find("move")) != cfg->children.end()) {
|
||||
assert(!it->second.empty());
|
||||
else if((child = cfg->child("move")) != NULL) {
|
||||
|
||||
config* const move = it->second.front();
|
||||
const config* const destination = child->child("destination");
|
||||
const config* const source = child->child("source");
|
||||
|
||||
assert(move->child("destination") != NULL);
|
||||
assert(move->child("source") != NULL);
|
||||
if(destination == NULL || source == NULL) {
|
||||
std::cerr << "no destination/source found in movement\n";
|
||||
throw replay::error();
|
||||
}
|
||||
|
||||
const gamemap::location src(*(move->child("source")));
|
||||
const gamemap::location dst(*(move->child("destination")));
|
||||
const gamemap::location src(*source);
|
||||
const gamemap::location dst(*destination);
|
||||
|
||||
const std::map<gamemap::location,unit>::iterator u=units.find(src);
|
||||
const std::map<gamemap::location,unit>::iterator u = units.find(src);
|
||||
if(u == units.end()) {
|
||||
std::cerr << "unfound location for source of movement: "
|
||||
<< (src.x+1) << "," << (src.y+1) << "-"
|
||||
|
@ -526,21 +537,23 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
clear_shroud(disp,map,gameinfo,units,teams,team_num-1);
|
||||
}
|
||||
|
||||
else if((it = cfg->children.find("attack")) != cfg->children.end()) {
|
||||
assert(!it->second.empty());
|
||||
else if((child = cfg->child("attack")) != NULL) {
|
||||
|
||||
config* const move = it->second.front();
|
||||
const config* const destination = child->child("destination");
|
||||
const config* const source = child->child("source");
|
||||
|
||||
assert(move->child("destination") != NULL);
|
||||
assert(move->child("source") != NULL);
|
||||
if(destination == NULL || source == NULL) {
|
||||
std::cerr << "no destination/source found in attack\n";
|
||||
throw replay::error();
|
||||
}
|
||||
|
||||
const gamemap::location src(*(move->child("source")));
|
||||
const gamemap::location dst(*(move->child("destination")));
|
||||
const gamemap::location src(*source);
|
||||
const gamemap::location dst(*destination);
|
||||
|
||||
const std::string& weapon = move->values["weapon"];
|
||||
const std::string& weapon = (*child)["weapon"];
|
||||
const int weapon_num = atoi(weapon.c_str());
|
||||
|
||||
std::map<gamemap::location,unit>::iterator u=units.find(src);
|
||||
std::map<gamemap::location,unit>::iterator u = units.find(src);
|
||||
if(u == units.end()) {
|
||||
std::cerr << "unfound location for source of attack\n";
|
||||
throw replay::error();
|
||||
|
@ -582,6 +595,8 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
tgt->second.type().advances_to().empty() == false) {
|
||||
advancing_units.push_back(tgt->first);
|
||||
}
|
||||
} else if((child = cfg->child("speak")) != NULL) {
|
||||
dialogs::unit_speak(*child,disp,units);
|
||||
} else {
|
||||
std::cerr << "unrecognized action: '" << cfg->write() << "'\n";
|
||||
throw replay::error();
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
void next_skip();
|
||||
bool skipping() const;
|
||||
|
||||
void save_game(game_data& data, const std::string& label);
|
||||
void save_game(game_data& data, const std::string& label, const config& start_pos);
|
||||
|
||||
void add_recruit(int unit_index, const gamemap::location& loc);
|
||||
void add_recall(int unit_index, const gamemap::location& loc);
|
||||
|
@ -47,6 +47,8 @@ public:
|
|||
void choose_option(int index);
|
||||
void end_turn();
|
||||
|
||||
void speak(const config& cfg);
|
||||
|
||||
config get_data_range(int cmd_start, int cmd_end);
|
||||
config get_last_turn(int num_turns=1);
|
||||
|
||||
|
@ -59,6 +61,9 @@ public:
|
|||
void start_replay();
|
||||
config* get_next_action();
|
||||
|
||||
bool at_end() const;
|
||||
void set_to_end();
|
||||
|
||||
void clear();
|
||||
bool empty();
|
||||
|
||||
|
@ -77,7 +82,7 @@ private:
|
|||
|
||||
void add_value(const std::string& type, int value);
|
||||
|
||||
const config::child_list& commands();
|
||||
const config::child_list& commands() const;
|
||||
config* add_command();
|
||||
config cfg_;
|
||||
unsigned int pos_;
|
||||
|
|
|
@ -120,7 +120,7 @@ SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& area)
|
|||
/* Rotates 8-, 16-, and 32-bit sprites. 24-bit sprites aren't handled; you
|
||||
* must convert to one of these color depths before calling this function.
|
||||
* */
|
||||
#ifdef WIN32
|
||||
#if (defined(_WIN32) || defined(__APPLE__))
|
||||
#define tanf(value) (float)tan(value)
|
||||
#define sinf(value) (float)sin(value)
|
||||
#define cosf(value) (float)cos(value)
|
||||
|
@ -461,11 +461,18 @@ surface_restorer::~surface_restorer()
|
|||
|
||||
void surface_restorer::restore()
|
||||
{
|
||||
::SDL_BlitSurface(surface_,NULL,target_,&rect_);
|
||||
update_rect(rect_);
|
||||
if(surface_ != NULL) {
|
||||
::SDL_BlitSurface(surface_,NULL,target_,&rect_);
|
||||
update_rect(rect_);
|
||||
}
|
||||
}
|
||||
|
||||
void surface_restorer::update()
|
||||
{
|
||||
surface_.assign(::get_surface_portion(target_,rect_));
|
||||
}
|
||||
|
||||
void surface_restorer::cancel()
|
||||
{
|
||||
surface_.assign(NULL);
|
||||
}
|
|
@ -131,6 +131,7 @@ struct surface_restorer
|
|||
|
||||
void restore();
|
||||
void update();
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
SDL_Surface* target_;
|
||||
|
|
|
@ -328,7 +328,7 @@ void run_server()
|
|||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try {
|
||||
run_server();
|
||||
|
@ -336,4 +336,6 @@ int main()
|
|||
std::cerr << "error starting server: " << e.message << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
if(disp.update_locked())
|
||||
return -1;
|
||||
|
||||
const events::event_context dialog_events_context;
|
||||
const dialog_manager manager;
|
||||
|
||||
const events::resize_lock prevent_resizing;
|
||||
|
@ -221,8 +222,8 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
text_widget_width =
|
||||
font::draw_text(NULL, clipRect, message_font_size,
|
||||
font::NORMAL_COLOUR, text_widget_label, 0, 0, NULL).w +
|
||||
text_widget.width();
|
||||
text_widget_height = text_widget.height() + 6;
|
||||
text_widget.location().w;
|
||||
text_widget_height = text_widget.location().h + 6;
|
||||
}
|
||||
|
||||
menu menu_(disp,menu_items,type == MESSAGE);
|
||||
|
@ -436,10 +437,10 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
const int text_widget_y = yloc+top_padding+image_h-6+text_size.h+menu_hpadding;
|
||||
|
||||
if(use_textbox) {
|
||||
text_widget.set_location(xloc + left_padding +
|
||||
text_widget_width - text_widget.width(),
|
||||
text_widget.set_position(xloc + left_padding +
|
||||
text_widget_width - text_widget.location().w,
|
||||
text_widget_y);
|
||||
text_widget.draw();
|
||||
events::raise_draw_event();
|
||||
font::draw_text(&disp, clipRect, message_font_size,
|
||||
font::NORMAL_COLOUR, text_widget_label,
|
||||
xloc + left_padding,text_widget_y);
|
||||
|
@ -448,7 +449,7 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
//set the position of any tick boxes. they go right below the menu, slammed against
|
||||
//the right side of the dialog
|
||||
if(options != NULL) {
|
||||
int options_y = text_widget_y + (use_textbox ? text_widget.height() : 0) + menu_.height() + button_height_padding + menu_hpadding;
|
||||
int options_y = text_widget_y + (use_textbox ? text_widget.location().h : 0) + menu_.height() + button_height_padding + menu_hpadding;
|
||||
for(size_t i = 0; i != check_buttons.size(); ++i) {
|
||||
check_buttons[i].set_x(xloc + total_width - padding_width - check_buttons[i].width());
|
||||
check_buttons[i].set_y(options_y);
|
||||
|
@ -565,10 +566,8 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
page_up = new_page_up;
|
||||
page_down = new_page_down;
|
||||
|
||||
if(use_textbox) {
|
||||
text_widget.process();
|
||||
}
|
||||
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
||||
if(buttons.empty() && (new_left_button && !left_button ||
|
||||
new_right_button && !right_button) ||
|
||||
|
@ -578,7 +577,7 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
|
||||
left_button = new_left_button;
|
||||
right_button = new_right_button;
|
||||
key_down = new_key_down;
|
||||
key_down = new_key_down;
|
||||
|
||||
for(std::vector<button>::iterator button_it = buttons.begin();
|
||||
button_it != buttons.end(); ++button_it) {
|
||||
|
@ -625,7 +624,7 @@ TITLE_RESULT show_title(display& screen)
|
|||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
|
||||
const scoped_sdl_surface title_surface(image::get_image("title.png",image::UNSCALED));
|
||||
const scoped_sdl_surface title_surface(image::get_image(game_config::game_title,image::UNSCALED));
|
||||
|
||||
if(title_surface == NULL) {
|
||||
std::cerr << "Could not find title image 'title.png'\n";
|
||||
|
|
106
src/team.cpp
|
@ -18,12 +18,18 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
team::target::target(const config& cfg)
|
||||
: criteria(cfg), value(atof(cfg["value"].c_str()))
|
||||
{
|
||||
}
|
||||
|
||||
void team::target::write(config& cfg) const
|
||||
{
|
||||
cfg = criteria;
|
||||
}
|
||||
|
||||
team::team_info::team_info(const config& cfg)
|
||||
{
|
||||
gold = cfg["gold"];
|
||||
|
@ -106,11 +112,111 @@ team::team_info::team_info(const config& cfg)
|
|||
music = cfg["music"];
|
||||
}
|
||||
|
||||
void team::team_info::write(config& cfg) const
|
||||
{
|
||||
cfg["gold"] = gold;
|
||||
cfg["income"] = income;
|
||||
cfg["name"] = name;
|
||||
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",income_per_village);
|
||||
cfg["village_gold"] = buf;
|
||||
|
||||
sprintf(buf,"%f",aggression);
|
||||
cfg["aggression"] = buf;
|
||||
|
||||
std::stringstream enemies_str;
|
||||
for(std::vector<int>::const_iterator en = enemies.begin(); en != enemies.end(); ++en) {
|
||||
enemies_str << *en;
|
||||
if(en+1 != enemies.end())
|
||||
enemies_str << ",";
|
||||
}
|
||||
|
||||
cfg["enemy"] = enemies_str.str();
|
||||
|
||||
switch(controller) {
|
||||
case AI: cfg["controller"] = "ai"; break;
|
||||
case HUMAN: cfg["controller"] = "human"; break;
|
||||
case NETWORK: cfg["controller"] = "network"; break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
sprintf(buf,"%d",villages_per_scout);
|
||||
cfg["villages_per_scout"] = buf;
|
||||
|
||||
sprintf(buf,"%f",leader_value);
|
||||
cfg["leader_value"] = buf;
|
||||
|
||||
sprintf(buf,"%f",village_value);
|
||||
cfg["village_value"] = buf;
|
||||
|
||||
for(std::vector<target>::const_iterator tg = targets.begin(); tg != targets.end(); ++tg) {
|
||||
tg->write(cfg.add_child("target"));
|
||||
}
|
||||
|
||||
std::stringstream can_recruit_str;
|
||||
for(std::set<std::string>::const_iterator cr = can_recruit.begin(); cr != can_recruit.end(); ++cr) {
|
||||
if(cr != can_recruit.begin())
|
||||
can_recruit_str << ",";
|
||||
|
||||
can_recruit_str << *cr;
|
||||
}
|
||||
|
||||
cfg["recruit"] = can_recruit_str.str();
|
||||
|
||||
std::stringstream recruit_pattern_str;
|
||||
for(std::vector<std::string>::const_iterator p = recruitment_pattern.begin(); p != recruitment_pattern.end(); ++p) {
|
||||
if(p != recruitment_pattern.begin())
|
||||
recruit_pattern_str << ",";
|
||||
|
||||
recruit_pattern_str << *p;
|
||||
}
|
||||
|
||||
cfg["recruitment_pattern"] = recruit_pattern_str.str();
|
||||
|
||||
cfg["shroud"] = use_shroud ? "yes" : "no";
|
||||
cfg["fog"] = use_fog ? "yes" : "no";
|
||||
|
||||
if(music.empty() == false)
|
||||
cfg["music"] = music;
|
||||
}
|
||||
|
||||
team::team(const config& cfg, int gold) : gold_(gold), info_(cfg)
|
||||
{
|
||||
//gold is the maximum of 'gold' and what is given in the config file
|
||||
if(info_.gold.empty() == false)
|
||||
gold_ = maximum(gold,::atoi(info_.gold.c_str()));
|
||||
|
||||
//load in the villages the side controls at the start
|
||||
const config::child_list& villages = cfg.get_children("village");
|
||||
for(config::child_list::const_iterator v = villages.begin(); v != villages.end(); ++v) {
|
||||
towers_.insert(gamemap::location(**v));
|
||||
}
|
||||
}
|
||||
|
||||
void team::write(config& cfg) const
|
||||
{
|
||||
info_.write(cfg);
|
||||
|
||||
char buf[50];
|
||||
sprintf(buf,"%d",gold_);
|
||||
cfg["gold"] = buf;
|
||||
|
||||
//write village locations
|
||||
for(std::set<gamemap::location>::const_iterator t = towers_.begin(); t != towers_.end(); ++t) {
|
||||
t->write(cfg.add_child("village"));
|
||||
}
|
||||
|
||||
std::stringstream shroud_str;
|
||||
for(std::vector<std::vector<bool> >::const_iterator sh = shroud_.begin(); sh != shroud_.end(); ++sh) {
|
||||
for(std::vector<bool>::const_iterator i = sh->begin(); i != sh->end(); ++i) {
|
||||
shroud_str << (*i ? '1' : '0');
|
||||
}
|
||||
|
||||
shroud_str << '\n';
|
||||
}
|
||||
|
||||
cfg["shroud_data"] = shroud_str.str();
|
||||
}
|
||||
|
||||
void team::get_tower(const gamemap::location& loc)
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
|
||||
struct target {
|
||||
explicit target(const config& cfg);
|
||||
void write(config& cfg) const;
|
||||
config criteria;
|
||||
double value;
|
||||
};
|
||||
|
@ -35,6 +36,7 @@ public:
|
|||
struct team_info
|
||||
{
|
||||
team_info(const config& cfg);
|
||||
void write(config& cfg) const;
|
||||
std::string name;
|
||||
std::string gold;
|
||||
std::string income;
|
||||
|
@ -58,6 +60,9 @@ public:
|
|||
};
|
||||
|
||||
team(const config& cfg, int gold=100);
|
||||
|
||||
void write(config& cfg) const;
|
||||
|
||||
void get_tower(const gamemap::location&);
|
||||
void lose_tower(const gamemap::location&);
|
||||
const std::set<gamemap::location>& towers() const;
|
||||
|
|