summaryrefslogtreecommitdiff
path: root/newgrf_station.c
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2006-04-19 07:17:00 +0000
committerpeter1138 <peter1138@openttd.org>2006-04-19 07:17:00 +0000
commitde84d6338d50a35aaee6ae296c796ed3e55b4435 (patch)
tree49a389f05f9514e1b67682db1c98f548340fa20f /newgrf_station.c
parent225f7dcb6211a094cc72f749d7c2e6562708e3cf (diff)
downloadopenttd-de84d6338d50a35aaee6ae296c796ed3e55b4435.tar.xz
(svn r4473) - Newstations:
- Alter parameters of CMD_BUILD_RAILROAD_STATION to accept a custom station class and id. - Add a dynamically allocated list of custom stations that the SpecIndex (m4) references.
Diffstat (limited to 'newgrf_station.c')
-rw-r--r--newgrf_station.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/newgrf_station.c b/newgrf_station.c
index 114152b26..ce336c6ae 100644
--- a/newgrf_station.c
+++ b/newgrf_station.c
@@ -7,6 +7,7 @@
#include "debug.h"
#include "sprite.h"
#include "station.h"
+#include "station_map.h"
#include "newgrf_station.h"
static StationClass station_classes[STAT_CLASS_MAX];
@@ -70,6 +71,17 @@ StationClassID AllocateStationClass(uint32 class)
}
/**
+ * Get the number of station classes in use.
+ * @return Number of station classes.
+ */
+uint GetNumStationClasses(void)
+{
+ uint i;
+ for (i = 0; i < STAT_CLASS_MAX && station_classes[i].id != 0; i++);
+ return i;
+}
+
+/**
* Return the number of stations for the given station class.
* @param sclass Index of the station class.
* @return Number of stations in the class.
@@ -198,3 +210,94 @@ uint32 GetCustomStationRelocation(const StationSpec *spec, const Station *st, by
* emergency measure. */
return 0;
}
+
+
+/**
+ * Allocate a StationSpec to a Station. This is called once per build operation.
+ * @param spec StationSpec to allocate.
+ * @param st Station to allocate it to.
+ * @param exec Whether to actually allocate the spec.
+ * @return Index within the Station's spec list, or -1 if the allocation failed.
+ */
+int AllocateSpecToStation(const StationSpec *spec, Station *st, bool exec)
+{
+ uint i;
+
+ if (spec == NULL) return 0;
+
+ /* Check if this spec has already been allocated */
+ for (i = 1; i < st->num_specs && i < 256; i++) {
+ if (st->speclist[i].spec == spec) return i;
+ }
+
+ for (i = 1; i < st->num_specs && i < 256; i++) {
+ if (st->speclist[i].spec == NULL && st->speclist[i].grfid == 0) break;
+ }
+
+ if (i < 256) {
+ if (exec) {
+ if (i >= st->num_specs) {
+ st->num_specs = i + 1;
+ st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
+
+ if (st->num_specs == 2) {
+ /* Initial allocation */
+ st->speclist[0].spec = NULL;
+ st->speclist[0].grfid = 0;
+ st->speclist[0].localidx = 0;
+ }
+ }
+
+ st->speclist[i].spec = spec;
+ st->speclist[i].grfid = spec->grfid;
+ st->speclist[i].localidx = spec->localidx;
+ }
+ return i;
+ }
+
+ return -1;
+}
+
+
+/** Deallocate a StationSpec from a Station. Called when removing a single station tile.
+ * @param st Station to work with.
+ * @param specindex Index of the custom station within the Station's spec list.
+ * @return Indicates whether the StationSpec was deallocated.
+ */
+bool DeallocateSpecFromStation(Station *st, byte specindex)
+{
+ bool freeable = true;
+
+ /* specindex of 0 (default) is never freeable */
+ if (specindex == 0) return false;
+
+ /* Check all tiles over the station to check if the specindex is still in use */
+ BEGIN_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile) {
+ if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st->index && IsRailwayStation(tile) && GetCustomStationSpecIndex(tile) == specindex) {
+ freeable = false;
+ break;
+ }
+ } END_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile)
+
+ if (freeable) {
+ /* This specindex is no longer in use, so deallocate it */
+ st->speclist[specindex].spec = NULL;
+ st->speclist[specindex].grfid = 0;
+ st->speclist[specindex].localidx = 0;
+
+ /* If this was the highest spec index, reallocate */
+ if (specindex == st->num_specs - 1) {
+ for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--);
+
+ if (st->num_specs > 1) {
+ st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
+ } else {
+ free(st->speclist);
+ st->num_specs = 0;
+ st->speclist = NULL;
+ }
+ }
+ }
+
+ return freeable;
+}