openttd 1.5.9-RC1 with missing files

--HG--
branch : openttd
This commit is contained in:
Pavel Stupnikov
2015-03-19 16:55:44 +03:00
parent 46e74a9a05
commit 990dac5149
24 changed files with 9000 additions and 3 deletions

View File

@@ -0,0 +1,32 @@
# $Id: assemble_nfo.awk 26708 2014-07-30 17:21:42Z rubidium $
# This file is part of OpenTTD.
# OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
# OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
BEGIN {
# Very basic variant function; barely any error checking.
# Just use the first argument as the file to start from when assembling everything
path = ARGV[1];
gsub("[^/\\\\]*$", "", path);
assemble(ARGV[1]);
}
# Recursive function for assembling by means of resolving the #includes.
function assemble(filename) {
while ((getline < filename) > 0) {
if (NF == 2 && $1 == "#include" ) {
# Remove the quotes.
gsub("[\"'<>]", "", $2);
assemble(path $2);
} else {
print $0;
}
}
if (close(filename) < 0) {
print "Could not open " filename > "/dev/stderr";
exit -1;
}
}

View File

@@ -0,0 +1,20 @@
//
// $Id: palette.nfo 26869 2014-09-21 07:57:45Z rubidium $
//
// This file is part of OpenTTD.
// OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
//
-1 * 0 0C "All black palette"
-1 * 0 05 18 01
-1 * 0 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01

Binary file not shown.

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,2 @@
#v4.0:v110:false
Debug|Win32|\\VBOXSVR\Projects\novattd\projects\|

View File

@@ -0,0 +1,18 @@
Build started 18.04.2014 19:09:33.
1>Project "\\VBOXSVR\Projects\novattd\projects\generate_vs100.vcxproj" on node 2 (Build target(s)).
1>CustomBuild:
"\\VBOXSVR\Projects\novattd\projects"
Указанный путь был использован при запуске CMD.EXE в качестве текущей папки.
CMD.EXE не поддерживает пути UNC. По умолчанию выбрана системная папка Windows.
Running 'generate.vbs' ...
Сервер сценариев Windows (Microsoft R) версия 5.8
c Корпорация Майкрософт (Microsoft Corp.), 1996-2001. Все права защищены.
Can't find source.list, needed in order to make this run.
Please go to either the project dir, or the root dir of a clean SVN checkout.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(172,5): error MSB6006: "cmd.exe" exited with code 1.
1>Done Building Project "\\VBOXSVR\Projects\novattd\projects\generate_vs100.vcxproj" (Build target(s)) -- FAILED.
Build FAILED.
Time Elapsed 00:00:00.40

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,48 @@
--- projects/openttd_vs90.vcproj (revision 26379)
+++ projects/openttd_vs90.vcproj (working copy)
@@ -255,38 +268,26 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
- TypeLibraryName=".\Release/openttd.tlb"
+ TypeLibraryName=".\Debug/openttd.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- Optimization="3"
- InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="true"
- FavorSizeOrSpeed="2"
- OmitFramePointers="true"
+ Optimization="0"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;_SQ64;WITH_ASSERT"
- StringPooling="true"
- ExceptionHandling="1"
- RuntimeLibrary="0"
- StructMemberAlignment="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
UsePrecompiledHeader="0"
- PrecompiledHeaderThrough=""
- PrecompiledHeaderFile=""
- AssemblerOutput="2"
AssemblerListingLocation="$(IntDir)/"
ObjectFile="$(IntDir)/"
ProgramDataBaseFileName="$(IntDir)/$(TargetName).pdb"
WarningLevel="3"
WarnAsError="false"
SuppressStartupBanner="true"
- DebugInformationFormat="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
CallingConvention="1"
CompileAs="0"
/>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

299
src/3rdparty/os2/getaddrinfo.c vendored Normal file
View File

@@ -0,0 +1,299 @@
/*
* This file is part of libESMTP, a library for submission of RFC 2822
* formatted electronic mail messages using the SMTP protocol described
* in RFC 2821.
*
* Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* An emulation of the RFC 2553 / Posix getaddrinfo resolver interface.
*/
#if !HAVE_GETADDRINFO
/* Need to turn off Posix features in glibc to build this */
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
#include "getaddrinfo.h"
//#include "compat/inet_pton.h"
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
static struct addrinfo *
dup_addrinfo (struct addrinfo *info, void *addr, size_t addrlen) {
struct addrinfo *ret;
ret = malloc (sizeof (struct addrinfo));
if (ret == NULL)
return NULL;
memcpy (ret, info, sizeof (struct addrinfo));
ret->ai_addr = malloc (addrlen);
if (ret->ai_addr == NULL) {
free (ret);
return NULL;
}
memcpy (ret->ai_addr, addr, addrlen);
ret->ai_addrlen = addrlen;
return ret;
}
int
getaddrinfo (const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
struct hostent *hp;
struct servent *servent;
const char *socktype;
int port;
struct addrinfo hint, result;
struct addrinfo *ai, *sai, *eai;
char **addrs;
if (servname == NULL && nodename == NULL)
return EAI_NONAME;
memset (&result, 0, sizeof result);
/* default for hints */
if (hints == NULL) {
memset (&hint, 0, sizeof hint);
hint.ai_family = PF_UNSPEC;
hints = &hint;
}
if (servname == NULL)
port = 0;
else {
/* check for tcp or udp sockets only */
if (hints->ai_socktype == SOCK_STREAM)
socktype = "tcp";
else if (hints->ai_socktype == SOCK_DGRAM)
socktype = "udp";
else
return EAI_SERVICE;
result.ai_socktype = hints->ai_socktype;
/* Note: maintain port in host byte order to make debugging easier */
if (isdigit (*servname))
port = strtol (servname, NULL, 10);
else if ((servent = getservbyname (servname, socktype)) != NULL)
port = ntohs (servent->s_port);
else
return EAI_NONAME;
}
/* if nodename == NULL refer to the local host for a client or any
for a server */
if (nodename == NULL) {
struct sockaddr_in sin;
/* check protocol family is PF_UNSPEC or PF_INET - could try harder
for IPv6 but that's more code than I'm prepared to write */
if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
result.ai_family = AF_INET;
else
return EAI_FAMILY;
sin.sin_family = result.ai_family;
sin.sin_port = htons (port);
if (hints->ai_flags & AI_PASSIVE)
sin.sin_addr.s_addr = htonl (INADDR_ANY);
else
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
/* Duplicate result and addr and return */
*res = dup_addrinfo (&result, &sin, sizeof sin);
return (*res == NULL) ? EAI_MEMORY : 0;
}
/* If AI_NUMERIC is specified, use inet_pton to translate numbers and
dots notation. */
if (hints->ai_flags & AI_NUMERICHOST) {
struct sockaddr_in sin;
/* check protocol family is PF_UNSPEC or PF_INET */
if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
result.ai_family = AF_INET;
else
return EAI_FAMILY;
sin.sin_family = result.ai_family;
sin.sin_port = htons (port);
if (inet_pton(result.ai_family, nodename, &sin.sin_addr)==0)
return EAI_NONAME;
sin.sin_addr.s_addr = inet_addr (nodename);
/* Duplicate result and addr and return */
*res = dup_addrinfo (&result, &sin, sizeof sin);
return (*res == NULL) ? EAI_MEMORY : 0;
}
#if HAVE_H_ERRNO
h_errno = 0;
#endif
errno = 0;
hp = gethostbyname(nodename);
if (hp == NULL) {
#ifdef EAI_SYSTEM
if (errno != 0) {
return EAI_SYSTEM;
}
#endif
switch (h_errno) {
case HOST_NOT_FOUND:
return EAI_NODATA;
case NO_DATA:
return EAI_NODATA;
#if defined(NO_ADDRESS) && NO_ADDRESS != NO_DATA
case NO_ADDRESS:
return EAI_NODATA;
#endif
case NO_RECOVERY:
return EAI_FAIL;
case TRY_AGAIN:
return EAI_AGAIN;
default:
return EAI_FAIL;
}
return EAI_FAIL;
}
/* Check that the address family is acceptable.
*/
switch (hp->h_addrtype) {
case AF_INET:
if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET))
return EAI_FAMILY;
break;
#ifndef __OS2__
case AF_INET6:
if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET6))
return EAI_FAMILY;
break;
#endif
default:
return EAI_FAMILY;
}
/* For each element pointed to by hp, create an element in the
result linked list. */
sai = eai = NULL;
for (addrs = hp->h_addr_list; *addrs != NULL; addrs++) {
struct sockaddr sa;
size_t addrlen;
if (hp->h_length < 1)
continue;
sa.sa_family = hp->h_addrtype;
switch (hp->h_addrtype) {
case AF_INET:
((struct sockaddr_in *) &sa)->sin_port = htons (port);
memcpy (&((struct sockaddr_in *) &sa)->sin_addr,
*addrs, hp->h_length);
addrlen = sizeof (struct sockaddr_in);
break;
#ifndef __OS2__
case AF_INET6:
#if SIN6_LEN
((struct sockaddr_in6 *) &sa)->sin6_len = hp->h_length;
#endif
((struct sockaddr_in6 *) &sa)->sin6_port = htons (port);
memcpy (&((struct sockaddr_in6 *) &sa)->sin6_addr,
*addrs, hp->h_length);
addrlen = sizeof (struct sockaddr_in6);
break;
#endif
default:
continue;
}
result.ai_family = hp->h_addrtype;
ai = dup_addrinfo (&result, &sa, addrlen);
if (ai == NULL) {
freeaddrinfo (sai);
return EAI_MEMORY;
}
if (sai == NULL)
sai = ai;
else
eai->ai_next = ai;
eai = ai;
}
if (sai == NULL) {
return EAI_NODATA;
}
if (hints->ai_flags & AI_CANONNAME) {
sai->ai_canonname = malloc (strlen (hp->h_name) + 1);
if (sai->ai_canonname == NULL) {
freeaddrinfo (sai);
return EAI_MEMORY;
}
strcpy (sai->ai_canonname, hp->h_name);
}
*res = sai;
return 0;
}
void
freeaddrinfo (struct addrinfo *ai)
{
struct addrinfo *next;
while (ai != NULL) {
next = ai->ai_next;
if (ai->ai_canonname != NULL)
free (ai->ai_canonname);
if (ai->ai_addr != NULL)
free (ai->ai_addr);
free (ai);
ai = next;
}
}
const char *
gai_strerror (int ecode)
{
static const char *eai_descr[] = {
"no error",
"address family for nodename not supported", /* EAI_ADDRFAMILY */
"temporary failure in name resolution", /* EAI_AGAIN */
"invalid value for ai_flags", /* EAI_BADFLAGS */
"non-recoverable failure in name resolution", /* EAI_FAIL */
"ai_family not supported", /* EAI_FAMILY */
"memory allocation failure", /* EAI_MEMORY */
"no address associated with nodename", /* EAI_NODATA */
"nodename nor servname provided, or not known", /* EAI_NONAME */
"servname not supported for ai_socktype", /* EAI_SERVICE */
"ai_socktype not supported", /* EAI_SOCKTYPE */
"system error returned in errno", /* EAI_SYSTEM */
"argument buffer overflow", /* EAI_OVERFLOW */
};
if (ecode < 0 || ecode > (int) (sizeof eai_descr/ sizeof eai_descr[0]))
return "unknown error";
return eai_descr[ecode];
}
#endif /* HAVE_GETADDRINFO */

