/* * Map a trigger to a slot number if it has not been done so already */ void level_trigger_alloc (levelp level, color c) { if (color_none(c)) { c = default_trigger; } int i; if (level_trigger2slot(level, c) != -1) { return; } /* * See if the trigger exists */ for (i = 0; i < ARRAY_SIZE(level->trigger); i++) { if (color_none(level->trigger[i].c)) { level->trigger[i].c = c; LEVEL_LOG(level, "Allocate trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); return; } } ERR("out of level triggers trying to add %u.%u.%u.%u", c.a, c.r, c.g, c.a); }
/* * Find an existing trigger and which slot it is in */ int level_trigger2slot (levelp level, color c) { if (color_none(c)) { c = default_trigger; } int i; /* * See if the trigger exists */ for (i = 0; i < ARRAY_SIZE(level->trigger); i++) { if (color_none(level->trigger[i].c)) { break; } if (color_cmp(c, level->trigger[i].c)) { return (i); } } return (-1); }
static void level_trigger_mark_activate (levelp level, color c) { if (color_none(c)) { c = default_trigger; } int slot; slot = level_trigger2slot(level, c); if (slot == -1) { ERR("Cannot activate trigger %u.%u.%u.%u", c.a, c.r, c.g, c.a); } level->trigger[slot].activated = 1; }
int level_trigger_is_activated (levelp level, color c) { if (color_none(c)) { c = default_trigger; } int slot; slot = level_trigger2slot(level, c); if (slot == -1) { ERR("cannot check if activated, name %u.%u.%u.%u", c.a, c.r, c.g, c.a); } return (level->trigger[slot].activated); }
/* plot areas */ int PS_vareas_plot(struct Map_info *P_map, int vec) { int na, area, ret; double e, w, n, s, aw, shift; double llx, lly, urx, ury, sc; char pat[50]; struct line_cats *Cats; struct bound_box box; struct varray *Varray = NULL; PSCOLOR color; int centroid; /* rgbcol */ dbCatValArray cvarr_rgb; fprintf(PS.fp, "1 setlinejoin\n"); /* set line join to round */ Cats = Vect_new_cats_struct(); /* Create vector array if required */ if (vector.layer[vec].cats != NULL || vector.layer[vec].where != NULL) { Varray = Vect_new_varray(Vect_get_num_areas(P_map)); if (vector.layer[vec].cats != NULL) { ret = Vect_set_varray_from_cat_string(P_map, vector.layer[vec].field, vector.layer[vec].cats, GV_AREA, 1, Varray); } else { ret = Vect_set_varray_from_db(P_map, vector.layer[vec].field, vector.layer[vec].where, GV_AREA, 1, Varray); } G_debug(3, "%d items selected for vector %d", ret, vec); if (ret == -1) G_fatal_error(_("Cannot load data from table")); } /* load attributes if rgbcol used */ if (vector.layer[vec].rgbcol != NULL) { load_catval_array_rgb(P_map, vec, &cvarr_rgb); } shift = 0; /* read and plot areas */ na = Vect_get_num_areas(P_map); for (area = 1; area <= na; area++) { G_debug(4, "area = %d", area); if (Varray != NULL && Varray->c[area] == 0) continue; /* is not in array */ if (!Vect_area_alive(P_map, area)) continue; centroid = Vect_get_area_centroid(P_map, area); G_debug(4, "centroid = %d", centroid); if (centroid < 1) /* area is an island */ continue; Vect_get_area_box(P_map, area, &box); n = box.N; s = box.S; e = box.E; w = box.W; if (PS.w.proj == PROJECTION_LL) { aw = G_adjust_easting(w, &PS.w); if (aw > PS.w.east) aw -= 360.0; shift = aw - w; e += shift; w += shift; } /* check if in window */ if (n < PS.w.south || s > PS.w.north || e < PS.w.west || w > PS.w.east) continue; fprintf(PS.fp, "NP\n"); if (PS.w.proj == PROJECTION_LL) { /* plot area while in window */ while (e > PS.w.west) { ret = plot_area(P_map, area, shift); if (ret != 1) return 0; shift -= 360.0; e -= 360.0; } } else { ret = plot_area(P_map, area, shift); if (ret != 1) return 0; } if (vector.layer[vec].pat != NULL || (!color_none(&vector.layer[vec].fcolor) || vector.layer[vec].rgbcol != NULL)) { if (vector.layer[vec].rgbcol != NULL) { /* load fill color from rgbcol */ /* if data column is empty or cat is missing don't fill */ if (get_ps_color_rgbcol_varea(P_map, vec, area, &cvarr_rgb, &color) != 1) return 0; } else { color = vector.layer[vec].fcolor; } if (vector.layer[vec].pat != NULL) { /* use pattern */ sc = vector.layer[vec].scale; /* DEBUG */ /* printf("\n eps pattern = %s\n", vector.layer[vec].eps); printf(" scale = %f\n", vector.layer[vec].scale); */ /* load pattern */ eps_bbox(vector.layer[vec].pat, &llx, &lly, &urx, &ury); sprintf(pat, "APATTEPS%d", vec); pat_save(PS.fp, vector.layer[vec].pat, pat); fprintf(PS.fp, "<< /PatternType 1\n /PaintType 1\n /TilingType 1\n"); fprintf(PS.fp, " /BBox [%f %f %f %f]\n", llx * sc, lly * sc, urx * sc, ury * sc); fprintf(PS.fp, " /XStep %f\n /YStep %f\n", (urx - llx) * sc, (ury - lly) * sc); fprintf(PS.fp, " /PaintProc\n { begin\n"); fprintf(PS.fp, " %f %f scale\n", sc, sc); set_ps_color(&color); fprintf(PS.fp, " %.8f W\n", vector.layer[vec].pwidth); fprintf(PS.fp, " %s\n", pat); fprintf(PS.fp, " end\n"); fprintf(PS.fp, " } bind\n>>\n"); sprintf(pat, "APATT%d", vec); fprintf(PS.fp, " matrix\n makepattern /%s exch def\n", pat); fprintf(PS.fp, "/Pattern setcolorspace\n %s setcolor\n", pat); } else { set_ps_color(&color); } fprintf(PS.fp, "F\n"); } if (vector.layer[vec].width > 0 && !(color_none(&vector.layer[vec].color))) { fprintf(PS.fp, "%.8f W\n", vector.layer[vec].width); set_ps_color(&(vector.layer[vec].color)); fprintf(PS.fp, "stroke\n"); } } fprintf(PS.fp, "\n"); fprintf(PS.fp, "0 setlinejoin\n"); /* reset line join to miter */ return 1; }
int read_text(char *east, char *north, char *text) { PSCOLOR color, hcolor, background, border; int r, g, b; int ret; int xoffset; int yoffset; float size; int fontsize; double width; double hwidth; double rotate; int xref, yref; int opaque; char t1[128]; char buf[1024]; char *key, *data; FILE *fd; char fontname[128]; set_color(&color, 0, 0, 0); /* black */ unset_color(&hcolor); unset_color(&background); unset_color(&border); opaque = TRUE; size = 0.0; fontsize = 0; xoffset = 0; yoffset = 0; width = 1.; hwidth = 0.; rotate = 0.0; xref = CENTER; yref = CENTER; G_strcpy(fontname, "Helvetica"); while (*text == ' ' || *text == '\t') text++; if (*text == '\\') text++; if (*text == 0) { error("text", "", "no text given"); gobble_input(); return 0; } while (input(2, buf, help)) { if (!key_data(buf, &key, &data)) continue; if (KEY("font")) { get_font(data); strcpy(fontname, data); continue; } if (KEY("color")) { ret = G_str_to_color(data, &r, &g, &b); if (ret == 1) set_color(&color, r, g, b); else if (ret == 2) error(key, data, "primary color cannot be \"none\""); else error(key, data, "illegal color request"); continue; } if (KEY("hcolor")) { ret = G_str_to_color(data, &r, &g, &b); if (ret == 1) set_color(&hcolor, r, g, b); else if (ret == 2) unset_color(&hcolor); else error(key, data, "illegal hcolor request"); if (color_none(&hcolor) || hwidth <= 0.) hwidth = 0.; continue; } if (KEY("background")) { ret = G_str_to_color(data, &r, &g, &b); if (ret == 1) set_color(&background, r, g, b); else if (ret == 2) { unset_color(&background); opaque = FALSE; } else error(key, data, "illegal background color request"); continue; } if (KEY("border")) { ret = G_str_to_color(data, &r, &g, &b); if (ret == 1) set_color(&border, r, g, b); else if (ret == 2) unset_color(&border); else error(key, data, "illegal border color request"); continue; } if (KEY("opaque")) { opaque = yesno(key, data); continue; } if (KEY("width")) { width = -1.; *t1 = 0; if (sscanf(data, "%lf%1s", &width, t1) < 1 || width < 0.) { width = 1.; error(key, data, "illegal width request"); } if (t1 && t1[0] == 'i') width = width / 72.0; continue; } if (KEY("hwidth")) { hwidth = -1.; *t1 = 0; if (sscanf(data, "%lf%1s", &hwidth, t1) < 1 || hwidth < 0.) { hwidth = 0.; error(key, data, "illegal width request"); } if (t1 && t1[0] == 'i') hwidth = hwidth / 72.0; continue; } if (KEY("size")) { double x; if (!scan_resolution(data, &x)) { size = 0.0; error(key, data, "illegal size request"); } else size = x; continue; } if (KEY("fontsize")) { if (sscanf(data, "%d", &fontsize) != 1 || fontsize <= 0) { error(key, data, "illegal fontsize request"); } else continue; } if (KEY("xoffset")) { *t1 = 0; if (sscanf(data, "%d%1s", &xoffset, t1) != 1 || *t1) { xoffset = 0; error(key, data, "illegal request (text)"); } continue; } if (KEY("yoffset")) { *t1 = 0; if (sscanf(data, "%d%1s", &yoffset, t1) != 1 || *t1) { yoffset = 0; error(key, data, "illegal request (text)"); } continue; } if (KEY("rotate")) { if (sscanf(data, "%lf", &rotate) != 1) { rotate = 0.0; error(key, data, "illegal rotate request"); } continue; } if (KEY("ref")) { if (!scan_ref(data, &xref, &yref)) { xref = CENTER; yref = CENTER; error(key, data, "illegal ref request"); } continue; } error(key, data, "illegal request (text)"); } /* if file doesn't exist create it and close it */ if (labels.other == NULL) { labels.other = G_tempfile(); if ((fd = fopen(labels.other, "w")) != NULL) fclose(fd); } /* open file in append mode */ fd = fopen(labels.other, "a"); if (fd == NULL) { error("misc labels file", "", "can't open"); return 1; } /* write the file */ fprintf(fd, "font: %s\n", fontname); fprintf(fd, "east: %s\n", east); fprintf(fd, "north: %s\n", north); fprintf(fd, "xoffset: %d\n", xoffset); fprintf(fd, "yoffset: %d\n", yoffset); fprintf(fd, "width: %f\n", width); fprintf(fd, "hwidth: %f\n", hwidth); fprintf(fd, "size: %f\n", size); fprintf(fd, "fontsize: %d\n", fontsize); fprintf(fd, "opaque: %s\n", opaque ? "yes" : "no"); if (rotate != 0) fprintf(fd, "rotate: %f\n", rotate); fprintf(fd, "color: "); if (!color_none(&color)) fprintf(fd, "%d:%d:%d\n", color.r, color.g, color.b); else fprintf(fd, "black\n"); fprintf(fd, "hcolor: "); if (!color_none(&hcolor)) fprintf(fd, "%d:%d:%d\n", hcolor.r, hcolor.g, hcolor.b); else fprintf(fd, "none\n"); fprintf(fd, "background: "); if (!color_none(&background)) fprintf(fd, "%d:%d:%d\n", background.r, background.g, background.b); else fprintf(fd, "none\n"); fprintf(fd, "border: "); if (!color_none(&border)) fprintf(fd, "%d:%d:%d\n", border.r, border.g, border.b); else fprintf(fd, "none\n"); fprintf(fd, "ref: "); switch (yref) { case UPPER: fprintf(fd, "upper"); break; case LOWER: fprintf(fd, "lower"); break; case CENTER: fprintf(fd, "center"); break; } switch (xref) { case LEFT: fprintf(fd, " left"); break; case RIGHT: fprintf(fd, " right"); break; case CENTER: fprintf(fd, "%s", (xref == CENTER) ? "" : " center"); break; } fprintf(fd, "\n"); fprintf(fd, "text:%s\n\n", text); fclose(fd); return 0; }
void thing_reached_teleport (levelp level, thingp t, thingp teleport) { int tx[MAP_WIDTH*MAP_HEIGHT]; int ty[MAP_WIDTH*MAP_HEIGHT]; int poss = 0; int x, y; int delay = 20; if (!thing_is_player(t)) { /* * Only move other things sometimes. */ if ((myrand() % 100) < 95) { return; } } if (!time_have_x_tenths_passed_since(delay, t->timestamp_last_teleport)) { return; } for (x = 0; x < MAP_WIDTH; x++) { for (y = 0; y < MAP_HEIGHT; y++) { level_map_tile *tile = &level->map_grid.tile[x][y][MAP_DEPTH_EXPLOSION]; tpp it = tile->tp; if (!it) { continue; } if (!tp_is_teleport(it)) { continue; } if (DISTANCE(t->x, t->y, x, y) < 2.0) { continue; } color tcol; color col; tcol = teleport->data.col; col = tile->data.col; if (color_none(col) || color_none(tcol)) { tx[poss] = x; ty[poss] = y; poss++; continue; } if (color_cmp(col, tcol)) { tx[poss] = x; ty[poss] = y; poss++; continue; } } } if (!poss) { return; } t->timestamp_last_teleport = time_get_time_ms(); poss = myrand() % poss; double nx = tx[poss]; double ny = ty[poss]; /* * Don't let lava spawn continually on top of itself. */ if (thing_is_lava(t) && map_is_lava_at(level, nx, ny)) { return; } /* * Don't let water spawn continually on top of itself. */ if (thing_is_water(t) && map_is_water_at(level, nx, ny)) { return; } /* * Don't let acid spawn continually on top of itself. */ if (thing_is_acid(t) && map_is_acid_at(level, nx, ny)) { return; } /* * Don't let water spawn continually on top of itself. */ if (thing_is_water(t) && map_is_water_at(level, nx, ny)) { return; } /* * Don't let monsters spawn continually on top of themselves. */ if (thing_is_monst(t) && map_is_monst_at(level, nx, ny)) { return; } THING_LOG(t, "Teleport"); wid_move_end(t->wid); thing_wid_update(level, t, nx, ny, false /* smooth */, true /* is_new */); /* * Make sure the client sees the jump */ thing_handle_collisions(level, t); MSG_SHOUT_AT(SOUND, t, t->x, t->y, "teleport"); }
/* * Activate any triggers that don't have anything to activate them! i.e. a * move trigger without any activate triogger. */ void level_trigger_activate_default_triggers (levelp level) { int x, y; level_trigger_alloc(level, default_trigger); for (x = 0; x < MAP_WIDTH; x++) { for (y = 0; y < MAP_HEIGHT; y++) { level_map_tile *tile = &level->map_grid.tile[x][y][MAP_DEPTH_ACTIONS]; tpp it = tile->tp; if (!it) { continue; } if (tp_is_action(it)) { color c = tile->data.col; LEVEL_LOG(level, "Found action color %u.%u.%u.%u", c.a, c.r, c.g, c.a); level_trigger_alloc(level, c); } if (tp_is_action_trigger(it)) { color c = tile->data.col; LEVEL_LOG(level, "Found action trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); level_trigger_mark_activate_exists(level, c); continue; } } } int i; for (i = 0; i < ARRAY_SIZE(level->trigger); i++) { color c = level->trigger[i].c; if (color_none(c)) { break; } if (!level->trigger[i].activate_exists) { /* * If nothing exists to activate it, activate it now. */ LEVEL_LOG(level, "No action trigger exists, activate trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); level_trigger_activate(level, c); } else { /* * Else we wait to be activated. */ LEVEL_LOG(level, "Sleeping trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); } } }
void level_trigger_activate (levelp level, color c) { int x, y, z; int spawned = false; int zapped = false; if (level_trigger_is_activated(level, c)) { return; } LEVEL_LOG(level, "Activate trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); level_trigger_mark_activate(level, c); /* * Look for any items to be spawned. * * We don't need to activate movement tiles as they will be activated by * the move tiles themselves during collision testing. */ for (x = 0; x < MAP_WIDTH; x++) { for (y = 0; y < MAP_HEIGHT; y++) { level_map_tile *tile = &level->map_grid.tile[x][y][MAP_DEPTH_ACTIONS]; tpp tile_tp = tile->tp; if (!tile_tp) { continue; } color it_trigger = tile->data.col; if (color_none(it_trigger)) { it_trigger = default_trigger; } if (!color_cmp(it_trigger, c)) { continue; } /* * Look for the original thing that it looks like we wanted to * destroy. Then try and find it on the map. */ tpp triggerd_tp = 0; for (z = MAP_DEPTH_ACTIONS - 1; z >= 0; z--) { triggerd_tp = level->map_grid.tile[x][y][z].tp; if (triggerd_tp) { break; } } if (!triggerd_tp) { continue; } /* * Any sleeping things that need to be awoken? Actually they don't * exist yet, so we need to create them. It's best not to waste * resources with sleeping things until they are needed. */ if (tp_is_action_sleep(tile_tp)) { LEVEL_LOG(level, "Spawn %s via movement trigger %u.%u.%u.%u", tp_name(triggerd_tp), c.a, c.r, c.g, c.a); widp w = wid_game_map_replace_tile(level, x, y, 0, /* thing */ triggerd_tp, 0 /* tpp data */ ); /* * For things like bombs and the like, make them active. */ thingp t = wid_get_thing(w); if (t) { thing_wake(level, t); } spawned = 1; } /* * Any things that need to be zapped? */ if (tp_is_action_zap(tile_tp)) { thingp t = map_is_tp_at(level, x, y, triggerd_tp); if (t) { LEVEL_LOG(level, "Kill %s via movement trigger %u.%u.%u.%u", thing_logname(t), c.a, c.r, c.g, c.a); thing_dead(level, t, 0, "killed by zap trigger"); zapped = true; } } /* * Activate any blocks sitting on movement actions. This will * allow them to do collision testing with the action block and * then move. */ if (tp_is_action_left(tile_tp) || tp_is_action_right(tile_tp) || tp_is_action_up(tile_tp) || tp_is_action_down(tile_tp)) { thingp t = map_is_tp_at(level, x, y, triggerd_tp); if (t) { LEVEL_LOG(level, "Active %s via movement trigger %u.%u.%u.%u", thing_logname(t), c.a, c.r, c.g, c.a); level_trigger_move_thing(level, tile_tp, t); } } } } if (spawned) { sound_play_slime(); } }