示例#1
8
bool GameChat::handle_special_commands(GameState* gs,
		const std::string& command) {
	ChatMessage printed;
	const char* content;
	PlayerInst* p = gs->local_player();

	//Spawn monster
	if (starts_with(command, "!spawn ", &content)) {
		const char* rest = content;
		int amnt = strtol(content, (char**)&rest, 10);
		if (content == rest)
			amnt = 1;
		rest = skip_whitespace(rest);

		int enemy = get_enemy_by_name(rest, false);
		if (enemy == -1) {
			printed.message = "No such monster, '" + std::string(rest) + "'!";
			printed.message_colour = Colour(255, 50, 50);
		} else {
			printed.message = std::string(rest) + " has spawned !";
			generate_enemy_after_level_creation(gs, enemy, amnt);
			printed.message_colour = Colour(50, 255, 50);
		}
		add_message(printed);
		return true;
	}

	//Set game speed
	if (starts_with(command, "!gamespeed ", &content)) {
		int gamespeed = squish(atoi(content), 1, 200);
		gs->game_settings().time_per_step = gamespeed;
		printed.message = std::string("Game speed set.");
		printed.message_colour = Colour(50, 255, 50);
		add_message(printed);
		return true;
	}

	//Gain XP
	if (starts_with(command, "!gainxp ", &content)) {
		int xp = atoi(content);
		if (xp > 0 && xp < 999999) {
			printed.message = std::string("You have gained ") + content
					+ " experience.";
			printed.message_colour = Colour(50, 255, 50);
			add_message(printed);
			p->gain_xp(gs, xp);
		} else {
			printed.message = "Invalid experience amount!";
			printed.message_colour = Colour(255, 50, 50);
			add_message(printed);
		}
		return true;
	}

	//Create item
	if (starts_with(command, "!item ", &content)) {
		const char* rest = content;
		int amnt = strtol(content, (char**)&rest, 10);
		if (content == rest)
			amnt = 1;
		rest = skip_whitespace(rest);

		int item = get_item_by_name(rest, false);
		if (item == -1) {
			printed.message = "No such item, '" + std::string(rest) + "'!";
			printed.message_colour = Colour(255, 50, 50);
		} else {
			printed.message = std::string(rest) + " put in your inventory !";
			p->stats().equipment.inventory.add(Item(item), amnt);
			printed.message_colour = Colour(50, 255, 50);
		}
		add_message(printed);
		return true;
	}

	//Kill all monsters
	if (starts_with(command, "!killall", &content)) {
		MonsterController& mc = gs->monster_controller();
		for (int i = 0; i < mc.monster_ids().size(); i++) {
			EnemyInst* inst = (EnemyInst*)gs->get_instance(mc.monster_ids()[i]);
			if (inst) {
				inst->damage(gs, 99999);
			}
		}
		printed.message = "Killed all monsters.";
		printed.message_colour = Colour(50, 255, 50);
		add_message(printed);
		return true;
	}

	lua_State* L = gs->get_luastate();
	static LuaValue script_globals;
	if (script_globals.empty()) {
		script_globals.table_initialize(L);
//		script_globals.push(L);
//		int script = lua_gettop(L);
//		lua_pushvalue(L, LUA_GLOBALSINDEX);
//		lua_setmetatable(L, script);
//		lua_pop(L, 1);
	}

	lua_push_gameinst(L, p);
	script_globals.table_pop_value(L, "player");
	lua_push_combatstats(L, p);
	script_globals.table_pop_value(L, "stats");

	//Run lua command
	if (starts_with(command, "!lua ", &content)) {
//		std::string luafunc = std::string(content);

		int prior_top = lua_gettop(L);

		luaL_loadstring(L, content);
		if (lua_isstring(L, -1)) {
			const char* val = lua_tostring(L, -1);
			add_message(val, /*iserr ? Colour(255,50,50) :*/
			Colour(120, 120, 255));
			return true;
		}

		int lfunc = lua_gettop(L);
		script_globals.push(L);
		lua_setfenv(L, lfunc);

		bool iserr = (lua_pcall(L, 0, LUA_MULTRET, 0) != 0);

		int current_top = lua_gettop(L);

		for (; prior_top < current_top; prior_top++) {
			if (lua_isstring(L, -1)) {
				const char* val = lua_tostring(L, -1);
				add_message(val,
						iserr ? Colour(255, 50, 50) : Colour(120, 120, 255));
			}
			lua_pop(L, 1);
		}

		return true;
	}
	//Run lua file
	if (starts_with(command, "!luafile ", &content)) {
		int prior_top = lua_gettop(L);

		int err_func = luaL_loadfile(L, content);
		if (err_func) {
			const char* val = lua_tostring(L, -1);
			add_message(val, Colour(120, 120, 255));
			lua_pop(L, 1);
			return true;
		}

		int lfunc = lua_gettop(L);
		script_globals.push(L);
		lua_setfenv(L, lfunc);

		bool err_call = (lua_pcall(L, 0, 0, 0) != 0);
		if (err_call) {
			const char* val = lua_tostring(L, -1);
			add_message(val, Colour(120, 120, 255));
			lua_pop(L, 1);
		}
		return true;
	}

	return false;
}
示例#2
0
void PlayerInst::pickup_item(GameState* gs, const GameAction& action) {
	const int PICKUP_RATE = 10;
	GameInst* inst = gs->get_instance(action.use_id);
	if (!inst) {
		return;
	}
	ItemInst* iteminst = dynamic_cast<ItemInst*>(inst);
	LANARTS_ASSERT(iteminst);

	const Item& type = iteminst->item_type();
	int amnt = iteminst->item_quantity();

	bool inventory_full = false;
	if (type.id == get_item_by_name("Gold")) {
		gold() += amnt;
	} else {
		itemslot_t slot = inventory().add(type);
		if (slot == -1) {
			inventory_full = true;
		} else if (projectile_should_autowield(equipment(), type,
				this->last_chosen_weaponclass)) {
			projectile_smart_equip(inventory(), slot);
		}
	}

	if (!inventory_full) {
		cooldowns().reset_pickup_cooldown(PICKUP_RATE);
		gs->remove_instance(iteminst);
	}
}
示例#3
0
EquipmentEntry& get_equipment_entry(projectile_id id) {
	if (id == NO_ITEM) {
		return get_equipment_entry(get_item_by_name("Nothing"));
	}
	ItemEntry* item = game_item_data.at(id);

	return dynamic_cast<EquipmentEntry&>(*item);
}
示例#4
0
equipment_id get_equipment_by_name(const char* name) {
	if (strcmp(name, "Nothing") == 0) {
		return NO_ITEM;
	}
	item_id id = get_item_by_name(name);
	LANARTS_ASSERT(dynamic_cast<EquipmentEntry*>(game_item_data.at(id)));
	return (equipment_id) id;
}
示例#5
0
WeaponEntry& get_weapon_entry(weapon_id id) {
	if (id == NO_ITEM) {
		return get_weapon_entry(get_item_by_name("Unarmed"));
	}
	ItemEntry* item = game_item_data.get(id);

	return dynamic_cast<WeaponEntry&>(*item);
}
示例#6
0
weapon_id get_weapon_by_name(const char* name) {
	if (strcmp(name, "Unarmed") == 0) {
		return NO_ITEM;
	}
	item_id id = get_item_by_name(name);
	LANARTS_ASSERT(dynamic_cast<WeaponEntry*>(game_item_data.get(id)));
	return (weapon_id)id;
}
void PlayerInst::enqueue_not_enough_mana_actions(GameState* gs) {
    const int AUTOUSE_MANA_POTION_CNT = 2;
    int item_slot = inventory().find_slot(get_item_by_name("Mana Potion"));
    if (gs->game_settings().autouse_mana_potions
            && autouse_mana_potion_try_count >= AUTOUSE_MANA_POTION_CNT
            && item_slot != -1) {
        queued_actions.push_back(
            game_action(gs, this, GameAction::USE_ITEM, item_slot));
        autouse_mana_potion_try_count = 0;
    } else {
        autouse_mana_potion_try_count++;
    }
}
示例#8
0
	int equip(lua_State* L) {
		CombatGameInst* combatinst;
		if ((combatinst = dynamic_cast<CombatGameInst*>(get_inst()))) {
			int args = lua_gettop(L);

			lua_pushstring(L, "name");
			lua_gettable(L, 1);
			const char* itemname = lua_tostring(L, lua_gettop(L));
			item_id item = get_item_by_name(itemname);
			int amnt = args >= 2 ? lua_tointeger(L, 2) : 1;
			combatinst->equip(item, amnt);
			lua_pop(L, 1);
		}
		return 0;
	}
