bool move_unit(unit *new_pool, unit *to_move) { if (new_pool != NULL) { append_unit(new_pool, remove_unit(to_move)); } else { new_pool = remove_unit(to_move); } return(true); }
static int yp_int_to_bin( TXT_BIN_PARAMS, int64_t min, int64_t max, uint8_t min_bytes, yp_style_t style) { char *end = (char *)txt; int64_t number = strtoll(txt, &end, 10); // Check if the whole string is invalid. if (end == txt) { return KNOT_EINVAL; } // Check the rest of the string for a unit. if (*end != '\0') { // Check just for one-char rest. if (*(end + 1) != '\0') { return KNOT_EINVAL; } // Try to apply the unit on the number. if (remove_unit(&number, *end, style) != KNOT_EOK) { return KNOT_EINVAL; } } if (number < min || number > max) { return KNOT_ERANGE; } // Convert the number to litte-endian byte order. number = htole64(number); // Store the result memcpy(bin, &number, sizeof(number)); *bin_len = sizeof(number); // Ignore trailing zeroes. for (int i = 7; i >= min_bytes; i--) { if (((uint8_t *)&number)[i] != 0) { break; } (*bin_len)--; } return KNOT_EOK; }
void remove_region(region ** rlist, region * r) { while (r->units) { unit *u = r->units; i_freeall(&u->items); remove_unit(&r->units, u); } runhash(r); unhash_uid(r); while (*rlist && *rlist != r) rlist = &(*rlist)->next; assert(*rlist == r); *rlist = r->next; r->next = deleted_regions; deleted_regions = r; }
void chaos(region * r) { if (rng_int() % 100 < 8) { switch (rng_int() % 3) { case 0: /* Untote */ if (!fval(r->terrain, SEA_REGION)) { unit *u = random_unit(r); if (u && playerrace(u_race(u))) { ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u)); u_setfaction(u, get_monsters()); u_setrace(u, get_race(RC_GHOUL)); } } break; case 1: /* Drachen */ if (random_unit(r)) { int mfac = 0; unit *u; switch (rng_int() % 3) { case 0: mfac = 100; u = createunit(r, get_monsters(), rng_int() % 8 + 1, get_race(RC_FIREDRAGON)); break; case 1: mfac = 500; u = createunit(r, get_monsters(), rng_int() % 4 + 1, get_race(RC_DRAGON)); break; default: mfac = 1000; u = createunit(r, get_monsters(), rng_int() % 2 + 1, get_race(RC_WYRM)); break; } if (mfac) set_money(u, u->number * (rng_int() % mfac)); fset(u, UFL_ISNEW | UFL_MOVED); } case 2: /* Terrainveränderung */ if (!fval(r->terrain, FORBIDDEN_REGION)) { if (!fval(r->terrain, SEA_REGION)) { direction_t dir; for (dir = 0; dir != MAXDIRECTIONS; ++dir) { region *rn = rconnect(r, dir); if (rn && fval(rn->terrain, SEA_REGION)) break; } if (dir != MAXDIRECTIONS) { ship *sh = r->ships; unit **up; while (sh) { ship *nsh = sh->next; float dmg = get_param_flt(global.parameters, "rules.ship.damage.atlantis", 0.50); damage_ship(sh, dmg); if (sh->damage >= sh->size * DAMAGE_SCALE) { remove_ship(&sh->region->ships, sh); } sh = nsh; } for (up = &r->units; *up;) { unit *u = *up; if (u_race(u) != get_race(RC_SPELL) && u->ship == 0 && !canfly(u)) { ADDMSG(&u->faction->msgs, msg_message("tidalwave_kill", "region unit", r, u)); remove_unit(up, u); } if (*up == u) up = &u->next; } ADDMSG(&r->msgs, msg_message("tidalwave", "region", r)); while (r->buildings) { remove_building(&r->buildings, r->buildings); } terraform_region(r, newterrain(T_OCEAN)); } } else { direction_t dir; for (dir = 0; dir != MAXDIRECTIONS; ++dir) { region *rn = rconnect(r, dir); if (rn && fval(rn->terrain, SEA_REGION)) break; } if (dir != MAXDIRECTIONS) { terraform_region(r, chaosterrain()); } } } } } }
/** * @ingroup COND * @brief Wait on the condition. * * The ULT calling \c ABT_cond_timedwait() waits on the condition variable * until it is signaled or the absolute time specified by \c abstime passes. * If system time equals or exceeds \c abstime before \c cond is signaled, * the error code \c ABT_ERR_COND_TIMEDOUT is returned. * * The user should call this routine while the mutex specified as \c mutex is * locked. The mutex will be automatically released while waiting. After signal * is received and the waiting ULT is awakened, the mutex will be * automatically locked for use by the ULT. The user is then responsible for * unlocking mutex when the ULT is finished with it. * * @param[in] cond handle to the condition variable * @param[in] mutex handle to the mutex * @param[in] abstime absolute time for timeout * @return Error code * @retval ABT_SUCCESS on success * @retval ABT_ERR_COND_TIMEDOUT timeout */ int ABT_cond_timedwait(ABT_cond cond, ABT_mutex mutex, const struct timespec *abstime) { int abt_errno = ABT_SUCCESS; ABTI_cond *p_cond = ABTI_cond_get_ptr(cond); ABTI_CHECK_NULL_COND_PTR(p_cond); ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex); ABTI_CHECK_NULL_MUTEX_PTR(p_mutex); double tar_time = convert_timespec_to_sec(abstime); ABTI_unit *p_unit; volatile int ext_signal = 0; p_unit = (ABTI_unit *)ABTU_calloc(1, sizeof(ABTI_unit)); p_unit->pool = (ABT_pool)&ext_signal; p_unit->type = ABT_UNIT_TYPE_EXT; ABTI_mutex_spinlock(&p_cond->mutex); if (p_cond->p_waiter_mutex == NULL) { p_cond->p_waiter_mutex = p_mutex; } else { ABT_bool result = ABTI_mutex_equal(p_cond->p_waiter_mutex, p_mutex); if (result == ABT_FALSE) { ABTI_mutex_unlock(&p_cond->mutex); abt_errno = ABT_ERR_INV_MUTEX; goto fn_fail; } } if (p_cond->num_waiters == 0) { p_unit->p_prev = p_unit; p_unit->p_next = p_unit; p_cond->p_head = p_unit; p_cond->p_tail = p_unit; } else { p_cond->p_tail->p_next = p_unit; p_cond->p_head->p_prev = p_unit; p_unit->p_prev = p_cond->p_tail; p_unit->p_next = p_cond->p_head; p_cond->p_tail = p_unit; } p_cond->num_waiters++; ABTI_mutex_unlock(&p_cond->mutex); /* Unlock the mutex that the calling ULT is holding */ ABTI_mutex_unlock(p_mutex); while (!ext_signal) { double cur_time = get_cur_time(); if (cur_time >= tar_time) { remove_unit(p_cond, p_unit); abt_errno = ABT_ERR_COND_TIMEDOUT; break; } ABT_thread_yield(); } ABTU_free(p_unit); /* Lock the mutex again */ ABTI_mutex_spinlock(p_mutex); fn_exit: return abt_errno; fn_fail: HANDLE_ERROR_FUNC_WITH_CODE(abt_errno); goto fn_exit; }