Exemplo n.º 1
0
/** Untote können entstehen */
void spawn_undead(void)
{
    region *r;
    faction *monsters = get_monsters();

    for (r = regions; r; r = r->next) {
        int unburied = deathcount(r);
        static const curse_type *ctype = NULL;

        if (!ctype)
            ctype = ct_find("holyground");
        if (ctype && curse_active(get_curse(r->attribs, ctype)))
            continue;

        /* Chance 0.1% * chaosfactor */
        if (r->land && unburied > r->land->peasants / 20
            && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) {
            message *msg;
            unit *u;
            /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen.
             * Lieber sammeln lassen, bis sie mindestens 5% der Bevölkerung sind, und
             * dann erst auferstehen. */
            int undead = unburied / (rng_int() % 2 + 1);
            const race *rc = NULL;
            int i;
            if (r->age < 100)
                undead = undead * r->age / 100; /* newbie-regionen kriegen weniger ab */

            if (!undead || r->age < 20)
                continue;

            switch (rng_int() % 3) {
            case 0:
                rc = get_race(RC_SKELETON);
                break;
            case 1:
                rc = get_race(RC_ZOMBIE);
                break;
            default:
                rc = get_race(RC_GHOUL);
                break;
            }

            u = create_unit(r, monsters, undead, rc, 0, NULL, NULL);
            fset(u, UFL_ISNEW | UFL_MOVED);
            if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE))
                && rng_int() % 10 < 4) {
                equip_unit(u, get_equipment("rising_undead"));
            }

            for (i = 0; i < MAXSKILLS; i++) {
                if (rc->bonus[i] >= 1) {
                    set_level(u, (skill_t)i, 1);
                }
            }
            u->hp = unit_max_hp(u) * u->number;

            deathcounts(r, -undead);
            name_unit(u);

            log_debug("spawning %d %s in %s.\n", u->number,
                LOC(default_locale,
                rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL));
          msg = msg_message("undeadrise", "region", r);
          add_message(&r->msgs, msg);
          for (u = r->units; u; u = u->next)
              freset(u->faction, FFL_SELECT);
          for (u = r->units; u; u = u->next) {
              if (fval(u->faction, FFL_SELECT))
                  continue;
              fset(u->faction, FFL_SELECT);
              add_message(&u->faction->msgs, msg);
          }
          msg_release(msg);
        }
        else {
            int i = deathcount(r);
            if (i) {
                /* Gräber verwittern, 3% der Untoten finden die ewige Ruhe */
                deathcounts(r, (int)(-i * 0.03));
            }
        }
    }
}
Exemplo n.º 2
0
int shipspeed(const ship * sh, const unit * u)
{
    int k = sh->type->range;
    static const struct curse_type *stormwind_ct, *nodrift_ct;
    static bool init;
    attrib *a;
    struct curse *c;
    int bonus;

    assert(sh);
    if (!u) u = ship_owner(sh);
    if (!u) return 0;
    assert(u->ship == sh);
    assert(u == ship_owner(sh));
    assert(sh->type->construction);
    assert(sh->type->construction->improvement == NULL);  /* sonst ist construction::size nicht ship_type::maxsize */

    if (!init) {
        init = true;
        stormwind_ct = ct_find("stormwind");
        nodrift_ct = ct_find("nodrift");
    }
    if (sh->size != sh->type->construction->maxsize)
        return 0;

    if (curse_active(get_curse(sh->attribs, stormwind_ct)))
        k *= 2;
    if (curse_active(get_curse(sh->attribs, nodrift_ct)))
        k += 1;

    if (u->faction->race == u_race(u)) {
        /* race bonus for this faction? */
        if (fval(u_race(u), RCF_SHIPSPEED)) {
            k += 1;
        }
    }

    bonus = ShipSpeedBonus(u);
    if (bonus > 0 && sh->type->range_max>sh->type->range) {
        int crew = crew_skill(sh);
        int crew_bonus = (crew / sh->type->sumskill / 2) - 1;
        if (crew_bonus > 0) {
            bonus = _min(bonus, crew_bonus);
            bonus = _min(bonus, sh->type->range_max - sh->type->range);
        }
        else {
            bonus = 0;
        }
    }
    k += bonus;

    a = a_find(sh->attribs, &at_speedup);
    while (a != NULL && a->type == &at_speedup) {
        k += a->data.sa[0];
        a = a->next;
    }

    c = get_curse(sh->attribs, ct_find("shipspeedup"));
    while (c) {
        k += curse_geteffect_int(c);
        c = c->nexthash;
    }

    if (sh->damage>0) {
        int size = sh->size * DAMAGE_SCALE;
        k *= (size - sh->damage);
        k = (k + size - 1) / size;
    }
    return k;
}
Exemplo n.º 3
0
Arquivo: RT1.C Projeto: g8bpq/BPQ32
static void chkctl(CIRCUIT *ckt_from)
{
	NODE    *node, *ln;
	CIRCUIT *ckt_to;
	USER    *user, *su;
	char    *ncall, *ucall, *f1, *f2, *buf;

	if (ckt_from->buf[FORMAT_O] != FORMAT) return; // Not a control message.
	buf = strdup(ckt_from->buf + DATA_O);

// FORMAT and TYPE bytes are followed by node and user callsigns.

	ncall = buf;
	ucall = strlop(buf, ' ');
	if (!ucall) { free(buf); return; } // Not a control message.

// There may be at least one field after the node and user callsigns.
// Node leave (id_unlink) has no F1.

	f1 = strlop(ucall, ' ');

// If the frame came from an unknown node ignore it.
// If the frame came from us ignore it (loop breaking).

	node = node_find(ncall);
	if (!node || matchi(ncall, Node->calls)) { free(buf); return; }

	switch(ckt_from->buf[TYPE_O])
	{
// Data from user ucall at node ncall.

		case id_data :
			user = user_find(ucall);
			if (!user) break;
			text_tellu(user, f1, NULL, o_topic);

			for (ckt_to = circuit_hd; ckt_to; ckt_to = ckt_to->next)
				if ((ckt_to->flags & p_linked) &&
					   ckt_to->refcnt &&
					   !cn_find(ckt_to, node) &&
					   ct_find(ckt_to, user->topic)) nprintf(ckt_to->s, "%s\n", ckt_from->buf);
			break;

// User ucall at node ncall changed their Name/QTH info.

		case id_user :
			echo(ckt_from, node);  // Relay to other nodes.
			user = user_find(ucall);
			if (!user) break;
			f2 = strlop(f1, ' ');
			if (!f2) break;
			strnew(&user->name, f1);
			strnew(&user->qth,  f2);
			upduser(user);
			break;

// User ucall logged into node ncall.

		case id_join :
			echo(ckt_from, node);  // Relay to other nodes.
			f2 = strlop(f1, ' ');
			if (!f2) break;
			user = user_join(ckt_from, ucall, ncall, NULL);
			if (!user) break;
			ckt_from->refcnt++;
			text_tellu(user, rtjoin, NULL, o_all);
			strnew(&user->name, f1);
			strnew(&user->qth,  f2);
			upduser(user);
			break;

// User ucall logged out of node ncall.

		case id_leave :
			echo(ckt_from, node);  // Relay to other nodes.
			user = user_find(ucall);
			if (!user) break;
			f2 = strlop(f1, ' ');
			if (!f2) break;
			text_tellu(user, rtleave, NULL, o_all);
			ckt_from->refcnt--;
			cn_dec(ckt_from, node);
			strnew(&user->name, f1);
			strnew(&user->qth,  f2);
			upduser(user);
			user_leave(user);
			break;

// Node ncall lost its link to node ucall, alias f1.

		case id_unlink :
			echo(ckt_from, node);  // Relay to other nodes.
			ln = node_find(ucall);
			if (ln)	cn_dec(ckt_from, ln);
			break;

// Node ncall acquired a link to node ucall, alias f1.
// If we are not linked, is no problem, don't link.
// If we are linked, is a loop, do what?

		case id_link :
			echo(ckt_from, node);  // Relay to other nodes.
			ln = node_find(ucall);
			if (!ln && !matchi(ncall, Node->calls)) cn_inc(ckt_from, ucall, f1);
			break;

// User ucall at node ncall sent f2 to user f1.

		case id_send :
			user = user_find(ucall);
			if (!user) break;
			f2 = strlop(f1, ' ');
			if (!f2) break;
			su = user_find(f1);
			if (!su) break;

			if (su->circuit->flags & p_user)
				text_tellu(user, f2, f1, o_one);
			else
				echo(ckt_from, node);  // Relay to other nodes.
			break;

// User ucall at node ncall changed topic.

		case id_topic :
			echo(ckt_from, node);  //  Relay to other nodes.
			user = user_find(ucall);
			if (user) topic_chg(user, f1);
			break;

		default :  break;
	}

	free(buf);
}
Exemplo n.º 4
0
Arquivo: RT1.C Projeto: g8bpq/BPQ32
int rtloginu ()
{
	CIRCUIT *c, *circuit;
	USER    *user;

// Is this user already logged in to RT somewhere else?

	if (user_find(CurProc->user))
	{
		tputs("*** Already connected at another node.\n");
		return cmd_exit;
	}

	if (log_rt) tlogp("RT Login");

// Create a circuit for this user.

	circuit = circuit_new(p_user, CurProc->output);
	if (!circuit) return cmd_exit;

// Create the user entry.

	user = user_join(circuit, CurProc->user, Node->calls, Node->aliass);
	circuit->u.user = user;
	tputs("RoundTable Server.\nType /h for command summary.\nBringing up links to other nodes.\n");
	tputs("This may take a minute or two.\nThe /p command shows what nodes are linked.\n");
	text_tellu(user, rtjoin, NULL, o_all);
	user_tell(user, id_join);
	show_users();
	makelinks();

// Run in circles, scream and shout.

	for (;;) if (getinp(circuit))
	{
		if (circuit->buf[0] is '/')
		{
			if (!rt_cmd(circuit))
			{
				tputs("Returned to node.\n");
				logout(circuit);
				return cmd_ok;
			}
		}
		else
		{
			text_tellu(user, circuit->buf, NULL, o_topic); // To local users.

// To remote users.

			for (c = circuit_hd; c; c = c->next)
			if ((c->flags & p_linked) && c->refcnt && ct_find(c, user->topic))
				nprintf(c->s, "%c%c%s %s %s\n",
				FORMAT, id_data, Node->calls, user->call, circuit->buf);
		}
	}
	else
	{
		logout(circuit);
		return cmd_exit;
	}
}
Exemplo n.º 5
0
static int
cthelper_process_packet(const uint8_t *pkt, uint32_t pktlen,
			struct ctd_helper *h, int proto, uint16_t port,
			int type)
{
	struct pkt_buff *pktb;
	struct cthelper_proto_l2l3_helper *l3h;
	struct cthelper_proto_l4_helper *l4h;
	unsigned int l3hdr_len, l4protonum;
	struct nf_ct_entry *ct;
	int ret, this_proto;
	uint32_t dataoff, ctinfo = 0;

	l3h = cthelper_proto_l2l3_helper_find(pkt, &l4protonum, &l3hdr_len);
	if (l3h == NULL) {
		fprintf(stderr, "Unsupported layer 3 protocol, skipping.\n");
		return -1;
	}

	l4h = cthelper_proto_l4_helper_find(pkt, l4protonum);
	if (l4h == NULL) {
		fprintf(stderr, "Unsupported layer 4 protocol, skipping.\n");
		return -1;
	}
	/* get layer 3 header. */
	pkt += l3h->l2hdr_len;
	pktlen -= l3h->l2hdr_len;

	/* skip packet with mismatching protocol */
	this_proto = l3h->l4pkt_proto(pkt);
	if (this_proto != proto) {
		cthelper_test_stats.pkt_mismatch_proto++;
		return 0;
	}

	/* Look for the fake conntrack. */
	ct = ct_find(pkt, l3hdr_len, l3h, l4h, &ctinfo);
	if (ct == NULL) {
		/* It doesn't exist any, create one. */
		ct = ct_alloc(pkt, l3hdr_len, l3h, l4h);
		if (ct == NULL) {
			fprintf(stderr, "Not enough memory\n");
			return -1;
		}
		ct_add(ct);
		ctinfo += IP_CT_NEW;
	} else
		ctinfo += IP_CT_ESTABLISHED;

	/* skip packets with mismatching ports */
	if (!l4h->l4ct_cmp_port(ct->myct->ct, ntohs(port))) {
		cthelper_test_stats.pkt_mismatch_port++;
		return -1;
	}

	/*
	 * FIXME: reminder, implement this below in the kernel for cthelper.
	 */

	/* This packet contains no data, skip it. */
/*	if (l4h->l4pkt_no_data && l4h->l4pkt_no_data(pkt + l3hdr_len)) {
		NFG_DEBUG("skipping packet with no data\n");
		continue;
	} */

	/* Create the fake network buffer. */
	pktb = pktb_alloc(AF_INET, pkt, pktlen, 128);
	if (pktb == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return -1;
	}

	dataoff = l3h->l3pkt_hdr_len(pkt);
	if (dataoff > pktb_len(pktb)) {
		fprintf(stderr, "wrong layer 3 offset: %d > %d\n",
			dataoff, pktb_len(pktb));
		return -1;
	}

	/* tweak to run DNAT mangling code using the same PCAP file. */
	if (type == TEST_DNAT) {
		struct nf_conntrack *tmp = ct->myct->ct;
		/* as long as this is tested, who cares the destination IP? */
		in_addr_t addr = inet_addr("1.1.1.1");

		/* clone the real conntrack, to add DNAT information */
		ct->myct->ct = nfct_clone(ct->myct->ct);
		/* set fake DNAT information */
		nfct_set_attr_u32(ct->myct->ct, ATTR_STATUS, IPS_DST_NAT);
		nfct_set_attr_u32(ct->myct->ct, ATTR_ORIG_IPV4_DST, addr);
		/* pass it to helper */
		ret = h->cb(pktb, dataoff, ct->myct, ctinfo);
		/* restore real conntrack */
		nfct_destroy(ct->myct->ct);
		ct->myct->ct = tmp;

		if (pktb_mangled(pktb)) {
			int i;
			uint8_t *data = pktb_network_header(pktb);

			printf("\e[1;31mmangled content: ", pktb_len(pktb));

			for (i=0; i < pktb_len(pktb); i++)
				printf("%c", data[i]);

			printf("\e[0m\n");
		}
	} else
Exemplo n.º 6
0
int teach_cmd(unit * u, struct order *ord)
{
    static const curse_type *gbdream_ct = NULL;
    plane *pl;
    region *r = u->region;
    int teaching, i, j, count, academy = 0;
    skill_t sk = NOSKILL;

    if (gbdream_ct == 0)
        gbdream_ct = ct_find("gbdream");
    if (gbdream_ct) {
        if (get_curse(u->region->attribs, gbdream_ct)) {
            ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "gbdream_noteach", ""));
            return 0;
        }
    }

    if ((u_race(u)->flags & RCF_NOTEACH) || fval(u, UFL_WERE)) {
        cmistake(u, ord, 274, MSG_EVENT);
        return 0;
    }

    pl = rplane(r);
    if (pl && fval(pl, PFL_NOTEACH)) {
        cmistake(u, ord, 273, MSG_EVENT);
        return 0;
    }

    teaching = u->number * 30 * TEACHNUMBER;

    if ((i = get_effect(u, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */
        i = _min(i, u->number * TEACHNUMBER);
        /* Trank wirkt pro Schueler, nicht pro Lehrer */
        teaching -= i * 30;
        change_effect(u, oldpotiontype[P_FOOL], -i);
        j = teaching / 30;
        ADDMSG(&u->faction->msgs, msg_message("teachdumb", "teacher amount", u, j));
    }
    if (teaching == 0)
        return 0;

    count = 0;

    init_order(ord);

#if TEACH_ALL
    if (getparam(u->faction->locale) == P_ANY) {
        unit *student = r->units;
        skill_t teachskill[MAXSKILLS];
        int i = 0;
        do {
            sk = getskill(u->faction->locale);
            teachskill[i++] = sk;
        } while (sk != NOSKILL);
        while (teaching && student) {
            if (student->faction == u->faction) {
                if (LongHunger(student))
                    continue;
                if (getkeyword(student->thisorder) == K_STUDY) {
                    /* Input ist nun von student->thisorder !! */
                    init_order(student->thisorder);
                    sk = getskill(student->faction->locale);
                    if (sk != NOSKILL && teachskill[0] != NOSKILL) {
                        for (i = 0; teachskill[i] != NOSKILL; ++i)
                            if (sk == teachskill[i])
                                break;
                        sk = teachskill[i];
                    }
                    if (sk != NOSKILL
                        && eff_skill_study(u, sk,
                        r) - TEACHDIFFERENCE > eff_skill_study(student, sk, r)) {
                        teaching -= teach_unit(u, student, teaching, sk, true, &academy);
                    }
                }
            }
            student = student->next;
        }
#ifdef TEACH_FRIENDS
        while (teaching && student) {
            if (student->faction != u->faction
                && alliedunit(u, student->faction, HELP_GUARD)) {
                if (LongHunger(student))
                    continue;
                if (getkeyword(student->thisorder) == K_STUDY) {
                    /* Input ist nun von student->thisorder !! */
                    init_order(student->thisorder);
                    sk = getskill(student->faction->locale);
                    if (sk != NOSKILL
                        && eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student,
                        sk, r)) {
                        teaching -= teach_unit(u, student, teaching, sk, true, &academy);
                    }
                }
            }
            student = student->next;
        }
#endif
    }
    else
#endif
    {
        char zOrder[4096];
        order *new_order;

        zOrder[0] = '\0';
        init_order(ord);

        while (!parser_end()) {
            unit *u2;
            bool feedback;

            getunit(r, u->faction, &u2);
            ++count;

            /* Falls die Unit nicht gefunden wird, Fehler melden */

            if (!u2) {
                char tbuf[20];
                const char *uid;
                const char *token;
                /* Finde den string, der den Fehler verursacht hat */
                parser_pushstate();
                init_order(ord);

                for (j = 0; j != count - 1; ++j) {
                    /* skip over the first 'count' units */
                    getunit(r, u->faction, NULL);
                }

                token = getstrtoken();

                /* Beginne die Fehlermeldung */
                if (isparam(token, u->faction->locale, P_TEMP)) {
                    token = getstrtoken();
                    sprintf(tbuf, "%s %s", LOC(u->faction->locale,
                        parameters[P_TEMP]), token);
                    uid = tbuf;
                }
                else {
                    uid = token;
                }
                ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unitnotfound_id",
                    "id", uid));

                parser_popstate();
                continue;
            }

            feedback = u->faction == u2->faction
                || alliedunit(u2, u->faction, HELP_GUARD);

            /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in
             * ihre neuen Nummern uebersetzt. */
            if (zOrder[0])
                strcat(zOrder, " ");
            strcat(zOrder, unitid(u2));

            if (getkeyword(u2->thisorder) != K_STUDY) {
                ADDMSG(&u->faction->msgs,
                    msg_feedback(u, ord, "teach_nolearn", "student", u2));
                continue;
            }

            /* Input ist nun von u2->thisorder !! */
            parser_pushstate();
            init_order(u2->thisorder);
            sk = getskill(u2->faction->locale);
            parser_popstate();

            if (sk == NOSKILL) {
                ADDMSG(&u->faction->msgs,
                    msg_feedback(u, ord, "teach_nolearn", "student", u2));
                continue;
            }

            /* u is teacher, u2 is student */
            if (eff_skill_study(u2, sk, r) > eff_skill_study(u, sk,
                r) - TEACHDIFFERENCE) {
                if (feedback) {
                    ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_asgood",
                        "student", u2));
                }
                continue;
            }
            if (sk == SK_MAGIC) {
                /* ist der Magier schon spezialisiert, so versteht er nur noch
                 * Lehrer seines Gebietes */
                sc_mage *mage1 = get_mage(u);
                sc_mage *mage2 = get_mage(u2);
                if (!mage2 || !mage1 || (mage2->magietyp != M_GRAY
                    && mage1->magietyp != mage2->magietyp)) {
                    if (feedback) {
                        ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
                            "error_different_magic", "target", u2));
                    }
                    continue;
                }
            }

            teaching -= teach_unit(u, u2, teaching, sk, false, &academy);
        }
        new_order = create_order(K_TEACH, u->faction->locale, "%s", zOrder);
        replace_order(&u->orders, ord, new_order);
        free_order(new_order);      /* parse_order & set_order have each increased the refcount */
    }
    if (academy && sk != NOSKILL) {
        academy = academy / 30;     /* anzahl gelehrter wochen, max. 10 */
        learn_skill(u, sk, academy / 30.0 / TEACHNUMBER);
    }
    return 0;
}