void inter_cylindre(t_caster *caster, t_object *cylindre) { double delt; double a; double b; double c; init_temp_pos(caster, cylindre); a = A(caster->temp_vec.x, caster->temp_vec.y); b = B(caster->temp_vec.x, caster->temp_pos.x, caster->temp_vec.y, caster->temp_pos.y); c = C(cylindre->data.radius, caster->temp_pos.x, caster->temp_pos.y); delt = (pow(b, 2.0) - 4.0 * (a * c)); if (delt >= 0.0) { cylindre->dist = get_nearest((-b - sqrt(delt)) / (2.0 * a), (-b + sqrt(delt)) / (2.0 * a)); if (cylindre->dist > 0.0 && cylindre->dist < caster->intersection.dist) { caster->intersection.brightness = cylindre->brightness; init_intersection(caster, cylindre); rotate_caster(caster, cylindre); } } }
void Barrack::tick(const float dt) { DestructableObject::tick(dt); if (!_broken && _spawn.tick(dt)) { if (hp == max_hp) { //nothing happens int tr; Config->get("objects." + registered_name + ".targeting-range", tr, 500); v2<float> pos, vel; if (!get_nearest(ai::Targets->infantry, tr, pos, vel, false)) return; //skip spawning } int max_c; Config->get("objects." + registered_name + ".maximum-children", max_c, 5); int n = get_children(std::string()); if (n < max_c) { v2<float>dpos; dpos.y = size.y / 2 + 16; //fixme: use debiloids size here. Object * o = spawn(_object, _animation, dpos); o->copy_special_owners(this); play_now("spawn"); } } }
void inter_cone(t_caster *caster, t_object *cone) { double a; double b; double c; double delt; init_temp_pos(caster, cone); a = A2(caster->temp_vec.x, caster->temp_vec.y, caster->temp_vec.z, cone->data.angle); b = B2(caster->temp_vec.x, caster->temp_pos.x, caster->temp_vec.y, caster->temp_pos.y, caster->temp_vec.z, caster->temp_pos.z, cone->data.angle); c = C2(caster->temp_pos.x, caster->temp_pos.y, caster->temp_pos.z, cone->data.angle); delt = (pow(b, 2.0) - 4.0 * (a * c)); if (delt >= 0.0) { cone->dist = get_nearest((-b - sqrt(delt)) / (2.0 * a), (-b + sqrt(delt)) / (2.0 * a)); if (cone->dist > 0.0 && cone->dist < caster->intersection.dist) { caster->intersection.brightness = cone->brightness; init_intersection(caster, cone); rotate_caster(caster, cone); } } }
bool Submarine::spawnBallistic() { v2<float> pos, vel; if (get_nearest(ai::Targets->troops, 640.0f, pos, vel, false)) { spawn("ballistic-missile", "nuke-missile"); return true; } return false; }
std::set<IVehicleDataListener*, IVehicleDataListener::IVehicleDataListenerComp> VehicleManager::get_nearest(IVehicleDataListener &v, unsigned int num_vehicles, double meters) { Position p = v.get_position(); std::set<IVehicleDataListener*, IVehicleDataListener::IVehicleDataListenerComp> nearest = get_nearest(p, num_vehicles, meters); nearest.erase(&v); return nearest; }
void Cannon::calculate(const float dt) { if (!_reaction.tick(dt)) return; static float range = getWeaponRange("cannon-bullet"); v2<float> pos, vel; if (get_nearest(_variants.has("trainophobic")? ai::Targets->infantry_and_train: ai::Targets->infantry, range, pos, vel, true)) { pos.normalize(); set_direction(pos.get_direction(get_directions_number()) - 1); _direction = pos; _state.fire = true; } else _state.fire = false; }
const Waypoint* Waypoints::lookup_location(const GeoPoint &loc, const fixed range) const { const Waypoint* wp = get_nearest(loc, range); if (!wp) return NULL; if (wp->location == loc) return wp; else if (positive(range) && (wp->IsCloseTo(loc, range))) return wp; return NULL; }
void rmove() { register struct player *j; register int i; register int burst; register int numHits, tDir; int avDir; extern struct Enemy *get_nearest(); struct Enemy *enemy_buf; struct player *enemy = NULL; static int roboclock = 0; static int avoid[2] = { -32, 32 }; int no_cloak; char towhom[MSG_LEN]; int timer; static int lastTorpped = 0; /* when we last fired a torp 4/13/92 TC */ roboclock++; /* keep ghostbuster away */ me->p_ghostbuster = 0; /* Check that I'm alive */ if (me->p_status == PEXPLODE) { if (debug) ERROR(1,("Robot: Augh! exploding.\n")); return; } else if (me->p_status == PDEAD) { if (me->p_ntorp > 0) return; if (debug) ERROR(1,("Robot: done exploding and torps are gone.\n")); exitRobot(); return; } timer=0; for (i = 0, j = &players[i]; i < (MAXPLAYER - TESTERS); i++, j++) { if ((j->p_status != PFREE) && !(j->p_flags & PFROBOT)) timer=1; } if (!timer && !sticky) { exitRobot(); return; } /* if I'm a Terminator, quit if he quits, and quit if he dies and */ /* I'm not "sticky" (-s) */ if (target >= 0) { if (players[target].p_status == PFREE) { /* he went away */ me->p_status = PEXPLODE; return; } if ((!sticky) && (players[target].p_status != PALIVE)) { /* he died */ me->p_status = PEXPLODE; return; } } /* If it's been BOREDOM_TIME updates since we fired a torp, become hostile to all races, if we aren't already, and if we're not a practice robot (intended for guardian bots). 4/13/92 TC */ if ((roboclock - lastTorpped > BOREDOM_TIME) && (!practice) && (!hostile) && (me->p_team != 0 && !quiet)) { messAll(me->p_no,roboname,"I'm bored."); hostile++; declare_war(ALLTEAM, 0); } /* Our first priority is to phaser plasma torps in nearby vicinity... */ /* If we fire, we aren't allowed to cloak... */ no_cloak = phaser_plasmas(); /* Find an enemy */ enemy_buf = get_nearest(); if ((enemy_buf != NULL) && (enemy_buf != NOENEMY)) { /* Someone to kill */ enemy = &players[enemy_buf->e_info]; if (((random() % messfuse) == 0) && (hypot((double) me->p_x-enemy->p_x, (double) me->p_y-enemy->p_y) < 20000.0)) { /* change 5/10/21 TC ...neut robots don't message */ messfuse = MESSFUSEVAL; if (me->p_team != 0 && !quiet) { sprintf(towhom, " %s->%s", players[me->p_no].p_mapchars, players[enemy->p_no].p_mapchars); pmessage2(enemy->p_no, MINDIV, towhom, me->p_no, "%s", robo_message(enemy)); } else if (target >= 0 && !quiet) { messAll(me->p_no,roboname,"%s",termie_message(enemy)); } } else if (--messfuse == 0) messfuse = 1; timer = 0; /* if (debug) ERROR(1,( "%d) noticed %d\n", me->p_no, enemy_buf->e_info));*/ } else if (enemy_buf == NOENEMY) { /* no more players. wait 1 minute. */ if (do_repair()) { return; } go_home(0); /* if (debug) ERROR(1,( "%d) No players in game.\n", me->p_no));*/ return; } else if (enemy_buf == 0) { /* no one hostile */ /* if (debug) ERROR(1,( "%d) No hostile players in game.\n", me->p_no));*/ if (do_repair()) { return; } go_home(0); timer = 0; return; } /* Note a bug in this algorithm: ** Once someone dies, he is forgotten. This makes robots particularly easy ** to kill on a suicide run, where you aim to where you think he will turn ** as you die. Once dead, the robot will ignore you and all of your ** active torpedoes! **/ /* Algorithm: ** We have an enemy. ** First priority: shoot at target in range. ** Second: Dodge torps and plasma torps. ** Third: Get away if we are damaged. ** Fourth: repair. ** Fifth: attack. */ /* ** If we are a practice robot, we will do all but the second. One ** will be modified to shoot poorly and not use phasers. **/ /* Fire weapons!!! */ /* ** get_nearest() has already determined if torpedoes and phasers ** will hit. It has also determined the courses which torps and ** phasers should be fired. If so we will go ahead and shoot here. ** We will lose repair and cloaking for the rest of this interrupt. ** if we fire here. */ if (practice) { no_cloak = 1; if (enemy_buf->e_flags & E_TSHOT) { /* if (debug) ERROR(1,( "%d) firing torps\n", me->p_no));*/ for (burst = 0; (burst < 3) && (me->p_ntorp < MAXTORP); burst++) { ntorp(enemy_buf->e_tcourse, TWOBBLE | TOWNERSAFE | TDETTEAMSAFE | TPRACTICE); } } } else { if (enemy_buf->e_flags & E_TSHOT) { /* if (debug) ERROR(1,( "%d) firing torps\n", me->p_no));*/ for (burst = 0; (burst < 2) && (me->p_ntorp < MAXTORP); burst++) { repair_off(); if (! cloaker) cloak_off(); ntorp(enemy_buf->e_tcourse, TWOBBLE | TOWNERSAFE | TDETTEAMSAFE); no_cloak++; lastTorpped = roboclock; /* record time of firing 4/13/92 TC */ } } if (enemy_buf->e_flags & E_PSHOT) { /* if (debug) ERROR(1,( "%d) phaser firing\n", me->p_no));*/ no_cloak++; repair_off(); if (! cloaker) cloak_off(); phaser(enemy_buf->e_course); } } /* auto pressor 7/27/91 TC */ /* tractor/pressor rewritten on 5/1/92... glitches galore :-| TC */ /* whoa, too close for comfort, or he's tractoring me, or headed in for me, or I'm hurt */ /* a little tuning -- 0.8 on phrange and +/- 90 degrees in for pressor */ /* pressor_player(-1); this didn't do anything before, so we'll let the pressors disengage by themselves 5/1/92 TC */ if (enemy_buf->e_flags & E_TRACT) { /* if pressorable */ if (((enemy_buf->e_dist < 0.8 * enemy_buf->e_phrange) && (angdist(enemy_buf->e_edir, enemy_buf->e_course) > 64)) || (isTractoringMe(enemy_buf)) || (me->p_damage > 0)) { if (!(enemy->p_flags & PFCLOAK)) { if (debug) ERROR(1,( "%d) pressoring %d\n", me->p_no, enemy_buf->e_info)); pressor_player(enemy->p_no); no_cloak++; repair_off(); if (!cloaker) cloak_off(); } } } /* auto tractor 7/31/91 TC */ /* tractor if not pressoring and... */ /* tractor if: in range, not too close, and not headed +/- 90 degrees */ /* of me, and I'm not hurt */ if ((!(me->p_flags & PFPRESS)) && (enemy_buf->e_flags & E_TRACT) && (angdist(enemy_buf->e_edir, enemy_buf->e_course) < 64) && (enemy_buf->e_dist > 0.7 * enemy_buf->e_phrange)) { if (!(me->p_flags & PFTRACT)) { if (debug) ERROR(1,( "%d) tractoring %d\n", me->p_no, enemy_buf->e_info)); tractor_player(enemy->p_no); no_cloak++; } } else tractor_player(-1); /* otherwise don't tractor */ /* Avoid torps */ /* ** This section of code allows robots to avoid torps. ** Within a specific range they will check to see if ** any of the 'closest' enemies torps will hit them. ** If so, they will evade for four updates. ** Evading is all they will do for this round, other than shooting. */ if (!practice) { if ((enemy->p_ntorp < 5)) { if ((enemy_buf->e_dist < 15000) || (avoidTime > 0)) { numHits = projectDamage(enemy->p_no, &avDir); if (debug) { ERROR(1,( "%d hits expected from %d from dir = %d\n", numHits, enemy->p_no, avDir)); } if (numHits == 0) { if (--avoidTime > 0) { /* we may still be avoiding */ if (angdist(me->p_desdir, me->p_dir) > 64) me->p_desspeed = dogslow; else me->p_desspeed = dogfast; return; } } else { /* * Actually avoid Torps */ avoidTime = AVOID_TIME; tDir = avDir - me->p_dir; /* put into 0->255 range */ tDir = NORMALIZE(tDir); if (debug) ERROR(1,( "mydir = %d avDir = %d tDir = %d q = %d\n", me->p_dir, avDir, tDir, tDir / 64)); switch (tDir / 64) { case 0: case 1: set_course(NORMALIZE(avDir + 64)); break; case 2: case 3: set_course(NORMALIZE(avDir - 64)); break; } if (!no_cloak) cloak_on(); if (angdist(me->p_desdir, me->p_dir) > 64) me->p_desspeed = dogslow; else me->p_desspeed = dogfast; shield_up(); detothers(); /* hmm */ if (debug) ERROR(1,( "evading to dir = %d\n", me->p_desdir)); return; } } } /* ** Trying another scheme. ** Robot will keep track of the number of torps a player has ** launched. If they are greater than say four, the robot will ** veer off immediately. Seems more humanlike to me. */ else if (enemy_buf->e_dist < 15000) { if (--avoidTime > 0) { /* we may still be avoiding */ if (angdist(me->p_desdir, me->p_dir) > 64) me->p_desspeed = dogslow; else me->p_desspeed = dogfast; return; } if (random() % 2) { me->p_desdir = NORMALIZE(enemy_buf->e_course - 64); avoidTime = AVOID_TIME; } else { me->p_desdir = NORMALIZE(enemy_buf->e_course + 64); avoidTime = AVOID_TIME; } if (angdist(me->p_desdir, me->p_dir) > 64) me->p_desspeed = dogslow; else me->p_desspeed = dogfast; shield_up(); return; } } /* Run away */ /* ** The robot has taken damage. He will now attempt to run away from ** the closest player. This obviously won't do him any good if there ** is another player in the direction he wants to go. ** Note that the robot will not run away if he dodged torps, above. ** The robot will lower his shields in hopes of repairing some damage. */ #define STARTDELTA 5000 /* ships appear +/- delta of home planet */ if (me->p_damage > 0 && enemy_buf->e_dist < 13000) { if (me->p_etemp > 900) /* 90% of 1000 */ me->p_desspeed = runslow; else me->p_desspeed = runfast; if (!no_cloak) cloak_on(); repair_off(); shield_down(); set_course(enemy_buf->e_course - 128); if (debug) ERROR(1,( "%d(%d)(%d/%d) running from %c%d %16s damage (%d/%d) dist %d\n", me->p_no, (int) me->p_kills, me->p_damage, me->p_shield, teamlet[enemy->p_team], enemy->p_no, enemy->p_login, enemy->p_damage, enemy->p_shield, enemy_buf->e_dist)); return; } /* Repair if necessary (we are safe) */ /* ** The robot is safely away from players. It can now repair in peace. ** It will try to do so now. */ if (do_repair()) { return; } /* Attack. */ /* ** The robot has nothing to do. It will check and see if the nearest ** enemy fits any of its criterion for attack. If it does, the robot ** will speed in and deliver a punishing blow. (Well, maybe) */ if ((enemy_buf->e_flags & E_INTRUDER) || (enemy_buf->e_dist < 15000) || (hostile)) { if ((!no_cloak) && (enemy_buf->e_dist < 10000)) cloak_on(); shield_up(); /* if (debug) ERROR(1,( "%d(%d)(%d/%d) attacking %c%d %16s damage (%d/%d) dist %d\n", me->p_no, (int) me->p_kills, me->p_damage, me->p_shield, teamlet[enemy->p_team], enemy->p_no, enemy->p_login, enemy->p_damage, enemy->p_shield, enemy_buf->e_dist));*/ if (enemy_buf->e_dist < 15000) { set_course(enemy_buf->e_course + avoid[(roboclock / AVOID_CLICKS) % SIZEOF(avoid)]); if (angdist(me->p_desdir, me->p_dir) > 64) set_speed(closeslow); else set_speed(closefast); } else { me->p_desdir = enemy_buf->e_course; if (angdist(me->p_desdir, me->p_dir) > 64) set_speed(closeslow); if (target >= 0) /* 7/27/91 TC */ set_speed(12); else if (me->p_etemp > 900) /* 90% of 1000 */ set_speed(runslow); else set_speed(runfast); } } else { go_home(enemy_buf); } }
void CRATE::tick() { if(col_get((int)(pos.x+phys_size/2), (int)(pos.y-phys_size/2))&COLFLAG_DEATH || col_get((int)(pos.x+phys_size/2), (int)(pos.y+phys_size/2))&COLFLAG_DEATH || col_get((int)(pos.x-phys_size/2), (int)(pos.y-phys_size/2))&COLFLAG_DEATH || col_get((int)(pos.x-phys_size/2), (int)(pos.y+phys_size/2))&COLFLAG_DEATH) { die(); return; } grounded = is_grounded(); bool was_grounded = grounded; if(!grounded) { //die(); int k = 3; while(!grounded && k-- > 0) { pos.y += 1; grounded = is_grounded(); } } if(grounded && !was_grounded) game.create_sound(pos, SOUND_CRATE_IMPACT); was_grounded = grounded; if(!alive) return; CHARACTER *c = get_nearest(28); GAMECONTROLLER_NODES* gc = (GAMECONTROLLER_NODES*)game.controller; if(c) { dbg_msg("nodes", "activated a crate of type %d", type); char buf[128]; str_format(buf, sizeof(buf), "%s", BUF_NAMES[type]); game.send_broadcast(buf, c->player->client_id); switch(type) { //c->crate = type; //c->crate_tick = server_tick(); case CRATE_HEALTH: { c->health = 10; game.create_sound(pos, SOUND_PICKUP_HEALTH); } break; case CRATE_ARMOR: { c->armor = 10; game.create_sound(pos, SOUND_PICKUP_ARMOR); } break; case CRATE_CONSTRUCTION: { c->crate = CRATE_CONSTRUCTION; c->crate_tick = server_tick(); c->core.frozen = false; /*if(gc->buildings_buffpoints[1-c->team] > 0) { gc->buildings_points[1-c->team] -= gc->buildings_buffpoints[1-c->team]; gc->buildings_buffpoints[1-c->team] = 0; } if(gc->buildings_buffpoints[c->team] == 0) { gc->buildings_points[c->team] += config.sv_buffpoints; gc->buildings_buffpoints[c->team] = config.sv_buffpoints; }*/ } break; case CRATE_BASEBALL: { c->crate = CRATE_BASEBALL; c->crate_tick = server_tick(); c->core.frozen = false; c->active_weapon = WEAPON_HAMMER; } break; case CRATE_FREEZE: { c->crate = 0; //undo crate thingy, only enemies will get this "buff" c->core.frozen = false; CHARACTER *close_characters[MAX_CLIENTS]; int num = game.world.find_entities(c->pos, config.sv_freeze_radius, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER); for(int i = 0; i < num; i++) { if(close_characters[i]->player->team != c->player->team) { close_characters[i]->core.frozen = true; close_characters[i]->crate = CRATE_FREEZE; close_characters[i]->crate_tick = server_tick(); close_characters[i]->crate_misc = (int)(frandom() *2); game.create_sound(close_characters[i]->pos, SOUND_CRATE_ICE); } } game.create_sound(pos, SOUND_CRATE_ICE); game.create_effect(pos, 3); } break; case CRATE_EMP: { gc->emp = true; gc->emp_tick = server_tick(); game.create_effect(pos, 2); game.create_sound_global(SOUND_CRATE_EMP, -1); } break; case CRATE_DUCK: { c->core.frozen = true; //c->ill = true; c->crate = CRATE_FREEZE; c->crate_tick = server_tick(); c->crate_misc = (int)(frandom() *2); c->core.hook_state = -1; c->core.hooked_player = -1; game.create_sound(pos, SOUND_CRATE_ICE); } break; case CRATE_BOOM: { game.create_explosion(pos, -4, WEAPON_WORLD, false); game.create_explosion(pos, -4, WEAPON_WORLD, false); game.create_explosion(pos, -4, WEAPON_WORLD, false); game.create_sound(pos, SOUND_GRENADE_EXPLODE); } /*case CRATE_EXPLOSION: { game.create_explosion(pos, -1, WEAPON_WORLD, false); game.create_explosion(pos, -1, WEAPON_WORLD, false); game.create_explosion(pos, -1, WEAPON_WORLD, false); } break; case CRATE_ILLNESS: { c->ill = true; c->infecter = -1; } break; case CRATE_NOGRAV: { c->core.nograv = true; } break; case CRATE_FREEZE: { c->core.frozen = true; } break; case CRATE_STRIP: { c->weapons[WEAPON_GUN].got = 0; c->weapons[WEAPON_GRENADE].got = 0; c->weapons[WEAPON_RIFLE].got = 0; } case CRATE_HEALTH: { c->health = 10; } break; case CRATE_ARMOR: { c->armor = 10; } case CRATE_AMMO: { c->weapons[WEAPON_GUN].ammo = 10; c->weapons[WEAPON_GRENADE].ammo = 10; c->weapons[WEAPON_RIFLE].ammo = 10; } case CRATE_WEAPONS: { c->weapons[WEAPON_GUN].got = 1; c->weapons[WEAPON_GRENADE].got = 1; c->weapons[WEAPON_RIFLE].got = 1; }*/ } die(); return; } if(server_tick() > creation_tick + 20*50) { game.create_explosion(pos, -1, WEAPON_WORLD, true); game.create_sound(pos, SOUND_GRENADE_EXPLODE); die(); } return; }