101
src/3rdparty/os2/getaddrinfo.h vendored Normal file
View File

@@ -0,0 +1,101 @@
#ifndef _getaddrinfo_h
#define _getaddrinfo_h
/*
* Shamelessly duplicated from the fetchmail public sources
* for use by the Squid Project under GNU Public License.
*
* Update/Maintenance History:
*
* 15-Aug-2007 : Copied from fetchmail 6.3.8
* - added protection around libray headers
*
* 16-Aug-2007 : Altered configure checks
* Un-hacked slightly to use system gethostbyname()
*
* Original License and code follows.
*/
/*
* This file is part of libESMTP, a library for submission of RFC 2822
* formatted electronic mail messages using the SMTP protocol described
* in RFC 2821.
*
* Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Structure and prototypes taken from RFC 2553 */
/* SG 23/09/2007:
On Windows the following definitions are already available, may be that
this could be needed on some other platform */
typedef int socklen_t;
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
socklen_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for nodename */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
/* Supposed to be defined in <netdb.h> */
#define AI_ADDRCONFIG 0
#define AI_PASSIVE 1 /* Socket address is intended for `bind'. */
#define AI_CANONNAME 2 /* Request for canonical name. */
#define AI_NUMERICHOST 4 /* Don't use name resolution. */
/* Supposed to be defined in <netdb.h> */
#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */
#define EAI_AGAIN 2 /* temporary failure in name resolution */
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#define EAI_FAMILY 5 /* ai_family not supported */
#define EAI_MEMORY 6 /* memory allocation failure */
#define EAI_NODATA 7 /* no address associated with nodename */
#define EAI_NONAME 8 /* nodename nor servname provided, or not known */
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
#ifndef EAI_SYSTEM
/* Not defined on mingw32. */
#define EAI_SYSTEM 11 /* System error returned in `errno'. */
#endif
#ifndef EAI_OVERFLOW
/* Not defined on mingw32. */
#define EAI_OVERFLOW 12 /* Argument buffer overflow. */
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* RFC 2553 / Posix resolver */
int getaddrinfo (const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
/* Free addrinfo structure and associated storage */
void freeaddrinfo (struct addrinfo *ai);
/* Convert error return from getaddrinfo() to string */
const char *gai_strerror (int code);
#ifdef __cplusplus
}
#endif
#endif /* _getaddrinfo_h */

367
src/3rdparty/os2/getnameinfo.c vendored Normal file
View File

@@ -0,0 +1,367 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Issues to be discussed:
* - RFC2553 says that we should raise error on short buffer. X/Open says
* we need to truncate the result. We obey RFC2553 (and X/Open should be
* modified). ipngwg rough consensus seems to follow RFC2553. RFC3493 says
* nothing about it, but defines a new error code EAI_OVERFLOW which seems
* to be intended the code for this case.
* - What is "local" in NI_NOFQDN? (see comments in the code)
* - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
* - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
* sin6_scope_id is filled - standardization status?
* - what should we do if we should do getservbyport("sctp")?
*/
/*
* Considerations about thread-safeness
* The code in this file is thread-safe, and so the thread-safeness of
* getnameinfo() depends on the property of backend functions.
* - getservbyport() is not thread safe for most systems we are targeting.
* - getipnodebyaddr() is thread safe. However, many resolver libraries
* used in the function are not thread safe.
* - gethostbyaddr() is usually not thread safe.
*/
#if !HAVE_GETNAMEINFO
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <inttypes.h>
#include "getaddrinfo.h"
#include "getnameinfo.h"
static const struct afd {
int a_af;
int a_addrlen;
int a_socklen;
int a_off;
int a_portoff;
} afdl [] = {
#if INET6
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
offsetof(struct sockaddr_in6, sin6_addr),
offsetof(struct sockaddr_in6, sin6_port)},
#endif
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
offsetof(struct sockaddr_in, sin_addr),
offsetof(struct sockaddr_in, sin_port)},
{0, 0, 0, 0, 0},
};
#if INET6
static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
size_t, int));
static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
#endif
int
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
const struct sockaddr *sa;
socklen_t salen;
char *host;
size_t hostlen;
char *serv;
size_t servlen;
int flags;
{
const struct afd *afd;
struct servent *sp;
struct hostent *hp;
unsigned short port;
int family, i;
const char *addr;
uint32_t v4a;
char numserv[512];
if (sa == NULL)
return EAI_FAIL;
#if HAVE_SA_LEN /*XXX*/
if (sa->sa_len != salen)
return EAI_FAIL;
#endif
family = sa->sa_family;
for (i = 0; afdl[i].a_af; i++)
if (afdl[i].a_af == family) {
afd = &afdl[i];
goto found;
}
return EAI_FAMILY;
found:
if (salen != afd->a_socklen)
return EAI_FAIL;
/* network byte order */
memcpy(&port, (const char *)sa + afd->a_portoff, sizeof(port));
addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: RFC3493 says that serv == NULL OR servlen == 0
* means that the caller does not want the result.
*/
} else {
if (flags & NI_NUMERICSERV)
sp = NULL;
else {
sp = getservbyport(port,
(flags & NI_DGRAM) ? "udp" : "tcp");
}
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
return EAI_OVERFLOW;
strncpy(serv, sp->s_name, servlen);
} else {
snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
if (strlen(numserv) + 1 > servlen)
return EAI_OVERFLOW;
strncpy(serv, numserv, servlen);
}
}
switch (sa->sa_family) {
case AF_INET:
v4a = (uint32_t)
ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
flags |= NI_NUMERICHOST;
v4a >>= IN_CLASSA_NSHIFT;
if (v4a == 0)
flags |= NI_NUMERICHOST;
break;
#if INET6
case AF_INET6: {
const struct sockaddr_in6 *sin6;
sin6 = (const struct sockaddr_in6 *)sa;
switch (sin6->sin6_addr.s6_addr[0]) {
case 0x00:
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
;
else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
;
else
flags |= NI_NUMERICHOST;
break;
default:
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
break;
}
}
break;
#endif
}
if (host == NULL || hostlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: RFC3493 says that host == NULL or hostlen == 0
* means that the caller does not want the result.
*/
} else if (flags & NI_NUMERICHOST) {
/* NUMERICHOST and NAMEREQD conflicts with each other */
if (flags & NI_NAMEREQD)
return EAI_NONAME;
goto numeric;
} else {
#if USE_GETIPNODEBY
int h_error = 0;
hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
#else
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
#if 0 // getnameinfo.c:161:9: error: variable 'h_error' set but not used
#if HAVE_H_ERRNO
h_error = h_errno;
#else
h_error = EINVAL;
#endif
#endif /* 0 */
#endif
if (hp) {
#if 0
if (flags & NI_NOFQDN) {
/*
* According to RFC3493 section 6.2, NI_NOFQDN
* means "node name portion of the FQDN shall
* be returned for local hosts." The following
* code tries to implement it by returning the
* first label (the part before the first
* period) of the FQDN. However, it is not
* clear if this always makes sense, since the
* given address may be outside of "local
* hosts." Due to the unclear description, we
* disable the code in this implementation.
*/
char *p;
p = strchr(hp->h_name, '.');
if (p)
*p = '\0';
}
#endif
if (strlen(hp->h_name) + 1 > hostlen) {
#if USE_GETIPNODEBY
freehostent(hp);
#endif
return EAI_OVERFLOW;
}
strncpy(host, hp->h_name, hostlen);
#if USE_GETIPNODEBY
freehostent(hp);
#endif
} else {
if (flags & NI_NAMEREQD)
return EAI_NONAME;
numeric:
switch (afd->a_af) {
#if INET6
case AF_INET6: {
int error;
if ((error = ip6_parsenumeric(sa, addr, host,
hostlen,
flags)) != 0)
return(error);
break;
}
#endif
default:
if (inet_ntop(afd->a_af, addr, host,
hostlen) == NULL)
return EAI_SYSTEM;
break;
}
}
}
return(0);
}
#if INET6
static int
ip6_parsenumeric(sa, addr, host, hostlen, flags)
const struct sockaddr *sa;
const char *addr;
char *host;
size_t hostlen;
int flags;
{
int numaddrlen;
char numaddr[512];
if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
return EAI_SYSTEM;
numaddrlen = strlen(numaddr);
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
return EAI_OVERFLOW;
strncpy(host, numaddr, hostlen);
if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
char zonebuf[SQUIDHOSTNAMELEN];
int zonelen;
zonelen = ip6_sa2str(
(const struct sockaddr_in6 *)(const void *)sa,
zonebuf, sizeof(zonebuf), flags);
if (zonelen < 0)
return EAI_OVERFLOW;
if (zonelen + 1 + numaddrlen + 1 > hostlen)
return EAI_OVERFLOW;
/* construct <numeric-addr><delim><zoneid> */
memcpy(host + numaddrlen + 1, zonebuf,
(size_t)zonelen);
host[numaddrlen] = SCOPE_DELIMITER;
host[numaddrlen + 1 + zonelen] = '\0';
}
return 0;
}
/* ARGSUSED */
static int
ip6_sa2str(sa6, buf, bufsiz, flags)
const struct sockaddr_in6 *sa6;
char *buf;
size_t bufsiz;
int flags;
{
unsigned int ifindex;
const struct in6_addr *a6;
int n;
ifindex = (unsigned int)sa6->sin6_scope_id;
a6 = &sa6->sin6_addr;
#if NI_NUMERICSCOPE
if ((flags & NI_NUMERICSCOPE) != 0) {
n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
if (n < 0 || n >= bufsiz)
return -1;
else
return n;
}
#endif
/* if_indextoname() does not take buffer size. not a good api... */
if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
IN6_IS_ADDR_MC_NODELOCAL(a6)) && bufsiz >= IF_NAMESIZE) {
char *p = if_indextoname(ifindex, buf);
if (p)
return (strlen(p));
}
/* last resort */
n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
if (n < 0 || n >= bufsiz)
return -1;
else
return n;
}
#endif /* INET6 */
#endif

