///@param {Id.Buffer} memory ///@param {Pointer} system ///@param {Id.vertex_format} vertex_format ///@param {Id.vertex_buffer} vertex_buffer ///@param {Real} projectile_count ///@param {Struct.Texturepage} texturepage ///@param {Id.DsList} effects function _ProjectileEffectSystem(memory, system, vertex_format, vertex_buffer, projectile_count, texturepage, effects) constructor { self.memory = memory; self.system = system; self.vertex_format = vertex_format; self.vertex_buffer = vertex_buffer; self.projectile_count = projectile_count; self.texturepage = texturepage; self.effects = effects; } ///@param {Function} create_func ///@param {Real} interval ///@param {Id.DsList} list function _ProjectileEffectSystemEffect(create_func, interval, list) constructor { self.interval = interval; self.time = 0; self.instances = list; self.create_func = create_func; } ///@param {Real} projectile_count ///@return {_ProjectileEffectSystem} function pem_create(projectile_count, texturepage) { vertex_format_begin(); vertex_format_add_position_3d(); vertex_format_add_color(); vertex_format_add_texcoord(); vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Position vertex_format_add_custom(vertex_type_float2, vertex_usage_color); // Scale vertex_format_add_custom(vertex_type_float1, vertex_usage_color); // Angle vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Rotation direction vertex_format_add_custom(vertex_type_float1, vertex_usage_color); // Animation vertex_format_add_custom(vertex_type_float3, vertex_usage_color); // Hue saturation value var _vertex_format = vertex_format_end(); var _buffer = buffer_create(pem_get_size(projectile_count), buffer_fixed, 1); buffer_fill(_buffer, 0, buffer_u32, 0, buffer_get_size(_buffer)); var _ptr = buffer_get_address(_buffer); pem_init(_ptr, projectile_count, TEXTUREPAGE_SIZE); var _vertex_buffer = vertex_create_buffer_from_buffer_ext( _buffer, _vertex_format, pem_get_vertex_buffer_offset(), projectile_count * 6); return new _ProjectileEffectSystem(_buffer, _ptr, _vertex_format, _vertex_buffer, projectile_count, texturepage, ds_list_create()); } ///@param {Struct._ProjectileEffectSystem} system ///@param {Function} create_func ///@param {Real} interval function pem_effect_add(system, create_func, interval) { if (interval <= 0.0) { printerr("Interval cannot be equal or lower than 0.0", ERROR_LOC); return; } var _effect = new _ProjectileEffectSystemEffect(create_func, interval, ds_list_create()); ds_list_add(system.effects, _effect); } ///@param {Struct._ProjectileEffectSystem} system ///@param {Real} index ///@param {Id.Instance} inst function pem_effect_instance_add(system, index, inst) { ds_list_add(system.effects[|index].instances, inst); } ///@param {Struct._ProjectileEffectSystemEffect} effect function _pem_effect_destroy(effect) { ds_list_destroy(effect.instances); } ///@param {Struct._ProjectileEffectSystem} system function pem_update_vertex_buffer(system) { vertex_update_buffer_from_buffer( system.vertex_buffer, 0, system.memory, pem_get_vertex_buffer_offset(), pem_get_vertex_buffer_size(system.projectile_count)); } ///@param {Struct._ProjectileEffectSystem} system function pem_destroy(system) { buffer_delete(system.memory); vertex_format_delete(system.vertex_format); vertex_delete_buffer(system.vertex_buffer); for (var i = 0, n = ds_list_size(system.effects); i < n; i++) { _pem_effect_destroy(system.effects[|i]); } ds_list_destroy(system.effects); } ///@param {Struct._ProjectileEffectSystem} system function pem_update(system) { for (var i = 0, n = ds_list_size(system.effects); i < n; i++) { var _effect = system.effects[|i]; _effect.time += 1.0; while (_effect.time >= _effect.interval) { _effect.time -= _effect.interval; for (var j = 0, nn = ds_list_size(_effect.instances); j < nn; j++) { if (!instance_exists(_effect.instances[|j])) { ds_list_delete(_effect.instances, j); j--; nn--; continue; } _effect.create_func(system, _effect.instances[|j]); } } } _pem_update(system.system); pem_update_vertex_buffer(system); } ///@param {Struct._ProjectileEffectSystem} system function pem_set(system) { _pem_set(system.system); } ///@param {Struct._ProjectileEffectSystem} system function pem_draw(system) { shader_set(shdProjectileEffect); vertex_submit(system.vertex_buffer, pr_trianglelist, system.texturepage.texture); shader_reset(); } ///@param {Struct._ProjectileEffectSystem} system ///@param {Real} x ///@param {Real} y ///@param {Asset.GMSprite} sprite_index function pem_instance_create_from_sprite(system, x, y, sprite_index) { var _info = texturepage_sprite_get_info(system.texturepage, sprite_index); if (_info == -1) { printerr($"Couldn't create effect instance with sprite {sprite_get_name(sprite_index)}. It wasn't on the texture page", ERROR_LOC); return; } return pem_instance_create_from_info(x, y, _info); } ///@param {Struct._ProjectileEffectSystem} system ///@param {Real} x ///@param {Real} y ///@param {Real} sprite_origin ///@param {Asset.GMSprite} sprite_index function pem_instance_create_from_sprite_ext(system, x, y, origin, sprite_index) { var _info = texturepage_sprite_get_info(system.texturepage, sprite_index); if (_info == -1) { printerr("Couldn't create effect instance with sprite {sprite_get_name(sprite_index)}. It wasn't on the texture page", ERROR_LOC); return; } return pem_instance_create_from_info_ext(x, y, origin, _info); } ///@param {Real} x ///@param {Real} y ///@param {Struct.TexturepageEntryInfo} info function pem_instance_create_from_info(x, y, info) { return pem_instance_create( x, y, sprite_get_width(info.sprite_index), sprite_get_height(info.sprite_index), sprite_get_xoffset(info.sprite_index), sprite_get_yoffset(info.sprite_index), info.uvs[UvData.Left], info.uvs[UvData.Top], info.uvs[UvData.Right], info.uvs[UvData.Bottom], sprite_get_number(info.sprite_index)); } ///@param {Real} x ///@param {Real} y ///@param {Real} sprite_origin ///@param {Struct.TexturepageEntryInfo} info function pem_instance_create_from_info_ext(x, y, sprite_origin, info) { return pem_instance_create_origin( x, y, sprite_get_width(info.sprite_index), sprite_get_height(info.sprite_index), sprite_origin, info.uvs[UvData.Left], info.uvs[UvData.Top], info.uvs[UvData.Right], info.uvs[UvData.Bottom], sprite_get_number(info.sprite_index)); }