void thing_shield_sheath (thingp t) { tpp shield = thing_shield(t); if (!shield) { return; } THING_LOG(t, "sheathing %s", tp_short_name(shield)); /* * If this shield has its own thing id for animations then destroy that. */ thingp shield_carry_anim = thing_shield_carry_anim(t); if (shield_carry_anim) { THING_LOG(t, "unwield, carry anim %s", thing_logname(shield_carry_anim)); thing_dead(shield_carry_anim, 0, "owner shield"); thing_set_shield_carry_anim(t, 0); } /* * Else if vanishes on level changes. */ if (!t->on_server) { t->shield = 0; } }
void thing_collect_key (levelp level, thingp owner, thingp it) { owner->keys++; player_wid_update(level); thing_dead(level, it, owner, "collected key"); }
void thing_collect_bomb (levelp level, thingp owner, thingp it) { owner->bombs++; player_wid_update(level); thing_dead(level, it, owner, "collected bomb"); }
static void server_rx_client_leave_implicit (gsocketp s) { aplayerp p = socket_get_player(s); if (!p) { return; } global_config.server_current_players--; if (!global_config.server_current_players) { LOG("Server: Last player left the game, destroy the map"); wid_game_map_server_wid_destroy(false /* keep players*/); } else { LOG("Server: %u player(s) left, do not destroy the map", global_config.server_current_players); } if (p->thing) { thing_dead(p->thing, 0, "the network"); } socket_set_player(s, 0); }
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(); } }