29
src/3rdparty/os2/getnameinfo.h vendored Normal file
View File

@@ -0,0 +1,29 @@
#ifndef _getnameinfo_h
#define _getnameinfo_h
/*
* Reconstructed from KAME getnameinfo.c (in lib/)
*/
/* getnameinfo flags */
#define NI_NOFQDN 0x0001
#define NI_NUMERICHOST 0x0002 /* return numeric form of address */
#define NI_NAMEREQD 0x0004 /* request DNS name */
#define NI_NUMERICSERV 0x0008
#define NI_DGRAM 0x0010
#ifdef __cplusplus
extern "C" {
#endif
/* RFC 2553 / Posix resolver */
int getnameinfo(const struct sockaddr *sa,
socklen_t salen,
char *host,
size_t hostlen,
char *serv,
size_t servlen,
int flags );
#ifdef __cplusplus
}
#endif
#endif /* _getnameinfo_h */

982
src/disaster_vehicle.cpp Normal file
View File

@@ -0,0 +1,982 @@
/* $Id: disaster_vehicle.cpp 27087 2014-12-21 20:49:15Z rubidium $ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file disaster_vehicle.cpp
*
* All disaster/easter egg vehicles are handled here.
* The general flow of control for the disaster vehicles is as follows:
* <ol>
* <li>Initialize the disaster in a disaster specific way (eg start position,
* possible target, etc.) Disaster_XXX_Init() function
* <li>Add a subtype to a disaster, which is an index into the function array
* that handles the vehicle's ticks.
* <li>Run the disaster vehicles each tick until their target has been reached,
* this happens in the DisasterTick_XXX() functions. In here, a vehicle's
* state is kept by v->current_order.dest variable. Each achieved sub-target
* will increase this value, and the last one will remove the disaster itself
* </ol>
*/
#include "stdafx.h"
#include "aircraft.h"
#include "disaster_vehicle.h"
#include "industry.h"
#include "station_base.h"
#include "command_func.h"
#include "news_func.h"
#include "town.h"
#include "company_func.h"
#include "strings_func.h"
#include "date_func.h"
#include "viewport_func.h"
#include "vehicle_func.h"
#include "sound_func.h"
#include "effectvehicle_func.h"
#include "roadveh.h"
#include "ai/ai.hpp"
#include "game/game.hpp"
#include "company_base.h"
#include "core/random_func.hpp"
#include "core/backup_type.hpp"
#include "table/strings.h"
#include "safeguards.h"
/** Delay counter for considering the next disaster. */
uint16 _disaster_delay;
static void DisasterClearSquare(TileIndex tile)
{
if (EnsureNoVehicleOnGround(tile).Failed()) return;
switch (GetTileType(tile)) {
case MP_RAILWAY:
if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) {
Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
cur_company.Restore();
/* update signals in buffer */
UpdateSignalsInBuffer();
}
break;
case MP_HOUSE: {
Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
cur_company.Restore();
break;
}
case MP_TREES:
case MP_CLEAR:
DoClearSquare(tile);
break;
default:
break;
}
}
static const SpriteID _disaster_images_1[] = {SPR_BLIMP, SPR_BLIMP, SPR_BLIMP, SPR_BLIMP, SPR_BLIMP, SPR_BLIMP, SPR_BLIMP, SPR_BLIMP};
static const SpriteID _disaster_images_2[] = {SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT, SPR_UFO_SMALL_SCOUT};
static const SpriteID _disaster_images_3[] = {SPR_F_15, SPR_F_15, SPR_F_15, SPR_F_15, SPR_F_15, SPR_F_15, SPR_F_15, SPR_F_15};
static const SpriteID _disaster_images_4[] = {SPR_SUB_SMALL_NE, SPR_SUB_SMALL_NE, SPR_SUB_SMALL_SE, SPR_SUB_SMALL_SE, SPR_SUB_SMALL_SW, SPR_SUB_SMALL_SW, SPR_SUB_SMALL_NW, SPR_SUB_SMALL_NW};
static const SpriteID _disaster_images_5[] = {SPR_SUB_LARGE_NE, SPR_SUB_LARGE_NE, SPR_SUB_LARGE_SE, SPR_SUB_LARGE_SE, SPR_SUB_LARGE_SW, SPR_SUB_LARGE_SW, SPR_SUB_LARGE_NW, SPR_SUB_LARGE_NW};
static const SpriteID _disaster_images_6[] = {SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER, SPR_UFO_HARVESTER};
static const SpriteID _disaster_images_7[] = {SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER, SPR_XCOM_SKYRANGER};
static const SpriteID _disaster_images_8[] = {SPR_AH_64A, SPR_AH_64A, SPR_AH_64A, SPR_AH_64A, SPR_AH_64A, SPR_AH_64A, SPR_AH_64A, SPR_AH_64A};
static const SpriteID _disaster_images_9[] = {SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1, SPR_ROTOR_MOVING_1};
static const SpriteID * const _disaster_images[] = {
_disaster_images_1, _disaster_images_1, ///< zeppeliner and zeppeliner shadow
_disaster_images_2, _disaster_images_2, ///< small ufo and small ufo shadow
_disaster_images_3, _disaster_images_3, ///< combat aircraft and shadow
_disaster_images_8, _disaster_images_8, _disaster_images_9, ///< combat helicopter, shadow and rotor
_disaster_images_6, _disaster_images_6, ///< big ufo and shadow
_disaster_images_7, _disaster_images_7, ///< skyranger and shadow
_disaster_images_4, _disaster_images_5, ///< small and big submarine sprites
};
void DisasterVehicle::UpdateImage()
{
SpriteID img = this->image_override;
if (img == 0) img = _disaster_images[this->subtype][this->direction];
this->cur_image = img;
}
/**
* Construct the disaster vehicle.
* @param x The X coordinate.
* @param y The Y coordinate.
* @param direction The direction the vehicle is facing.
* @param subtype The sub type of vehicle.
* @param big_ufo_destroyer_target The target for the UFO destroyer.
*/
DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target) :
SpecializedVehicleBase(), big_ufo_destroyer_target(big_ufo_destroyer_target)
{
this->vehstatus = VS_UNCLICKABLE;
this->x_pos = x;
this->y_pos = y;
switch (subtype) {
case ST_ZEPPELINER:
case ST_SMALL_UFO:
case ST_AIRPLANE:
case ST_HELICOPTER:
case ST_BIG_UFO:
case ST_BIG_UFO_DESTROYER:
GetAircraftFlightLevelBounds(this, &this->z_pos, NULL);
break;
case ST_HELICOPTER_ROTORS:
GetAircraftFlightLevelBounds(this, &this->z_pos, NULL);
this->z_pos += ROTOR_Z_OFFSET;
break;
case ST_SMALL_SUBMARINE:
case ST_BIG_SUBMARINE:
this->z_pos = 0;
break;
case ST_ZEPPELINER_SHADOW:
case ST_SMALL_UFO_SHADOW:
case ST_AIRPLANE_SHADOW:
case ST_HELICOPTER_SHADOW:
case ST_BIG_UFO_SHADOW:
case ST_BIG_UFO_DESTROYER_SHADOW:
this->z_pos = 0;
this->vehstatus |= VS_SHADOW;
break;
}
this->direction = direction;
this->tile = TileVirtXY(x, y);
this->subtype = subtype;
this->UpdateDeltaXY(INVALID_DIR);
this->owner = OWNER_NONE;
this->image_override = 0;
this->current_order.Free();
this->UpdateImage();
this->UpdatePositionAndViewport();
}
/**
* Update the position of the vehicle.
* @param x The new X-coordinate.
* @param y The new Y-coordinate.
* @param z The new Z-coordinate.
*/
void DisasterVehicle::UpdatePosition(int x, int y, int z)
{
this->x_pos = x;
this->y_pos = y;
this->z_pos = z;
this->tile = TileVirtXY(x, y);
this->UpdateImage();
this->UpdatePositionAndViewport();
DisasterVehicle *u = this->Next();
if (u != NULL) {
int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
u->x_pos = x;
u->y_pos = y - 1 - (max(z - GetSlopePixelZ(safe_x, safe_y), 0) >> 3);
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
u->direction = this->direction;
u->UpdateImage();
u->UpdatePositionAndViewport();
if ((u = u->Next()) != NULL) {
u->x_pos = x;
u->y_pos = y;
u->z_pos = z + ROTOR_Z_OFFSET;
u->UpdatePositionAndViewport();
}
}
}
/**
* Zeppeliner handling, v->current_order.dest states:
* 0: Zeppeliner initialization has found a small airport, go there and crash
* 1: Create crash and animate falling down for extra dramatic effect
* 2: Create more smoke and leave debris on ground
* 2: Clear the runway after some time and remove crashed zeppeliner
* If not airport was found, only state 0 is reached until zeppeliner leaves map
*/
static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
{
v->tick_counter++;
if (v->current_order.GetDestination() < 2) {
if (HasBit(v->tick_counter, 0)) return true;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
if (v->current_order.GetDestination() == 1) {
if (++v->age == 38) {
v->current_order.SetDestination(2);
v->age = 0;
}
if (GB(v->tick_counter, 0, 3) == 0) CreateEffectVehicleRel(v, 0, -17, 2, EV_CRASH_SMOKE);
} else if (v->current_order.GetDestination() == 0) {
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
v->current_order.SetDestination(1);
v->age = 0;
SetDParam(0, GetStationIndex(v->tile));
AddVehicleNewsItem(STR_NEWS_DISASTER_ZEPPELIN, NT_ACCIDENT, v->index); // Delete the news, when the zeppelin is gone
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCrashed(GetStationIndex(v->tile)));
}
}
if (v->y_pos >= (int)((MapSizeY() + 9) * TILE_SIZE - 1)) {
delete v;
return false;
}
return true;
}
if (v->current_order.GetDestination() > 2) {
if (++v->age <= 13320) return true;
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
Station *st = Station::GetByTile(v->tile);
CLRBITS(st->airport.flags, RUNWAY_IN_block);
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCleared(st->index));
}
v->UpdatePosition(v->x_pos, v->y_pos, GetAircraftFlightLevel(v));
delete v;
return false;
}
int x = v->x_pos;
int y = v->y_pos;
int z = GetSlopePixelZ(x, y);
if (z < v->z_pos) z = v->z_pos - 1;
v->UpdatePosition(x, y, z);
if (++v->age == 1) {
CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
v->image_override = SPR_BLIMP_CRASHING;
} else if (v->age == 70) {
v->image_override = SPR_BLIMP_CRASHED;
} else if (v->age <= 300) {
if (GB(v->tick_counter, 0, 3) == 0) {
uint32 r = Random();
CreateEffectVehicleRel(v,
GB(r, 0, 4) - 7,
GB(r, 4, 4) - 7,
GB(r, 8, 3) + 5,
EV_EXPLOSION_SMALL);
}
} else if (v->age == 350) {
v->current_order.SetDestination(3);
v->age = 0;
}
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
SETBITS(Station::GetByTile(v->tile)->airport.flags, RUNWAY_IN_block);
}
return true;
}
/**
* (Small) Ufo handling, v->current_order.dest states:
* 0: Fly around to the middle of the map, then randomly, after a while target a road vehicle
* 1: Home in on a road vehicle and crash it >:)
* If not road vehicle was found, only state 0 is used and Ufo disappears after a while
*/
static bool DisasterTick_Ufo(DisasterVehicle *v)
{
v->image_override = (HasBit(++v->tick_counter, 3)) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
if (v->current_order.GetDestination() == 0) {
/* Fly around randomly */
int x = TileX(v->dest_tile) * TILE_SIZE;
int y = TileY(v->dest_tile) * TILE_SIZE;
if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
return true;
}
if (++v->age < 6) {
v->dest_tile = RandomTile();
return true;
}
v->current_order.SetDestination(1);
uint n = 0; // Total number of targetable road vehicles.
RoadVehicle *u;
FOR_ALL_ROADVEHICLES(u) {
if (u->IsFrontEngine()) n++;
}
if (n == 0) {
/* If there are no targetable road vehicles, destroy the UFO. */
delete v;
return false;
}
n = RandomRange(n); // Choose one of them.
FOR_ALL_ROADVEHICLES(u) {
/* Find (n+1)-th road vehicle. */
if (u->IsFrontEngine() && (n-- == 0)) break;
}
/* Target it. */
v->dest_tile = u->index;
v->age = 0;
return true;
} else {
/* Target a vehicle */
RoadVehicle *u = RoadVehicle::Get(v->dest_tile);
assert(u != NULL && u->type == VEH_ROAD && u->IsFrontEngine());
uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos);
if (dist < TILE_SIZE && !(u->vehstatus & VS_HIDDEN) && u->breakdown_ctr == 0) {
u->breakdown_ctr = 3;
u->breakdown_delay = 140;
}
v->direction = GetDirectionTowards(v, u->x_pos, u->y_pos);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
int z = v->z_pos;
if (dist <= TILE_SIZE && z > u->z_pos) z--;
v->UpdatePosition(gp.x, gp.y, z);
if (z <= u->z_pos && (u->vehstatus & VS_HIDDEN) == 0) {
v->age++;
if (u->crashed_ctr == 0) {
u->Crash();
AddVehicleNewsItem(STR_NEWS_DISASTER_SMALL_UFO, NT_ACCIDENT, u->index); // delete the news, when the roadvehicle is gone
AI::NewEvent(u->owner, new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO));
Game::NewEvent(new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO));
}
}
/* Destroy? */
if (v->age > 50) {
CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
delete v;
return false;
}
}
return true;
}
static void DestructIndustry(Industry *i)
{
for (TileIndex tile = 0; tile != MapSize(); tile++) {
if (i->TileBelongsToIndustry(tile)) {
ResetIndustryConstructionStage(tile);
MarkTileDirtyByTile(tile);
}
}
}
/**
* Aircraft handling, v->current_order.dest states:
* 0: Fly towards the targeted industry
* 1: If within 15 tiles, fire away rockets and destroy industry
* 2: Industry explosions
* 3: Fly out of the map
* If the industry was removed in the meantime just fly to the end of the map.
* @param v The disaster vehicle.
* @param image_override The image at the time the aircraft is firing.
* @param leave_at_top True iff the vehicle leaves the map at the north side.
* @param news_message The string that's used as news message.
* @param industry_flag Only attack industries that have this flag set.
*/
static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, bool leave_at_top, StringID news_message, IndustryBehaviour industry_flag)
{
v->tick_counter++;
v->image_override = (v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? image_override : 0;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) {
delete v;
return false;
}
if (v->current_order.GetDestination() == 2) {
if (GB(v->tick_counter, 0, 2) == 0) {
Industry *i = Industry::Get(v->dest_tile); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
int x = TileX(i->location.tile) * TILE_SIZE;
int y = TileY(i->location.tile) * TILE_SIZE;
uint32 r = Random();
CreateEffectVehicleAbove(
GB(r, 0, 6) + x,
GB(r, 6, 6) + y,
GB(r, 12, 4),
EV_EXPLOSION_SMALL);
if (++v->age >= 55) v->current_order.SetDestination(3);
}
} else if (v->current_order.GetDestination() == 1) {
if (++v->age == 112) {
v->current_order.SetDestination(2);
v->age = 0;
Industry *i = Industry::Get(v->dest_tile); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
DestructIndustry(i);
SetDParam(0, i->town->index);
AddIndustryNewsItem(news_message, NT_ACCIDENT, i->index); // delete the news, when the industry closes
if (_settings_client.sound.disaster) SndPlayTileFx(SND_12_EXPLOSION, i->location.tile);
}
} else if (v->current_order.GetDestination() == 0) {
int x = v->x_pos + ((leave_at_top ? -15 : 15) * TILE_SIZE);
int y = v->y_pos;
if ((uint)x > MapMaxX() * TILE_SIZE - 1) return true;
TileIndex tile = TileVirtXY(x, y);
if (!IsTileType(tile, MP_INDUSTRY)) return true;
IndustryID ind = GetIndustryIndex(tile);
v->dest_tile = ind;
if (GetIndustrySpec(Industry::Get(ind)->type)->behaviour & industry_flag) {
v->current_order.SetDestination(1);
v->age = 0;
}
}
return true;
}
/** Airplane handling. */
static bool DisasterTick_Airplane(DisasterVehicle *v)
{
return DisasterTick_Aircraft(v, SPR_F_15_FIRING, true, STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY, INDUSTRYBEH_AIRPLANE_ATTACKS);
}
/** Helicopter handling. */
static bool DisasterTick_Helicopter(DisasterVehicle *v)
{
return DisasterTick_Aircraft(v, SPR_AH_64A_FIRING, false, STR_NEWS_DISASTER_HELICOPTER_FACTORY, INDUSTRYBEH_CHOPPER_ATTACKS);
}
/** Helicopter rotor blades; keep these spinning */
static bool DisasterTick_Helicopter_Rotors(DisasterVehicle *v)
{
v->tick_counter++;
if (HasBit(v->tick_counter, 0)) return true;
if (++v->cur_image > SPR_ROTOR_MOVING_3) v->cur_image = SPR_ROTOR_MOVING_1;
v->UpdatePositionAndViewport();
return true;
}
/**
* (Big) Ufo handling, v->current_order.dest states:
* 0: Fly around to the middle of the map, then randomly for a while and home in on a piece of rail
* 1: Land there and breakdown all trains in a radius of 12 tiles; and now we wait...
* because as soon as the Ufo lands, a fighter jet, a Skyranger, is called to clear up the mess
*/
static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
{
v->tick_counter++;
if (v->current_order.GetDestination() == 1) {
int x = TileX(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
int y = TileY(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
if (Delta(v->x_pos, x) + Delta(v->y_pos, y) >= 8) {
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
return true;
}
if (!IsValidTile(v->dest_tile)) {
/* Make sure we don't land outside the map. */
delete v;
return false;
}
int z = GetSlopePixelZ(v->x_pos, v->y_pos);
if (z < v->z_pos) {
v->UpdatePosition(v->x_pos, v->y_pos, v->z_pos - 1);
return true;
}
v->current_order.SetDestination(2);
Vehicle *target;
FOR_ALL_VEHICLES(target) {
if (target->IsGroundVehicle()) {
if (Delta(target->x_pos, v->x_pos) + Delta(target->y_pos, v->y_pos) <= 12 * (int)TILE_SIZE) {
target->breakdown_ctr = 5;
target->breakdown_delay = 0xF0;
}
}
}
Town *t = ClosestTownFromTile(v->dest_tile, UINT_MAX);
SetDParam(0, t->index);
AddTileNewsItem(STR_NEWS_DISASTER_BIG_UFO, NT_ACCIDENT, v->tile);
if (!Vehicle::CanAllocateItem(2)) {
delete v;
return false;
}
DisasterVehicle *u = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER, v->index);
DisasterVehicle *w = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER_SHADOW);
u->SetNext(w);
} else if (v->current_order.GetDestination() == 0) {
int x = TileX(v->dest_tile) * TILE_SIZE;
int y = TileY(v->dest_tile) * TILE_SIZE;
if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
return true;
}
if (++v->age < 6) {
v->dest_tile = RandomTile();
return true;
}
v->current_order.SetDestination(1);
TileIndex tile_org = RandomTile();
TileIndex tile = tile_org;
do {
if (IsPlainRailTile(tile) &&
Company::IsHumanID(GetTileOwner(tile))) {
break;
}
tile = TILE_MASK(tile + 1);
} while (tile != tile_org);
v->dest_tile = tile;
v->age = 0;
}
return true;
}
/**
* Skyranger destroying (Big) Ufo handling, v->current_order.dest states:
* 0: Home in on landed Ufo and shoot it down
*/
static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
{
v->tick_counter++;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v));
if (gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) {
delete v;
return false;
}
if (v->current_order.GetDestination() == 0) {
Vehicle *u = Vehicle::Get(v->big_ufo_destroyer_target);
if (Delta(v->x_pos, u->x_pos) > (int)TILE_SIZE) return true;
v->current_order.SetDestination(1);
CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, u);
delete u;
for (int i = 0; i != 80; i++) {
uint32 r = Random();
CreateEffectVehicleAbove(
GB(r, 0, 6) + v->x_pos - 32,
GB(r, 5, 6) + v->y_pos - 32,
0,
EV_EXPLOSION_SMALL);
}
for (int dy = -3; dy < 3; dy++) {
for (int dx = -3; dx < 3; dx++) {
TileIndex tile = TileAddWrap(v->tile, dx, dy);
if (tile != INVALID_TILE) DisasterClearSquare(tile);
}
}
}
return true;
}
/**
* Submarine, v->current_order.dest states:
* Unused, just float around aimlessly and pop up at different places, turning around
*/
static bool DisasterTick_Submarine(DisasterVehicle *v)
{
v->tick_counter++;
if (++v->age > 8880) {
delete v;
return false;
}
if (!HasBit(v->tick_counter, 0)) return true;
TileIndex tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
if (IsValidTile(tile)) {
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
if (trackbits == TRACK_BIT_ALL && !Chance16(1, 90)) {
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->UpdatePosition(gp.x, gp.y, v->z_pos);
return true;
}
}
v->direction = ChangeDir(v->direction, GB(Random(), 0, 1) ? DIRDIFF_90RIGHT : DIRDIFF_90LEFT);
return true;
}
static bool DisasterTick_NULL(DisasterVehicle *v)
{
return true;
}
typedef bool DisasterVehicleTickProc(DisasterVehicle *v);
static DisasterVehicleTickProc * const _disastervehicle_tick_procs[] = {
DisasterTick_Zeppeliner, DisasterTick_NULL,
DisasterTick_Ufo, DisasterTick_NULL,
DisasterTick_Airplane, DisasterTick_NULL,
DisasterTick_Helicopter, DisasterTick_NULL, DisasterTick_Helicopter_Rotors,
DisasterTick_Big_Ufo, DisasterTick_NULL, DisasterTick_Big_Ufo_Destroyer,
DisasterTick_NULL,
DisasterTick_Submarine,
DisasterTick_Submarine,
};
bool DisasterVehicle::Tick()
{
return _disastervehicle_tick_procs[this->subtype](this);
}
typedef void DisasterInitProc();
/**
* Zeppeliner which crashes on a small airport if one found,
* otherwise crashes on a random tile
*/
static void Disaster_Zeppeliner_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
/* Pick a random place, unless we find a small airport */
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
Station *st;
FOR_ALL_STATIONS(st) {
if (st->airport.tile != INVALID_TILE && (st->airport.type == AT_SMALL || st->airport.type == AT_LARGE)) {
x = (TileX(st->airport.tile) + 2) * TILE_SIZE;
break;
}
}
DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_ZEPPELINER);
/* Allocate shadow */
DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_ZEPPELINER_SHADOW);
v->SetNext(u);
}
/**
* Ufo which flies around aimlessly from the middle of the map a bit
* until it locates a road vehicle which it targets and then destroys
*/
static void Disaster_Small_Ufo_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO);
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
/* Allocate shadow */
DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO_SHADOW);
v->SetNext(u);
}
/* Combat airplane which destroys an oil refinery */
static void Disaster_Airplane_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
Industry *i, *found = NULL;
FOR_ALL_INDUSTRIES(i) {
if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_AIRPLANE_ATTACKS) &&
(found == NULL || Chance16(1, 2))) {
found = i;
}
}
if (found == NULL) return;
/* Start from the bottom (south side) of the map */
int x = (MapSizeX() + 9) * TILE_SIZE - 1;
int y = TileY(found->location.tile) * TILE_SIZE + 37;
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE);
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE_SHADOW);
v->SetNext(u);
}
/** Combat helicopter that destroys a factory */
static void Disaster_Helicopter_Init()
{
if (!Vehicle::CanAllocateItem(3)) return;
Industry *i, *found = NULL;
FOR_ALL_INDUSTRIES(i) {
if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CHOPPER_ATTACKS) &&
(found == NULL || Chance16(1, 2))) {
found = i;
}
}
if (found == NULL) return;
int x = -16 * (int)TILE_SIZE;
int y = TileY(found->location.tile) * TILE_SIZE + 37;
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER);
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER_SHADOW);
v->SetNext(u);
DisasterVehicle *w = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER_ROTORS);
u->SetNext(w);
}
/* Big Ufo which lands on a piece of rail and will consequently be shot
* down by a combat airplane, destroying the surroundings */
static void Disaster_Big_Ufo_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
int y = MapMaxX() * TILE_SIZE - 1;
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO);
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
/* Allocate shadow */
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO_SHADOW);
v->SetNext(u);
}
static void Disaster_Submarine_Init(DisasterSubType subtype)
{
if (!Vehicle::CanAllocateItem()) return;
int y;
Direction dir;
uint32 r = Random();
int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2;
if (HasBit(r, 31)) {
y = MapMaxY() * TILE_SIZE - TILE_SIZE / 2 - 1;
dir = DIR_NW;
} else {
y = TILE_SIZE / 2;
if (_settings_game.construction.freeform_edges) y += TILE_SIZE;
dir = DIR_SE;
}
if (!IsWaterTile(TileVirtXY(x, y))) return;
new DisasterVehicle(x, y, dir, subtype);
}
/* Curious submarine #1, just floats around */
static void Disaster_Small_Submarine_Init()
{
Disaster_Submarine_Init(ST_SMALL_SUBMARINE);
}
/* Curious submarine #2, just floats around */
static void Disaster_Big_Submarine_Init()
{
Disaster_Submarine_Init(ST_BIG_SUBMARINE);
}
/**
* Coal mine catastrophe, destroys a stretch of 30 tiles of
* land in a certain direction
*/
static void Disaster_CoalMine_Init()
{
int index = GB(Random(), 0, 4);
uint m;
for (m = 0; m < 15; m++) {
const Industry *i;
FOR_ALL_INDUSTRIES(i) {
if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) {
SetDParam(0, i->town->index);
AddTileNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, NT_ACCIDENT, i->location.tile + TileDiffXY(1, 1)); // keep the news, even when the mine closes
{
TileIndex tile = i->location.tile;
TileIndexDiff step = TileOffsByDiagDir((DiagDirection)GB(Random(), 0, 2));
for (uint n = 0; n < 30; n++) {
DisasterClearSquare(tile);
tile += step;
if (!IsValidTile(tile)) break;
}
}
return;
}
}
}
}
struct Disaster {
DisasterInitProc *init_proc; ///< The init function for this disaster.
Year min_year; ///< The first year this disaster will occur.
Year max_year; ///< The last year this disaster will occur.
};
static const Disaster _disasters[] = {
{Disaster_Zeppeliner_Init, 1930, 1955}, // zeppeliner
{Disaster_Small_Ufo_Init, 1940, 1970}, // ufo (small)
{Disaster_Airplane_Init, 1960, 1990}, // airplane
{Disaster_Helicopter_Init, 1970, 2000}, // helicopter
{Disaster_Big_Ufo_Init, 2000, 2100}, // ufo (big)
{Disaster_Small_Submarine_Init, 1940, 1965}, // submarine (small)
{Disaster_Big_Submarine_Init, 1975, 2010}, // submarine (big)
{Disaster_CoalMine_Init, 1950, 1985}, // coalmine
};
static void DoDisaster()
{
byte buf[lengthof(_disasters)];
byte j = 0;
for (size_t i = 0; i != lengthof(_disasters); i++) {
if (_cur_year >= _disasters[i].min_year && _cur_year < _disasters[i].max_year) buf[j++] = (byte)i;
}
if (j == 0) return;
_disasters[buf[RandomRange(j)]].init_proc();
}
static void ResetDisasterDelay()
{
_disaster_delay = GB(Random(), 0, 9) + 730;
}
void DisasterDailyLoop()
{
if (--_disaster_delay != 0) return;
ResetDisasterDelay();
if (_settings_game.difficulty.disasters != 0) DoDisaster();
}
void StartupDisasters()
{
ResetDisasterDelay();
}
/**
* Marks all disasters targeting this industry in such a way
* they won't call Industry::Get(v->dest_tile) on invalid industry anymore.
* @param i deleted industry
*/
void ReleaseDisastersTargetingIndustry(IndustryID i)
{
DisasterVehicle *v;
FOR_ALL_DISASTERVEHICLES(v) {
/* primary disaster vehicles that have chosen target */
if (v->subtype == ST_AIRPLANE || v->subtype == ST_HELICOPTER) {
/* if it has chosen target, and it is this industry (yes, dest_tile is IndustryID here), set order to "leaving map peacefully" */
if (v->current_order.GetDestination() > 0 && v->dest_tile == i) v->current_order.SetDestination(3);
}
}
}
/**
* Notify disasters that we are about to delete a vehicle. So make them head elsewhere.
* @param vehicle deleted vehicle
*/
void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
{
DisasterVehicle *v;
FOR_ALL_DISASTERVEHICLES(v) {
/* primary disaster vehicles that have chosen target */
if (v->subtype == ST_SMALL_UFO) {
if (v->current_order.GetDestination() != 0 && v->dest_tile == vehicle) {
/* Revert to target-searching */
v->current_order.SetDestination(0);
v->dest_tile = RandomTile();
GetAircraftFlightLevelBounds(v, &v->z_pos, NULL);
v->age = 0;
}
}
}
}
void DisasterVehicle::UpdateDeltaXY(Direction direction)
{
this->x_offs = -1;
this->y_offs = -1;
this->x_extent = 2;
this->y_extent = 2;
this->z_extent = 5;
}

