float building_onSale(building_t* b, char is_item, int id) { if (kindOf_building_canMake(b->t, is_item, id) == NULL) return 0; return inventory_get(&b->inventory, is_item, id); }
void building_take(building_t* b, char is_item, int id, float amount, inventory_t* inv, char isOwner) { universe_t* u = b->w->universe; amount = fmin(amount, inventory_get(&b->inventory, is_item, id)); float price = 0; if (!isOwner) { price = is_item ? u->items[id].price : u->materials[id].price; price *= amount; } if (price > inv->money) return; inventory_pay(&b->inventory, price, inv); inventory_mov(&b->inventory, is_item, id, -amount, inv); building_update(b); }
int ai_shouldnearestattackabletarget(struct world* world, struct entity* entity, struct aitask* ai) { struct ai_nearestattackabletarget_data* data = ai->data; if (data->chance > 0 && rand() % data->chance != 0) return 0; double cd = data->targetDist * data->targetDist; struct entity* ce = NULL; BEGIN_HASHMAP_ITERATION(world->entities) struct entity* ie = value; if (!hasFlag(getEntityInfo(ie->type), "livingbase") || ie == entity) continue; double dsq = entity_distsq(entity, value); if (ie->type == ENT_PLAYER) { struct player* pl = ie->data.player.player; if (pl->gamemode == 1 || pl->gamemode == 3 || pl->invulnerable) continue; int sk = hasFlag(getEntityInfo(entity->type), "skeleton"); int zo = hasFlag(getEntityInfo(entity->type), "zombie"); int cr = hasFlag(getEntityInfo(entity->type), "creeper"); if (sk || zo || cr) { struct slot* hs = inventory_get(pl, pl->inventory, 5); if (hs != NULL) { if (sk && hs->damage == 0) dsq *= 2.; else if (zo && hs->damage == 2) dsq *= 2.; else if (cr && hs->damage == 4) dsq *= 2.; } } } if (dsq < cd) { //TODO check teams, sight cd = dsq; ce = value; } END_HASHMAP_ITERATION(world->entities) if (entity->attacking != NULL && ce != entity->attacking) put_hashmap(entity->attacking->attackers, entity->id, NULL); if (ce != NULL && entity->attacking != ce) { put_hashmap(ce->attackers, entity->id, entity); } entity->attacking = ce; return 0; }
char ai_get(character_t* c, char is_item, int id, float amount, char keep) { universe_t* u = c->w->universe; amount -= inventory_get(&c->inventory, is_item, id); if (amount <= 0) return 0; // gather if possible kindOf_mine_t* m = universe_mineFor(u, is_item, id); if (m != NULL) { character_goMine(c, m); return 1; } // if the current building cannot obtain the component, build one which can building_t* b = building_get(&c->w->objects, c->hasBuilding); transform_t* tr = b == NULL ? NULL : kindOf_building_canMake(b->t, is_item, id); if (tr == NULL) { // do not replace the building if (keep) { if (rand() % 60 != 0) return 1; float price = is_item ? u->items[id].price : u->materials[id].price; price *= amount; if (c->inventory.money < price) { if (c->inBuilding != c->hasBuilding) character_goto(c, c->hasBuilding); return 1; } // try and buy it building_t* b = world_findSale(c->w, c->o.x, c->o.y, is_item, id); if (b == NULL) return 1; if (c->inBuilding != b->o.uuid) { character_goto(c, b->o.uuid); return 1; } building_take(b, is_item, id, amount, &c->inventory, 0); return 1; } kindOf_building_t* b = universe_buildFor(u, is_item, id); if (b == NULL) { const char* name = is_item ? u->items[id].name : u->materials[id].name; fprintf(stderr, "%s: I do not know how to make %s\n", c->ai->name, name); return 1; } // materials to be gather before building transform_t total; transform_init(&total); // first, gather the non-base materials for the component tr = kindOf_building_canMake(b, is_item, id); for (int i = 0; i < tr->n_req; i++) { component_t* p = &tr->req[i]; if (universe_mineFor(u, p->is_item, p->id) == NULL) transform_req(&total, p->is_item, p->id, p->amount*amount); } // then, gather the materials for the building transform_add(&total, &b->build, 1); // do gather char isreq = ai_getreq(c, &total, 1, keep); transform_exit(&total); if (isreq) return 1; // build character_buildAuto(c, b); return 1; } if (ai_getreq(c, tr, amount, keep)) return 1; // go in the building if (c->inBuilding != c->hasBuilding) { character_goto(c, b->o.uuid); return 1; } // enqueue item if (is_item && b->work_n == 0) { int nth = tr - b->t->items; building_work_enqueue(b, nth); } // work return 1; }