| version 1.14 | | version 1.15 |
|---|
| | |
| /* | | /* |
| * static char *rcsid_weather_c = | | * static char *rcsid_weather_c = |
| * "$Id: weather.c,v 1.14 2002/11/26 10:00:08 garbled Exp $"; | | * "$Id: weather.c,v 1.15 2002/11/26 21:53:29 garbled Exp $"; |
| */ | | */ |
| /* | | /* |
| CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | | |
| | | Copyright (C) 2002 Tim Rightnour |
| Copyright (C) 2002 Mark Wedel & Crossfire Development Team | | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
| Copyright (C) 1992 Frank Tore Johansen | | Copyright (C) 1992 Frank Tore Johansen |
| | | |
| | |
| The authors can be reached via e-mail to crossfire-devel@real-time.com | | The authors can be reached via e-mail to crossfire-devel@real-time.com |
| */ | | */ |
| | | |
| | | /* This weather system was written for crossfire by Tim Rightnour */ |
| | | |
| #include <global.h> | | #include <global.h> |
| #include <tod.h> | | #include <tod.h> |
| #include <map.h> | | #include <map.h> |
| | |
| {NULL, 0} | | {NULL, 0} |
| }; | | }; |
| | | |
| | | /* |
| | | * The table below is used in let_it_snow() and singing_in_the_rain() to |
| | | * decide what type of snow/rain/etc arch to put down. The first field is the |
| | | * name of the arch we want to match. The second field is the special snow |
| | | * type we use to cover that arch. The third field is the doublestack arch, |
| | | * NULL if none, used to stack over the snow after covering the tile. |
| | | * The fourth field is 1 if you want to match arch->name, 0 to match ob->name. |
| | | */ |
| | | |
| | | weather_replace_t weather_replace[] = { |
| | | {"impossible_match", "snow", NULL, 0}, |
| | | {"impossible_match2", "snow2", NULL, 0}, /* placeholders */ |
| | | {"hills", "drifts", NULL, 0}, |
| | | {"cobblestones", "snow4", NULL, 0}, |
| | | {"cobblestones2", "snow4", NULL, 1}, |
| | | {"stones", "snow4", NULL, 0}, |
| | | {"flagstone", "snow4", NULL, 0}, |
| | | {"stonefloor2", "snow4", NULL, 0}, |
| | | {"wasteland", "glacier", NULL, 0}, |
| | | {"evergreens", NULL, "evergreens2", 1}, |
| | | {"evergreen", NULL, "tree5", 0}, |
| | | {"tree", NULL, "tree3", 0}, |
| | | {"woods", NULL, "woods4", 1}, |
| | | {"woods_3", NULL, "woods5", 1}, |
| | | {NULL, NULL, NULL, 0}, |
| | | }; |
| | | |
| void set_darkness_map(mapstruct *m) | | void set_darkness_map(mapstruct *m) |
| { | | { |
| int i; | | int i; |
| | |
| | | |
| void let_it_snow(mapstruct *m, int wx, int wy, char *filename) | | void let_it_snow(mapstruct *m, int wx, int wy, char *filename) |
| { | | { |
| int x, y; | | int x, y, i; |
| int avoid, two, temp, sky, gotsnow; | | int avoid, two, temp, sky, gotsnow, found; |
| | | char *doublestack, *doublestack2; |
| object *ob, *tmp, *oldsnow; | | object *ob, *tmp, *oldsnow; |
| archetype *at; | | archetype *at; |
| | | |
| | |
| oldsnow = avoid_weather(&avoid, m, x, y, &gotsnow); | | oldsnow = avoid_weather(&avoid, m, x, y, &gotsnow); |
| if (!avoid) { | | if (!avoid) { |
| if (sky >= SKY_LIGHT_SNOW && sky < SKY_HEAVY_SNOW) | | if (sky >= SKY_LIGHT_SNOW && sky < SKY_HEAVY_SNOW) |
| at = find_archetype("snow"); | | at = find_archetype(weather_replace[0].special_snow); |
| if (sky >= SKY_HEAVY_SNOW) | | if (sky >= SKY_HEAVY_SNOW) |
| at = find_archetype("snow2"); | | at = find_archetype(weather_replace[1].special_snow); |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "hills") && | | if (sky >= SKY_LIGHT_SNOW) { |
| sky >= SKY_LIGHT_SNOW) | | found = 0; |
| at = find_archetype("drifts"); | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| | | if (weather_replace[i].arch_or_name == 1) { |
| | | if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } else { |
| | | if (!strcmp(GET_MAP_OB(m, x, y)->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } |
| | | if (found) { |
| | | if (weather_replace[i].special_snow != NULL) |
| | | at = find_archetype(weather_replace[i].special_snow); |
| | | if (weather_replace[i].doublestack_arch != NULL) { |
| | | two++; |
| | | doublestack = weather_replace[i].doublestack_arch; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| /* special case scorn, where the no-magic field wrecks my | | /* special case scorn, where the no-magic field wrecks my |
| logic */ | | logic */ |
| if (GET_MAP_OB(m, x, y)->above != NULL) { | | if (GET_MAP_OB(m, x, y)->above != NULL) { |
| | |
| "cobblestones2") && sky >= SKY_LIGHT_SNOW) | | "cobblestones2") && sky >= SKY_LIGHT_SNOW) |
| at = find_archetype("snow4"); | | at = find_archetype("snow4"); |
| } | | } |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "cobblestones") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("snow4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "cobblestones2") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("snow4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "stones") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("snow4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "flagstone") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("snow4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "stonefloor2") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("snow4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "evergreens") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("cforest1"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "wasteland") && | | |
| sky >= SKY_LIGHT_SNOW) | | |
| at = find_archetype("glacier"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "evergreen")) | | |
| two++; | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "tree")) | | |
| two++; | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods")) | | |
| two++; | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods_3")) | | |
| two++; | | |
| if (gotsnow && at) { | | if (gotsnow && at) { |
| if (!strcmp(oldsnow->arch->name, at->name)) | | if (!strcmp(oldsnow->arch->name, at->name)) |
| at = NULL; | | at = NULL; |
| | |
| free_object(oldsnow); | | free_object(oldsnow); |
| tmp=GET_MAP_OB(m, x, y); | | tmp=GET_MAP_OB(m, x, y); |
| /* clean up the trees we put over the snow */ | | /* clean up the trees we put over the snow */ |
| if (!strcmp(tmp->name, "evergreen")) | | found = 0; |
| tmp = tmp->above; | | doublestack2 = NULL; |
| else if (!strcmp(tmp->name, "tree")) | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| tmp = tmp->above; | | if (weather_replace[i].doublestack_arch == NULL) |
| else if (!strcmp(tmp->arch->name, "woods")) | | continue; |
| tmp = tmp->above; | | if (weather_replace[i].arch_or_name == 1) { |
| else if (!strcmp(tmp->arch->name, "woods_3")) | | if (!strcmp(tmp->arch->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } else { |
| | | if (!strcmp(tmp->name, weather_replace[i].tile)) |
| | | found++; |
| | | } |
| | | if (found) { |
| tmp = tmp->above; | | tmp = tmp->above; |
| if (tmp != NULL) | | doublestack2 = weather_replace[i].doublestack_arch; |
| if (strcmp(tmp->arch->name, "tree3") == 0 || | | break; |
| strcmp(tmp->arch->name, "tree5") == 0 || | | } |
| strcmp(tmp->arch->name, "woods4") == 0 || | | } |
| strcmp(tmp->arch->name, "woods5") == 0) { | | if (tmp != NULL && doublestack2 != NULL) |
| | | if (strcmp(tmp->arch->name, doublestack2) == 0) { |
| remove_ob(tmp); | | remove_ob(tmp); |
| free_object(tmp); | | free_object(tmp); |
| } | | } |
| | |
| INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); | | INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); |
| if (two) { | | if (two) { |
| at = NULL; | | at = NULL; |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "evergreen")) | | at = find_archetype(doublestack); |
| at = find_archetype("tree5"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "tree")) | | |
| at = find_archetype("tree3"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods")) | | |
| at = find_archetype("woods4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods3")) | | |
| at = find_archetype("woods5"); | | |
| if (at != NULL) { | | if (at != NULL) { |
| ob = get_object(); | | ob = get_object(); |
| copy_object(&at->clone, ob); | | copy_object(&at->clone, ob); |
| | |
| /* melt some snow */ | | /* melt some snow */ |
| for (tmp=GET_MAP_OB(m, x, y)->above; tmp; tmp = tmp->above) { | | for (tmp=GET_MAP_OB(m, x, y)->above; tmp; tmp = tmp->above) { |
| avoid = 0; | | avoid = 0; |
| if (!strcmp(tmp->name, "snow")) | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| avoid++; | | if (weather_replace[i].special_snow == NULL) |
| else if (!strcmp(tmp->arch->name, "snow2")) | | continue; |
| avoid++; | | if (!strcmp(tmp->arch->name, weather_replace[i].special_snow)) |
| else if (!strcmp(tmp->arch->name, "drifts")) | | |
| avoid++; | | |
| else if (!strcmp(tmp->arch->name, "cforest1")) | | |
| avoid++; | | |
| else if (!strcmp(tmp->arch->name, "snow4")) | | |
| avoid++; | | |
| else if (!strcmp(tmp->arch->name, "glacier")) | | |
| avoid++; | | avoid++; |
| | | if (avoid) |
| | | break; |
| | | } |
| if (avoid) { | | if (avoid) { |
| /* replace snow with a big puddle */ | | /* replace snow with a big puddle */ |
| remove_ob(tmp); | | remove_ob(tmp); |
| | |
| | | |
| void singing_in_the_rain(mapstruct *m, int wx, int wy, char *filename) | | void singing_in_the_rain(mapstruct *m, int wx, int wy, char *filename) |
| { | | { |
| int x, y; | | int x, y, i; |
| int avoid, two, temp, sky, gotsnow; | | int avoid, two, temp, sky, gotsnow, found; |
| object *ob, *tmp, *oldsnow; | | object *ob, *tmp, *oldsnow; |
| | | char *doublestack, *doublestack2; |
| archetype *at; | | archetype *at; |
| | | |
| for (x=0; x < settings.worldmaptilesizex; x++) { | | for (x=0; x < settings.worldmaptilesizex; x++) { |
| | |
| case 2: at = find_archetype("rain5"); break; | | case 2: at = find_archetype("rain5"); break; |
| default: at = NULL; | | default: at = NULL; |
| } | | } |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "evergreen")) | | found = 0; |
| two++; | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "tree")) | | if (weather_replace[i].arch_or_name == 1) { |
| two++; | | if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods")) | | weather_replace[i].tile)) |
| two++; | | found++; |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods_3")) | | } else { |
| | | if (!strcmp(GET_MAP_OB(m, x, y)->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } |
| | | if (found) { |
| | | if (weather_replace[i].doublestack_arch != NULL) { |
| two++; | | two++; |
| | | doublestack = weather_replace[i].doublestack_arch; |
| | | } |
| | | break; |
| | | } |
| | | } |
| if (gotsnow && at) { | | if (gotsnow && at) { |
| if (!strcmp(oldsnow->arch->name, at->name)) | | if (!strcmp(oldsnow->arch->name, at->name)) |
| at = NULL; | | at = NULL; |
| | |
| free_object(oldsnow); | | free_object(oldsnow); |
| tmp=GET_MAP_OB(m, x, y); | | tmp=GET_MAP_OB(m, x, y); |
| /* clean up the trees we put over the snow */ | | /* clean up the trees we put over the snow */ |
| if (!strcmp(tmp->name, "evergreen")) | | found = 0; |
| tmp = tmp->above; | | doublestack2 = NULL; |
| else if (!strcmp(tmp->name, "tree")) | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| tmp = tmp->above; | | if (weather_replace[i].doublestack_arch == NULL) |
| else if (!strcmp(tmp->arch->name, "woods")) | | continue; |
| tmp = tmp->above; | | if (weather_replace[i].arch_or_name == 1) { |
| else if (!strcmp(tmp->arch->name, "woods_3")) | | if (!strcmp(tmp->arch->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } else { |
| | | if (!strcmp(tmp->name, weather_replace[i].tile)) |
| | | found++; |
| | | } |
| | | if (found) { |
| tmp = tmp->above; | | tmp = tmp->above; |
| if (tmp != NULL) | | doublestack2 = weather_replace[i].doublestack_arch; |
| if (strcmp(tmp->arch->name, "tree3") == 0 || | | break; |
| strcmp(tmp->arch->name, "tree5") == 0 || | | } |
| strcmp(tmp->arch->name, "woods4") == 0 || | | } |
| strcmp(tmp->arch->name, "woods5") == 0) { | | if (tmp != NULL && doublestack2 != NULL) |
| | | if (strcmp(tmp->arch->name, doublestack2) == 0) { |
| remove_ob(tmp); | | remove_ob(tmp); |
| free_object(tmp); | | free_object(tmp); |
| } | | } |
| | |
| insert_ob_in_map(ob, m, ob, | | insert_ob_in_map(ob, m, ob, |
| INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); | | INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); |
| if (two) { | | if (two) { |
| at = NULL; | | at = find_archetype(doublestack); |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "evergreen")) | | |
| at = find_archetype("tree5"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->name, "tree")) | | |
| at = find_archetype("tree3"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods")) | | |
| at = find_archetype("woods4"); | | |
| if (!strcmp(GET_MAP_OB(m, x, y)->arch->name, "woods3")) | | |
| at = find_archetype("woods5"); | | |
| if (at != NULL) { | | if (at != NULL) { |
| ob = get_object(); | | ob = get_object(); |
| copy_object(&at->clone, ob); | | copy_object(&at->clone, ob); |
| | |
| weathermap[wx][wy].humid++; | | weathermap[wx][wy].humid++; |
| tmp=GET_MAP_OB(m, x, y); | | tmp=GET_MAP_OB(m, x, y); |
| /* clean up the trees we put over the rain */ | | /* clean up the trees we put over the rain */ |
| if (!strcmp(tmp->name, "evergreen")) | | found = 0; |
| tmp = tmp->above; | | doublestack2 = NULL; |
| else if (!strcmp(tmp->name, "tree")) | | for (i=0; weather_replace[i].tile != NULL; i++) { |
| tmp = tmp->above; | | if (weather_replace[i].doublestack_arch == NULL) |
| else if (!strcmp(tmp->arch->name, "woods")) | | continue; |
| tmp = tmp->above; | | if (weather_replace[i].arch_or_name == 1) { |
| else if (!strcmp(tmp->arch->name, "woods_3")) | | if (!strcmp(tmp->arch->name, |
| | | weather_replace[i].tile)) |
| | | found++; |
| | | } else { |
| | | if (!strcmp(tmp->name, weather_replace[i].tile)) |
| | | found++; |
| | | } |
| | | if (found) { |
| tmp = tmp->above; | | tmp = tmp->above; |
| if (tmp != NULL) | | doublestack2 = weather_replace[i].doublestack_arch; |
| if (strcmp(tmp->arch->name, "tree3") == 0 || | | break; |
| strcmp(tmp->arch->name, "tree5") == 0 || | | } |
| strcmp(tmp->arch->name, "woods4") == 0 || | | } |
| strcmp(tmp->arch->name, "woods5") == 0) { | | if (tmp != NULL && doublestack2 != NULL) |
| | | if (strcmp(tmp->arch->name, doublestack2) == 0) { |
| remove_ob(tmp); | | remove_ob(tmp); |
| free_object(tmp); | | free_object(tmp); |
| } | | } |