62
src/disaster_vehicle.h Normal file
View File

@@ -0,0 +1,62 @@
/* $Id: disaster_vehicle.h 26872 2014-09-21 11:12:42Z rubidium $ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file disaster_vehicle.h All disaster vehicles. */
#ifndef DISASTER_VEHICLE_H
#define DISASTER_VEHICLE_H
#include "vehicle_base.h"
/** Different sub types of disaster vehicles. */
enum DisasterSubType {
ST_ZEPPELINER, ///< Zeppelin, crashes at airports.
ST_ZEPPELINER_SHADOW, ///< Shadow of the zeppelin.
ST_SMALL_UFO, ///< Small UFO, tries to find a road vehicle to destroy.
ST_SMALL_UFO_SHADOW, ///< Shadow of small UFO
ST_AIRPLANE, ///< Airplane destroying an oil refinery
ST_AIRPLANE_SHADOW, ///< Shadow of airplane
ST_HELICOPTER, ///< Helicopter destroying a factory.
ST_HELICOPTER_SHADOW, ///< Shadow of helicopter.
ST_HELICOPTER_ROTORS, ///< Rotors of helicopter.
ST_BIG_UFO, ///< Big UFO, finds a piece of railroad to "park" on
ST_BIG_UFO_SHADOW, ///< Shadow of the big UFO
ST_BIG_UFO_DESTROYER, ///< Aircraft the will bomb the big UFO
ST_BIG_UFO_DESTROYER_SHADOW, ///< Shadow of the aircraft.
ST_SMALL_SUBMARINE, ///< Small submarine, pops up in the oceans but doesn't do anything
ST_BIG_SUBMARINE, ///< Big submarine, pops up in the oceans but doesn't do anything
};
/**
* Disasters, like submarines, skyrangers and their shadows, belong to this class.
*/
struct DisasterVehicle FINAL : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
SpriteID image_override; ///< Override for the default disaster vehicle sprite.
VehicleID big_ufo_destroyer_target; ///< The big UFO that this destroyer is supposed to bomb.
byte flags; ///< Flags about the state of the vehicle, @see AirVehicleFlags
/** For use by saveload. */
DisasterVehicle() : SpecializedVehicleBase() {}
DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target = VEH_INVALID);
/** We want to 'destruct' the right class. */
virtual ~DisasterVehicle() {}
void UpdatePosition(int x, int y, int z);
void UpdateDeltaXY(Direction direction);
void UpdateImage();
bool Tick();
};
/**
* Iterate over disaster vehicles.
* @param var The variable used to iterate over.
*/
#define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
#endif /* DISASTER_VEHICLE_H */

