void apply_guard_mode (struct anim *g, enum gm gm) { if (! is_guard (g)) return; switch (gm) { case ORIGINAL_GM: g->type = g->original_type; break; case GUARD_GM: g->type = GUARD; break; case FAT_GUARD_GM: g->type = FAT_GUARD; break; case VIZIER_GM: g->type = VIZIER; break; case SKELETON_GM: g->type = SKELETON; break; case SHADOW_GM: g->type = SHADOW; break; } }
void draw_guard_frame (ALLEGRO_BITMAP *bitmap, struct anim *g, enum vm vm) { struct coord c; if (! is_guard (g)) return; if (g->invisible) return; struct frame f = g->f; struct frame_offset xf = g->xf; f.b = apply_guard_palette (f.b, g->type, g->style, vm); xf.b = apply_guard_palette (xf.b, g->type, g->style, vm); draw_xframe (bitmap, &f, &xf); draw_frame (bitmap, &f); if (g->splash && g->type != SKELETON) { ALLEGRO_BITMAP *splash = (g->type == SHADOW) ? v_kid_splash : guard_splash; palette pal = get_guard_palette (g->style, vm); splash = apply_palette (splash, pal); if (hgc) splash = apply_palette (splash, hgc_palette); draw_bitmapc (splash, bitmap, splash_coord (&g->f, &c), g->f.flip); } }
void draw_guard_lives (ALLEGRO_BITMAP *bitmap, struct anim *g, enum vm vm) { if (g->dont_draw_lives) return; if (g->current_lives <= 0) return; int current_lives = (g->current_lives > 10) ? 10 : g->current_lives; int i; struct coord c; struct rect r; new_rect (&r, room_view, ORIGINAL_WIDTH - 7 * current_lives, ORIGINAL_HEIGHT - 8, 7 * current_lives, ORIGINAL_HEIGHT - 1); ALLEGRO_COLOR bg_color; switch (vm) { case CGA: bg_color = C_LIVES_RECT_COLOR; break; case EGA: bg_color = E_LIVES_RECT_COLOR; break; case VGA: bg_color = V_LIVES_RECT_COLOR; break; } draw_filled_rect (bitmap, &r, bg_color); ALLEGRO_BITMAP *life = guard_life; palette pal = NULL; if ((g->type == SHADOW && g->style == 0) || g->type == KID) { pal = get_shadow_life_palette (vm); life = apply_palette (life, pal); } else if (g->type == SKELETON && g->style == 0) life = apply_palette (life, skeleton_life_palette); else if (is_guard (g)) { pal = get_guard_palette (g->style, vm); life = apply_palette (life, pal); } if (hgc) life = apply_palette (life, hgc_palette); for (i = 0; i < current_lives; i++) draw_bitmapc (life, bitmap, guard_life_coord (i, &c), 0); }
void alert_guards (struct pos *p) { int i; for (i = 0; i < anima_nmemb; i++) { struct anim *g = &anima[i]; if (is_guard (g) && is_pos_on_back (g, p) && g->current_lives > 0 && g->enemy_id == -1 && abs (anim_cycle - g->alert_cycle) > 24) { invert_frame_dir (&g->f, &g->f); g->alert_cycle = anim_cycle; } } }
static void destroy_road(unit * u, int nmax, struct order *ord) { char token[128]; const char *s = gettoken(token, sizeof(token)); direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION; if (d == NODIRECTION) { /* Die Richtung wurde nicht erkannt */ cmistake(u, ord, 71, MSG_PRODUCE); } else { unit *u2; region *r = u->region; short road, n = (short)nmax; if (nmax > SHRT_MAX) { n = SHRT_MAX; } else if (nmax < 0) { n = 0; } for (u2 = r->units; u2; u2 = u2->next) { if (u2->faction != u->faction && is_guard(u2, GUARD_TAX) && cansee(u2->faction, u->region, u, 0) && !alliedunit(u, u2->faction, HELP_GUARD)) { cmistake(u, ord, 70, MSG_EVENT); return; } } road = rroad(r, d); n = _min(n, road); if (n != 0) { region *r2 = rconnect(r, d); int willdo = eff_skill(u, SK_ROAD_BUILDING, r) * u->number; willdo = _min(willdo, n); if (willdo == 0) { /* TODO: error message */ } if (willdo > SHRT_MAX) road = 0; else road = road - (short)willdo; rsetroad(r, d, road); ADDMSG(&u->faction->msgs, msg_message("destroy_road", "unit from to", u, r, r2)); } } }
static bool is_guardian_u(const unit * guard, unit * u) { if (guard->faction == u->faction) return false; if (is_guard(guard) == 0) return false; if (alliedunit(guard, u->faction, HELP_GUARD)) return false; if (ucontact(guard, u)) return false; if (!cansee(guard->faction, u->region, u, 0)) return false; if (!(u_race(guard)->flags & RCF_FLY) && u_race(u)->flags & RCF_FLY) return false; return true; }
static order *get_money_for_dragon(region * r, unit * udragon, int wanted) { int n; bool attacks = attack_chance > 0.0; /* falls genug geld in der region ist, treiben wir steuern ein. */ if (rmoney(r) >= wanted) { /* 5% chance, dass der drache aus einer laune raus attackiert */ if (!attacks || chance(1.0 - u_race(udragon)->aggression)) { /* Drachen haben in E3 und E4 keine Einnahmen. Neuer Befehl Pluendern erstmal nur fuer Monster?*/ return create_order(K_LOOT, default_locale, NULL); } } /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an * und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */ n = 0; if (attacks && is_guard(udragon, GUARD_TAX)) { unit *u; for (u = r->units; u; u = u->next) { if (u->faction != udragon->faction && cansee(udragon->faction, r, u, 0) && !in_safe_building(u, udragon)) { int m = get_money(u); if (m != 0) { order *ord = monster_attack(udragon, u); if (ord) { addlist(&udragon->orders, ord); n += m; } } } } } /* falls die einnahmen erreicht werden, bleibt das monster noch eine */ /* runde hier. */ if (n + rmoney(r) >= wanted) { return create_order(K_LOOT, default_locale, NULL); } /* wenn wir NULL zurueckliefern, macht der drache was anderes, z.b. weggehen */ return NULL; }
void fight_hit (struct anim *k, struct anim *ke) { if (k->immortal || k->sword_immune) return; if (k->current_lives <= 0) return; if (is_anim_fall (&k->f) || is_kid_stairs (&k->f)) return; place_on_the_ground (&k->f, &k->f.c); k->xf.b = NULL; if (! is_in_fight_mode (k)) k->current_lives = 0; else k->current_lives--; if (! is_guard (ke)) upgrade_skill (&ke->skill, &k->skill, k->total_lives); int d = (k->f.dir == LEFT) ? +1 : -1; struct pos pb; survey (_m, pos, &k->f, NULL, &k->p, NULL); prel (&k->p, &pb, 0, d); if (k->current_lives <= 0 && ! is_strictly_traversable (&pb)) { k->current_lives = 0; k->death_reason = FIGHT_DEATH; ke->alert_cycle = anim_cycle; anim_die (k); } else anim_sword_hit (k); if (is_in_fight_mode (k)) { backoff_from_range (ke, k, ATTACK_RANGE - 20, true, false); get_in_range (ke, k, ATTACK_RANGE - 10, false, false); } k->splash = true; if (k->id == current_kid_id) { mr.flicker = 2; mr.color = get_flicker_blood_color (); play_audio (&harm_audio, NULL, k->id); } else play_audio (&guard_hit_audio, NULL, k->id); }
void plan_monsters(faction * f) { region *r; assert(f); attack_chance = get_param_flt(global.parameters, "rules.monsters.attack_chance", 0.4); f->lastorders = turn; for (r = regions; r; r = r->next) { unit *u; bool attacking = false; for (u = r->units; u; u = u->next) { attrib *ta; order *long_order = NULL; /* Ab hier nur noch Befehle für NPC-Einheiten. */ if (!is_monsters(u->faction)) continue; /* Befehle müssen jede Runde neu gegeben werden: */ free_orders(&u->orders); if (skill_enabled(SK_PERCEPTION)) { /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ /* TODO: this only works for playerrace */ produceexp(u, SK_PERCEPTION, u->number); } if (!attacking) { if (chance(attack_chance)) attacking = true; } if (u->status > ST_BEHIND) { setstatus(u, ST_FIGHT); /* all monsters fight */ } if (attacking && (!r->land || is_guard(u, GUARD_TAX))) { monster_attacks(u); } /* units with a plan to kill get ATTACK orders: */ ta = a_find(u->attribs, &at_hate); if (ta && !monster_is_waiting(u)) { unit *tu = (unit *)ta->data.v; if (tu && tu->region == r) { order * ord = monster_attack(u, tu); if (ord) { addlist(&u->orders, ord); } } else if (tu) { tu = findunitg(ta->data.i, NULL); if (tu != NULL) { long_order = make_movement_order(u, tu->region, 2, allowed_walk); } } else a_remove(&u->attribs, ta); } /* All monsters guard the region: */ if (!monster_is_waiting(u) && r->land) { addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); } /* Einheiten mit Bewegungsplan kriegen ein NACH: */ if (long_order == NULL) { attrib *ta = a_find(u->attribs, &at_targetregion); if (ta) { if (u->region == (region *)ta->data.v) { a_remove(&u->attribs, ta); } } else if (u_race(u)->flags & RCF_MOVERANDOM) { if (rng_int() % 100 < MOVECHANCE || check_overpopulated(u)) { long_order = monster_move(r, u); } } } if (long_order == NULL && unit_can_study(u)) { /* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um * zu bewachen: */ if (u_race(u)->bonus[SK_WEAPONLESS] != -99) { if (effskill(u, SK_WEAPONLESS, 0) < 1) { long_order = create_order(K_STUDY, f->locale, "'%s'", skillname(SK_WEAPONLESS, f->locale)); } } } if (long_order == NULL) { /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ if (!u->orders) { handle_event(u->attribs, "ai_move", u); } switch (old_race(u_race(u))) { case RC_SEASERPENT: long_order = create_order(K_PIRACY, f->locale, NULL); break; #ifdef TODO_ALP case RC_ALP: long_order = monster_seeks_target(r, u); break; #endif case RC_FIREDRAGON: case RC_DRAGON: case RC_WYRM: long_order = plan_dragon(u); break; default: if (u_race(u)->flags & RCF_LEARN) { long_order = monster_learn(u); } break; } } if (long_order) { addlist(&u->orders, long_order); } } } pathfinder_cleanup(); }