示例#9
0
文件: cube.c 项目: naxIO/magebattle
void make_cube(
    float *data, float ao[6][4], float light[6][4],
    int left, int right, int top, int bottom, int front, int back,
    float x, float y, float z, float n, int w)
{
    struct item_list *it = get_item_by_id(ABS(w));
    if (it == NULL) {
        it = get_item_by_name("error");
    }
    int wleft = it->tile->left;
    int wright = it->tile->right;
    int wtop = it->tile->top;
    int wbottom = it->tile->bottom;
    int wfront = it->tile->front;
    int wback = it->tile->back;
    make_cube_faces(
        data, ao, light,
        left, right, top, bottom, front, back,
        wleft, wright, wtop, wbottom, wfront, wback,
        x, y, z, n);
}
示例#10
0
void PlayerInst::use_weapon(GameState* gs, const GameAction& action) {
    WeaponEntry& wentry = weapon().weapon_entry();
    MTwist& mt = gs->rng();
    const int MAX_MELEE_HITS = 10;
    EffectiveStats& estats = effective_stats();
    if (!cooldowns().can_doaction()) {
        return;
    }

    Pos start(x, y);
    Pos actpos(action.action_x, action.action_y);

    if (wentry.uses_projectile && !equipment().has_projectile()) {
        return;
    }

    int cooldown = 0;

    if (equipment().has_projectile()) {
        const Projectile& projectile = equipment().projectile;
        ProjectileEntry& pentry = projectile.projectile_entry();
        item_id item = get_item_by_name(pentry.name.c_str());
        int weaprange = std::max(wentry.range, pentry.range);

        AttackStats weaponattack(weapon());

        bool wallbounce = false;
        int nbounces = 0;
        float movespeed = pentry.speed;

        cooldown = std::max(wentry.cooldown, pentry.cooldown);

        //XXX: Horrible hack REMOVE THIS LATER
        if (class_stats().class_type().name == "Archer"
                && pentry.weapon_class == "bows") {
            int xplevel = class_stats().xplevel;
            float movebonus = class_stats().xplevel / 4.0f;
            if (movebonus > 2) {
                movebonus = 2;
            }
            float cooldown_mult = 1.0f - (class_stats().xplevel - 1) / 20.0f;
            if (cooldown_mult <= 0.85) {
                cooldown_mult = 0.85;
            }
            cooldown *= cooldown_mult;
            movespeed += movebonus;
            if (xplevel >= 3 && core_stats().mp >= 5) {
                nbounces = 2;
                core_stats().mp -= 5;
            }
        }

        GameInst* bullet = new ProjectileInst(projectile,
                                              effective_atk_stats(mt, weaponattack), id, start, actpos,
                                              movespeed, weaprange, NONE, wallbounce, nbounces);
        gs->add_instance(bullet);
        equipment().use_ammo();
    } else {
        int weaprange = wentry.range + this->radius + TILE_SIZE / 2;
        float mag = distance_between(actpos, Pos(x, y));
        if (mag > weaprange) {
            float dx = actpos.x - x, dy = actpos.y - y;
            actpos = Pos(x + dx / mag * weaprange, y + dy / mag * weaprange);
        }

        GameInst* enemies[MAX_MELEE_HITS];

        int max_targets = std::min(MAX_MELEE_HITS, wentry.max_targets);

        int numhit = get_targets(gs, this, actpos.x, actpos.y, wentry.dmgradius,
                                 enemies, max_targets);

        if (numhit == 0) {
            return;
        }

        for (int i = 0; i < numhit; i++) {
            EnemyInst* e = (EnemyInst*)enemies[i];
            lua_hit_callback(gs->get_luastate(), wentry.on_hit_func, this, e);
            if (attack(gs, e, AttackStats(equipment().weapon))) {
                PlayerData& pc = gs->player_data();
                signal_killed_enemy();

                char buffstr[32];
                int amnt = round(
                               double(e->xpworth()) / pc.all_players().size());
                players_gain_xp(gs, amnt);
                snprintf(buffstr, 32, "%d XP", amnt);
                gs->add_instance(
                    new AnimatedInst(Pos(e->x - 5, e->y - 5), -1, 25,
                                     Posf(), Posf(), AnimatedInst::DEPTH, buffstr,
                                     Colour(255, 215, 11)));
            }
        }
        cooldown = wentry.cooldown;
    }

    cooldowns().reset_action_cooldown(cooldown * estats.cooldown_mult);

    reset_rest_cooldown();
}
示例#11
0
void PlayerInst::enqueue_io_equipment_actions(GameState* gs,
		bool do_stopaction) {
	GameView& view = gs->view();
	bool mouse_within = gs->mouse_x() < gs->view().width;
	int rmx = view.x + gs->mouse_x(), rmy = view.y + gs->mouse_y();

	int level = gs->get_level()->id();
	int frame = gs->frame();
	bool item_used = false;
	IOController& io = gs->io_controller();

	Pos p(gs->mouse_x() + view.x, gs->mouse_y() + view.y);
	obj_id target = this->current_target;
	GameInst* targetted = gs->get_instance(target);
	if (targetted)
		p = Pos(targetted->x, targetted->y);

// We may have already used an item eg due to auto-use of items
	bool used_item = false;

//Item use
	for (int i = 0; i < 9 && !used_item; i++) {
		if (io.query_event(IOEvent(IOEvent::USE_ITEM_N, i))) {
			if (inventory().get(i).amount() > 0) {
				item_used = true;
				queued_actions.push_back(
						GameAction(id, GameAction::USE_ITEM, frame, level, i,
								p.x, p.y));
			}
		}
	}
	if (!used_item && gs->game_settings().autouse_health_potions
			&& core_stats().hp < AUTOUSE_HEALTH_POTION_THRESHOLD) {
		int item_slot = inventory().find_slot(
				get_item_by_name("Health Potion"));
		if (item_slot > -1) {
			queued_actions.push_back(
					game_action(gs, this, GameAction::USE_ITEM, item_slot));
			used_item = true;
		}
	}

//Item pickup
	GameInst* inst = NULL;
	if (cooldowns().can_pickup()
			&& gs->object_radius_test(this, &inst, 1, &item_colfilter)) {
		ItemInst* iteminst = (ItemInst*)inst;
		Item& item = iteminst->item_type();

		bool was_dropper = iteminst->last_held_by() == id;
		bool dropper_autopickup = iteminst->autopickup_held();

		bool autopickup = (item.is_normal_item() && !was_dropper
				&& !dropper_autopickup) || (was_dropper && dropper_autopickup);

		bool wieldable_projectile = projectile_should_autowield(equipment(),
				item, this->last_chosen_weaponclass);

		bool pickup_io = gs->key_down_state(SDLK_LSHIFT)
				|| gs->key_down_state(SDLK_RSHIFT);

		if (do_stopaction || wieldable_projectile || pickup_io || autopickup)
			queued_actions.push_back(
					GameAction(id, GameAction::PICKUP_ITEM, frame, level,
							iteminst->id));
	}
}
示例#12
0
//Lua argument getters
item_id item_from_lua(lua_State* L, int idx) {
	return get_item_by_name(lua_tostring(L, idx));
}