5288
src/lang/latin.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,7 @@ bool IsReleasedVersion()
* norev000 is for non-releases that are made on systems without
* subversion or sources that are not a checkout of subversion.
*/
const char _openttd_revision[] = "h08633bf1M-openttd";
const char _openttd_revision[] = "1.5.0-rc1";
/**
* The text version of OpenTTD's build date.
@@ -72,11 +72,11 @@ const byte _openttd_revision_modified = 2;
* final release will always have a lower version number than the released
* version, thus making comparisons on specific revisions easy.
*/
const uint32 _openttd_newgrf_version = 1 << 28 | 5 << 24 | 0 << 20 | 0 << 19 | (0 & ((1 << 19) - 1));
const uint32 _openttd_newgrf_version = 1 << 28 | 5 << 24 | 0 << 20 | 0 << 19 | (27196 & ((1 << 19) - 1));
#ifdef __MORPHOS__
/**
* Variable used by MorphOS to show the version.
*/
extern const char morphos_versions_tag[] = "$VER: OpenTTD h08633bf1M-openttd (16.03.15) OpenTTD Team [MorphOS, PowerPC]";
extern const char morphos_versions_tag[] = "$VER: OpenTTD h9213ee54M-openttd (19.03.15) OpenTTD Team [MorphOS, PowerPC]";
#endif

