예제 #1
0
void GameInstSet::deserialize(GameState* gs, SerializeBuffer& serializer) {
	serializer.read_int(grid_w);
	serializer.read_int(grid_h);

	//Resize and clear
	unit_grid.resize(grid_w * grid_h);
	clear();

	int amnt;
	serializer.read_int(amnt);
	serializer.read_int(next_id);

	for (int i = 0; i < amnt; i++) {
		InstType type;
		int id;
		serializer.read_int(type);
		serializer.read_int(id);
		printf("Deserializing id=%d\n", id);
		GameInst* inst = get_instance(id);
		bool has_inst = inst != NULL;
		if (!has_inst) {
			inst = from_inst_type(type);
			inst->deserialize(gs, serializer);
			inst->last_x = inst->x;
			inst->last_y = inst->y;
			inst->id = id;
			add_instance(inst, inst->id);

		} else {
			safe_deserialize(inst, gs, serializer);
		}
		LANARTS_ASSERT(
				serializer_equals_read(serializer, inst->integrity_hash()));
	}
}
예제 #2
0
unsigned int GameInstSet::hash() const {
	unsigned int hash = 0xbabdabe;
	std::vector<GameInst*> as_vector = to_vector();
	for (int i = 0; i < as_vector.size(); i++) {
		GameInst* inst = as_vector[i];
		if (!dynamic_cast<AnimatedInst*>(inst)) {
			hash ^= inst->integrity_hash();
			hash ^= hash * 31337; //Ad hoc hashing yay
		}
	}
	return hash;
}
예제 #3
0
void GameInstSet::clear() {
	for (int i = 0; i < unit_capacity; i++) {
		GameInst* inst = unit_set[i].inst;
		if (valid_inst(inst)) {
			inst->free_reference();
		}
	}
	next_id = 1;
	unit_amnt = 0;
	depthlist_map.clear();
	memset(&unit_set[0], 0, unit_capacity * sizeof(InstanceState));
	memset(&unit_grid[0], 0, grid_w * grid_h * sizeof(InstanceLinkedList));
}
예제 #4
0
GameInstSet::~GameInstSet() {

	for (int i = 0, j = 0; i < unit_capacity; i++) {
		GameInst* inst = unit_set[i].inst;
		if (valid_inst(inst)) {
			inst->free_reference();
		}
	}

	for (int i = 0; i < deallocation_list.size(); i++) {
		deallocation_list[i]->free_reference();
	}
}
예제 #5
0
void GameInstSet::step(GameState* gs) {
	for (int i = 0; i < deallocation_list.size(); i++) {
		deallocation_list[i]->free_reference();
	}
	deallocation_list.clear();
	for (int i = 0; i < unit_capacity; i++) {
		GameInst* inst = unit_set[i].inst;
		if (valid_inst(inst)) {
			inst->destroyed = false;
			inst->step(gs);
			update_instance_for_step(&unit_set[i], inst);
		}
	}
}
예제 #6
0
static void process_level_hash(GameState* gs, GameLevelState* level,
		SerializeBuffer& sb, bool isw) {
	if (level->id() == -1)
		return;

	std::vector<GameInst*> instances = level->game_inst_set().to_vector();
	for (int i = 0; i < instances.size(); i++) {
		GameInst* inst = instances[i];
		if (!dynamic_cast<AnimatedInst*>(inst)) {
			write_or_assert_hash(sb, inst->integrity_hash(), isw);
		}
	}
	//compare magic number marker
	write_or_assert_hash(sb, 0xABCDFFFF, isw);
	write_or_assert_hash(sb, level->game_inst_set().hash(), isw);
}
예제 #7
0
void GameInstSet::serialize(GameState* gs, SerializeBuffer& serializer) {
	serializer.write_int(grid_w);
	serializer.write_int(grid_h);

	serializer.write_int(size());
	serializer.write_int(next_id);
	DepthMap::const_iterator it = depthlist_map.end();
	for (int ind = 0; it != depthlist_map.begin();) {
		--it;
		InstanceState* state = it->second.start_of_list;
		while (state) {
			GameInst* inst = state->inst;
			serializer.write_int(get_inst_type(inst));
			serializer.write_int(inst->id);
			inst->serialize(gs, serializer);
			serializer.write_int(inst->integrity_hash());
			state = state->next_same_depth;
		}
	}
}
예제 #8
0
void GameInstSet::copy_to(GameInstSet& inst_set) const {

	DepthMap::const_iterator it = depthlist_map.end();
	//Synch live objects
	for (int ind = 0; it != depthlist_map.begin();) {
		--it;
		InstanceState* state = it->second.start_of_list;
		while (state) {
			GameInst* inst = state->inst;
			obj_id id = inst->id;
			GameInst* oinst = inst_set.get_instance(id);
			if (oinst == NULL || typeid(inst) != typeid(oinst)) {
				inst_set.add_instance(inst->clone(), id);
				if (oinst)
					oinst->destroyed = true;
			}
			state = state->next_same_depth;
		}
	}
	//Remove dead objects
	for (int i = 0; i < inst_set.unit_capacity; i++) {
		InstanceState* state = &inst_set.unit_set[i];
		GameInst* oinst = state->inst;
		if (valid_inst(oinst)) {
			if (!oinst->destroyed) {
				GameInst* inst = get_instance(oinst->id);
				if (inst != NULL) {
					inst_set.__update_collision_position(state,
							Pos(oinst->x, oinst->y), Pos(inst->x, inst->y));
					inst->copy_to(oinst);
				} else
					inst_set.__remove_instance(state);
				inst->free_reference();
			}

		}
	}
	inst_set.next_id = this->next_id;
	LANARTS_ASSERT(check_copy_integrity(inst_set));
}
예제 #9
0
// dx & dy indicates moving direction, useful for choosing melee attack targets
bool PlayerInst::enqueue_io_spell_and_attack_actions(GameState* gs, float dx,
        float dy) {
    GameView& view = gs->view();
    WeaponEntry& wentry = weapon().weapon_entry();

    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(), frame = gs->frame();

    bool is_moving = (dx != 0.0f || dy != 0.0f);
    IOController& io = gs->io_controller();
    bool attack_used = enqueue_io_spell_actions(gs);

    bool autotarget = io.query_event(IOEvent::AUTOTARGET_CURRENT_ACTION)
                      || io.query_event(IOEvent::ACTIVATE_SPELL_N);
    bool mousetarget = io.query_event(IOEvent::MOUSETARGET_CURRENT_ACTION);

    bool weaponuse = spell_selected() == -1;

    // choose & use weapon
    if (io.query_event(IOEvent::USE_WEAPON)) {
        queued_actions.push_back(
            game_action(gs, this, GameAction::CHOSE_SPELL, -1));
        autotarget = true;
        weaponuse = true;
    }

    if (spell_selected() >= 0
            && spells_known().get_entry(spell_selected()).mp_cost
            > core_stats().mp) {
        weaponuse = true;
    }

    // weapon use
    if (!attack_used && weaponuse && (autotarget || mousetarget)) {

        bool is_projectile = wentry.uses_projectile
                             || equipment().has_projectile();

        MonsterController& mc = gs->monster_controller();
        GameInst* curr_target = gs->get_instance(current_target);
        GameInst* target = NULL;
        Pos targ_pos;

        if (is_projectile) {
            if (mousetarget) {
                targ_pos = Pos(rmx, rmy);
            } else if (autotarget && curr_target) {
                targ_pos = curr_target->pos();
            }
        } else {
            if (mousetarget) {
                dx = rmx - x, dy = rmy - y;
            }
            target = get_weapon_autotarget(gs, this, curr_target, dx, dy);
            if (target) {
                targ_pos = Pos(target->x, target->y);

            }
            if (!is_moving && !target && !mousetarget && spell_selected() == -1
                    && curr_target && !is_projectile) {
                int vx, vy;
                GameInst* closest = get_closest_monster(gs, this);

                if (closest
                        && decide_attack_movement(pos(), closest->pos(),
                                                  TILE_SIZE / 4, vx, vy)) {
                    queued_actions.push_back(
                        game_action(gs, this, GameAction::MOVE, spellselect,
                                    round(vx), round(vy)));
                }
            }
        }
        if (target || (is_projectile && (mousetarget || curr_target))) {
            queued_actions.push_back(
                game_action(gs, this, GameAction::USE_WEAPON, spellselect,
                            targ_pos.x, targ_pos.y));
            attack_used = true;
        }
    }
    return attack_used;
}
예제 #10
0
/* Helper method for drawing basic stat information*/
static void draw_player_base_stats(GameState* gs, PlayerInst* player_inst,
		int x, int y, int width) {
	ClassStats& class_stats = player_inst->class_stats();
	CoreStats& core = player_inst->effective_stats().core;

	int x_interval = width / 2;
	int y_interval = 15;

	gs->font().drawf(ldraw::DrawOptions(COL_WHITE).origin(ldraw::CENTER), Pos(x - 10 + x_interval, 15), "Level %d",
			class_stats.xplevel);

//	y += y_interval;

	Pos p1(x, y), p2(x + x_interval, y);

	gs->font().drawf(COL_WHITE, Pos(x, y), "Kills %d",
			player_inst->score_stats().kills);

	if (gs->game_settings().regen_on_death) {
		gs->font().drawf(COL_PALE_RED, Pos(x + x_interval, y), "Deaths %d",
				player_inst->score_stats().deaths);
	} else {
		gs->font().draw(COL_PALE_BLUE, Pos(x + x_interval, y), "Hardcore");
	}

	p1.y += y_interval;
	p2.y += y_interval;

	gs->font().drawf(COL_WHITE, p1, "%s", gs->get_level()->label().c_str());
	gs->font().drawf(COL_GOLD, p2, "Gold %d", player_inst->gold());

	p1.y += y_interval;
	p2.y += y_interval;

	gs->font().drawf(COL_MUTED_GREEN, p1, "Strength %d", core.strength);
	gs->font().drawf(COL_MUTED_GREEN, p2, "Magic %d", core.magic);

	p1.y += y_interval;
	p2.y += y_interval;

	gs->font().drawf(COL_MUTED_GREEN, p1, "Defence %d", core.defence);
	gs->font().drawf(COL_MUTED_GREEN, p2, "Will %d", core.willpower);

	p1.y += y_interval;
	p2.y += y_interval;

	// Draw hashes if in network debug mode
	if (gs->game_settings().network_debug_mode) {
		// Draw level hash

		gs->font().drawf(COL_MUTED_GREEN, p1, "Hash 0x%X",
				gs->get_level()->game_inst_set().hash());

		p1.y += y_interval;

		// Draw player hashes
		for (int i = 0; i < gs->player_data().all_players().size(); i++) {
			unsigned int hash =
					gs->player_data().all_players()[i].player()->integrity_hash();
			gs->font().drawf(COL_MUTED_GREEN, p1, "P%d 0x%X", i + 1, hash);
			p1.y += y_interval;
		}

		// Draw monster hashes (note, takes up a lot of screen space)
		for (int i = 0; i < gs->monster_controller().monster_ids().size();
				i++) {
			GameInst* inst = gs->get_instance(
					gs->monster_controller().monster_ids()[i]);
			if (inst) {
				gs->font().drawf(COL_MUTED_GREEN, Pos(0, i * y_interval),
						"M%d 0x%X", i + 1, inst->integrity_hash());
			}
		}
	}
}