74
src/safeguards.h Normal file
View File

@@ -0,0 +1,74 @@
/* $Id: safeguards.h 26651 2014-06-17 19:01:45Z rubidium $ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file safeguards.h A number of safeguards to prevent using unsafe methods.
*
* Unsafe methods are, for example, strndup and strncpy because they may leave the
* string without a null termination, but also strdup and strndup because they can
* return NULL and then all strdups would need to be guarded against that instead
* of using the current MallocT/ReallocT/CallocT technique of just giving the user
* an error that too much memory was used instead of spreading that code though
* the whole code base.
*/
#ifndef SAFEGUARDS_H
#define SAFEGUARDS_H
/* Use MallocT instead. */
#define malloc SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use MallocT instead. */
#define calloc SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use ReallocT instead. */
#define realloc SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use stredup instead. */
#define strdup SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define strndup SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use strecpy instead. */
#define strcpy SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define strncpy SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use strecat instead. */
#define strcat SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define strncat SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use seprintf instead. */
#define sprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define snprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use vseprintf instead. */
#define vsprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define vsnprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use fgets instead. */
#define gets SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* No clear replacement. */
#define strtok SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use our own templated implementation instead of a macro or function with only one type. */
#ifdef min
#undef min
#endif
/* Use our own templated implementation instead of a macro or function with only one type. */
#ifdef max
#undef max
#endif
/* Use our own templated implementation instead of a macro or function with only one type. */
#ifdef abs
#undef abs
#endif
#endif /* SAFEGUARDS_H */

View File

@@ -0,0 +1,344 @@
/* $Id: heightmap_colours.h 26930 2014-09-27 14:51:34Z rubidium $ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file heightmap_colours.h The colour tables for heightmaps.
*/
/** Height map colours for the green colour scheme, ordered by height. */
static const uint32 _green_map_heights[] = {
MKCOLOUR(0x59595958),
MKCOLOUR(0x59595958),
MKCOLOUR(0x59595959),
MKCOLOUR(0x5959595A),
MKCOLOUR(0x59595A59),
MKCOLOUR(0x59595A5A),
MKCOLOUR(0x595A5959),
MKCOLOUR(0x595A595A),
MKCOLOUR(0x595A5A59),
MKCOLOUR(0x595A5A5A),
MKCOLOUR(0x5A595959),
MKCOLOUR(0x5A59595A),
MKCOLOUR(0x5A595A59),
MKCOLOUR(0x5A595A5A),
MKCOLOUR(0x5A5A5959),
MKCOLOUR(0x5A5A595A),
MKCOLOUR(0x5A5A5A59),
MKCOLOUR(0x5A5A5A5A),
MKCOLOUR(0x5A5A5A5B),
MKCOLOUR(0x5A5A5B5A),
MKCOLOUR(0x5A5A5B5B),
MKCOLOUR(0x5A5B5A5A),
MKCOLOUR(0x5A5B5A5B),
MKCOLOUR(0x5A5B5B5A),
MKCOLOUR(0x5A5B5B5B),
MKCOLOUR(0x5B5A5A5A),
MKCOLOUR(0x5B5A5A5B),
MKCOLOUR(0x5B5A5B5A),
MKCOLOUR(0x5B5A5B5B),
MKCOLOUR(0x5B5B5A5A),
MKCOLOUR(0x5B5B5A5B),
MKCOLOUR(0x5B5B5B5B),
MKCOLOUR(0x5B5B5B5C),
MKCOLOUR(0x5B5B5C5B),
MKCOLOUR(0x5B5B5C5C),
MKCOLOUR(0x5B5C5B5B),
MKCOLOUR(0x5B5C5B5C),
MKCOLOUR(0x5B5C5C5B),
MKCOLOUR(0x5B5C5C5C),
MKCOLOUR(0x5C5B5B5B),
MKCOLOUR(0x5C5B5B5C),
MKCOLOUR(0x5C5B5C5B),
MKCOLOUR(0x5C5B5C5C),
MKCOLOUR(0x5C5C5B5B),
MKCOLOUR(0x5C5C5B5C),
MKCOLOUR(0x5C5C5C5C),
MKCOLOUR(0x5C5C5C5D),
MKCOLOUR(0x5C5C5D5C),
MKCOLOUR(0x5C5C5D5D),
MKCOLOUR(0x5C5D5C5C),
MKCOLOUR(0x5C5D5C5D),
MKCOLOUR(0x5C5D5D5C),
MKCOLOUR(0x5C5D5D5D),
MKCOLOUR(0x5D5C5C5C),
MKCOLOUR(0x5D5C5C5D),
MKCOLOUR(0x5D5C5D5C),
MKCOLOUR(0x5D5C5D5D),
MKCOLOUR(0x5D5D5C5C),
MKCOLOUR(0x5D5D5C5D),
MKCOLOUR(0x5D5D5D5D),
MKCOLOUR(0x5D5D5D5E),
MKCOLOUR(0x5D5D5E5D),
MKCOLOUR(0x5D5D5E5E),
MKCOLOUR(0x5D5E5D5D),
MKCOLOUR(0x5D5E5D5E),
MKCOLOUR(0x5D5E5E5D),
MKCOLOUR(0x5D5E5E5E),
MKCOLOUR(0x5E5D5D5D),
MKCOLOUR(0x5E5D5D5E),
MKCOLOUR(0x5E5D5E5D),
MKCOLOUR(0x5E5D5E5E),
MKCOLOUR(0x5E5D5D5D),
MKCOLOUR(0x5E5D5D5E),
MKCOLOUR(0x5E5E5E5E),
MKCOLOUR(0x5E5E5E5F),
MKCOLOUR(0x5E5E5F5E),
MKCOLOUR(0x5E5E5F5F),
MKCOLOUR(0x5E5F5E5E),
MKCOLOUR(0x5E5F5E5F),
MKCOLOUR(0x5E5F5F5E),
MKCOLOUR(0x5E5F5F5F),
MKCOLOUR(0x5F5E5E5E),
MKCOLOUR(0x5F5E5E5F),
MKCOLOUR(0x5F5E5F5E),
MKCOLOUR(0x5F5E5F5F),
MKCOLOUR(0x5F5F5E5E),
MKCOLOUR(0x5F5F5E5F),
MKCOLOUR(0x5F5F5F5F),
MKCOLOUR(0x5F5F5F1F),
MKCOLOUR(0x5F5F1F5F),
MKCOLOUR(0x5F5F1F1F),
MKCOLOUR(0x5F1F5F1F),
MKCOLOUR(0x5F1F1F1F),
MKCOLOUR(0x1F5F5F5F),
MKCOLOUR(0x1F5F5F1F),
MKCOLOUR(0x1F5F1F5F),
MKCOLOUR(0x1F5F1F1F),
MKCOLOUR(0x1F1F5F5F),
MKCOLOUR(0x1F1F5F1F),
MKCOLOUR(0x1F1F1F5F),
MKCOLOUR(0x1F1F1F1F),
MKCOLOUR(0x1F1F1F27),
MKCOLOUR(0x1F1F271F),
MKCOLOUR(0x1F1F2727),
MKCOLOUR(0x1F271F1F),
MKCOLOUR(0x1F271F27),
MKCOLOUR(0x1F272727),
MKCOLOUR(0x271F1F1F),
MKCOLOUR(0x271F1F27),
MKCOLOUR(0x271F271F),
MKCOLOUR(0x271F2727),
MKCOLOUR(0x27271F1F),
MKCOLOUR(0x27271F27),
MKCOLOUR(0x2727271F),
MKCOLOUR(0x27272727),
};
/** Height map colours for the dark green colour scheme, ordered by height. */
static const uint32 _dark_green_map_heights[] = {
MKCOLOUR(0x60606060),
MKCOLOUR(0x60606061),
MKCOLOUR(0x60606160),
MKCOLOUR(0x60606161),
MKCOLOUR(0x60616060),
MKCOLOUR(0x60616061),
MKCOLOUR(0x60616160),
MKCOLOUR(0x60616161),
MKCOLOUR(0x61606060),
MKCOLOUR(0x61606061),
MKCOLOUR(0x61606160),
MKCOLOUR(0x61606161),
MKCOLOUR(0x61616060),
MKCOLOUR(0x61616061),
MKCOLOUR(0x61616160),
MKCOLOUR(0x61616161),
MKCOLOUR(0x61616162),
MKCOLOUR(0x61616261),
MKCOLOUR(0x61616262),
MKCOLOUR(0x61626161),
MKCOLOUR(0x61626162),
MKCOLOUR(0x61626261),
MKCOLOUR(0x61626262),
MKCOLOUR(0x62616161),
MKCOLOUR(0x62616162),
MKCOLOUR(0x62616261),
MKCOLOUR(0x62616262),
MKCOLOUR(0x62626161),
MKCOLOUR(0x62626162),
MKCOLOUR(0x62626261),
MKCOLOUR(0x62626262),
MKCOLOUR(0x62626263),
MKCOLOUR(0x62626362),
MKCOLOUR(0x62626363),
MKCOLOUR(0x62636262),
MKCOLOUR(0x62636263),
MKCOLOUR(0x62636362),
MKCOLOUR(0x62636363),
MKCOLOUR(0x63626262),
MKCOLOUR(0x63626263),
MKCOLOUR(0x63626362),
MKCOLOUR(0x63626363),
MKCOLOUR(0x63636262),
MKCOLOUR(0x63636263),
MKCOLOUR(0x63636362),
MKCOLOUR(0x63636363),
MKCOLOUR(0x63636364),
MKCOLOUR(0x63636463),
MKCOLOUR(0x63636464),
MKCOLOUR(0x63646363),
MKCOLOUR(0x63646364),
MKCOLOUR(0x63646463),
MKCOLOUR(0x63646464),
MKCOLOUR(0x64636363),
MKCOLOUR(0x64636364),
MKCOLOUR(0x64636463),
MKCOLOUR(0x64636464),
MKCOLOUR(0x64646363),
MKCOLOUR(0x64646364),
MKCOLOUR(0x64646463),
MKCOLOUR(0x64646464),
MKCOLOUR(0x64646465),
MKCOLOUR(0x64646564),
MKCOLOUR(0x64646565),
MKCOLOUR(0x64656464),
MKCOLOUR(0x64656465),
MKCOLOUR(0x64656564),
MKCOLOUR(0x64656565),
MKCOLOUR(0x65646464),
MKCOLOUR(0x65646465),
MKCOLOUR(0x65646564),
MKCOLOUR(0x65646565),
MKCOLOUR(0x65656464),
MKCOLOUR(0x65656465),
MKCOLOUR(0x65656564),
MKCOLOUR(0x65656565),
MKCOLOUR(0x65656566),
MKCOLOUR(0x65656665),
MKCOLOUR(0x65656666),
MKCOLOUR(0x65666565),
MKCOLOUR(0x65666566),
MKCOLOUR(0x65666665),
MKCOLOUR(0x65666666),
MKCOLOUR(0x66656565),
MKCOLOUR(0x66656566),
MKCOLOUR(0x66656665),
MKCOLOUR(0x66656666),
MKCOLOUR(0x66666565),
MKCOLOUR(0x66666566),
MKCOLOUR(0x66666665),
MKCOLOUR(0x66666666),
MKCOLOUR(0x66666667),
MKCOLOUR(0x66666766),
MKCOLOUR(0x66666767),
MKCOLOUR(0x66676666),
MKCOLOUR(0x66676667),
MKCOLOUR(0x66676766),
MKCOLOUR(0x66676767),
MKCOLOUR(0x67676767),
};
/** Height map colours for the violet colour scheme, ordered by height. */
static const uint32 _violet_map_heights[] = {
MKCOLOUR(0x80808080),
MKCOLOUR(0x80808081),
MKCOLOUR(0x80808180),
MKCOLOUR(0x80808181),
MKCOLOUR(0x80818080),
MKCOLOUR(0x80818081),
MKCOLOUR(0x80818180),
MKCOLOUR(0x80818181),
MKCOLOUR(0x81808080),
MKCOLOUR(0x81808081),
MKCOLOUR(0x81808180),
MKCOLOUR(0x81808181),
MKCOLOUR(0x81818080),
MKCOLOUR(0x81818081),
MKCOLOUR(0x81818180),
MKCOLOUR(0x81818181),
MKCOLOUR(0x81818182),
MKCOLOUR(0x81818281),
MKCOLOUR(0x81818282),
MKCOLOUR(0x81828181),
MKCOLOUR(0x81828182),
MKCOLOUR(0x81828281),
MKCOLOUR(0x81828282),
MKCOLOUR(0x82818181),
MKCOLOUR(0x82818182),
MKCOLOUR(0x82818281),
MKCOLOUR(0x82818282),
MKCOLOUR(0x82828181),
MKCOLOUR(0x82828182),
MKCOLOUR(0x82828281),
MKCOLOUR(0x82828282),
MKCOLOUR(0x82828283),
MKCOLOUR(0x82828382),
MKCOLOUR(0x82828383),
MKCOLOUR(0x82838282),
MKCOLOUR(0x82838283),
MKCOLOUR(0x82838382),
MKCOLOUR(0x82838383),
MKCOLOUR(0x83828282),
MKCOLOUR(0x83828283),
MKCOLOUR(0x83828382),
MKCOLOUR(0x83828383),
MKCOLOUR(0x83838282),
MKCOLOUR(0x83838283),
MKCOLOUR(0x83838382),
MKCOLOUR(0x83838383),
MKCOLOUR(0x83838384),
MKCOLOUR(0x83838483),
MKCOLOUR(0x83838484),
MKCOLOUR(0x83848383),
MKCOLOUR(0x83848384),
MKCOLOUR(0x83848483),
MKCOLOUR(0x83848484),
MKCOLOUR(0x84838383),
MKCOLOUR(0x84838384),
MKCOLOUR(0x84838483),
MKCOLOUR(0x84838484),
MKCOLOUR(0x84848383),
MKCOLOUR(0x84848384),
MKCOLOUR(0x84848483),
MKCOLOUR(0x84848484),
MKCOLOUR(0x84848485),
MKCOLOUR(0x84848584),
MKCOLOUR(0x84848585),
MKCOLOUR(0x84858484),
MKCOLOUR(0x84858485),
MKCOLOUR(0x84858584),
MKCOLOUR(0x84858585),
MKCOLOUR(0x85848484),
MKCOLOUR(0x85848485),
MKCOLOUR(0x85848584),
MKCOLOUR(0x85848585),
MKCOLOUR(0x85858484),
MKCOLOUR(0x85858485),
MKCOLOUR(0x85858584),
MKCOLOUR(0x85858585),
MKCOLOUR(0x85858586),
MKCOLOUR(0x85858685),
MKCOLOUR(0x85858686),
MKCOLOUR(0x85868585),
MKCOLOUR(0x85868586),
MKCOLOUR(0x85868685),
MKCOLOUR(0x85868686),
MKCOLOUR(0x85868585),
MKCOLOUR(0x85868586),
MKCOLOUR(0x85868685),
MKCOLOUR(0x85868686),
MKCOLOUR(0x86868585),
MKCOLOUR(0x86868586),
MKCOLOUR(0x86868685),
MKCOLOUR(0x86868686),
MKCOLOUR(0x86868687),
MKCOLOUR(0x86868786),
MKCOLOUR(0x86868787),
MKCOLOUR(0x86878686),
MKCOLOUR(0x86878687),
MKCOLOUR(0x86878786),
MKCOLOUR(0x86878787),
MKCOLOUR(0x87868686),
MKCOLOUR(0x87868687),
MKCOLOUR(0x87868786),
MKCOLOUR(0x87868787),
MKCOLOUR(0x87878686),
MKCOLOUR(0x87878687),
MKCOLOUR(0x87878786),
MKCOLOUR(0x87878787),
};