// Copyright (c) 2023 Alex Diener. All rights reserved. #include "PROJECT_NAME/Atoms.h" #include "PROJECT_NAME/EntityPushBlock.h" #include "PROJECT_NAME/RoomState.h" #include "PROJECT_NAME/Sprites.h" #include "PROJECT_NAME/Utilities.h" #define stemobject_implementation EntityPushBlock stemobject_vtable_begin(); stemobject_vtable_entry(createWithEncodedState); stemobject_vtable_entry(initWithEncodedState); stemobject_vtable_entry(copy); stemobject_vtable_entry(initCopy); stemobject_vtable_entry(dispose); stemobject_vtable_entry(getComponent); stemobject_vtable_entry(preadvance); stemobject_vtable_entry(postadvance); stemobject_vtable_entry(isEqual); stemobject_vtable_entry(enumerateProperties); stemobject_vtable_end(); EntityPushBlock * EntityPushBlock_create(Vector2i position, bool multipush, struct RoomState * roomState) { stemobject_create_implementation(init, position, multipush, roomState) } static void initComponents(EntityPushBlock * self, Vector2i position, bool multipush) { stemobject_assign_vtable(self->collidableComponent, EntityComponent_collidable); stemobject_assign_vtable(self->positionComponent, EntityComponent_position); stemobject_assign_vtable(self->pushableComponent, EntityComponent_pushable); stemobject_assign_vtable(self->spriteComponent, EntityComponent_sprite); EntityComponent_collidable_init(&self->collidableComponent, alwaysSolidCollisionCallback, NULL); EntityComponent_position_init(&self->positionComponent, position); EntityComponent_pushable_init(&self->pushableComponent, multipush); EntityComponent_sprite_init(&self->spriteComponent, multipush ? SPRITE_ID_MULTIPUSH_BLOCK : SPRITE_ID_PUSH_BLOCK, DRAW_LAYER_ENTITY, 0); } bool EntityPushBlock_init(EntityPushBlock * self, Vector2i position, bool multipush, struct RoomState * roomState) { call_super(init, self, roomState); initComponents(self, position, multipush); return true; } EntityPushBlock * EntityPushBlock_createWithEncodedState(struct memreadContext * memreadContext, struct RoomState * roomState) { GameEntity_createWithEncodedState_implementation(); } void EntityPushBlock_initWithEncodedState(EntityPushBlock * self, struct memreadContext * memreadContext, struct RoomState * roomState) { initComponents(self, VECTOR2i_ZERO, false); call_super_virtual(initWithEncodedState, self, memreadContext, roomState); self->positionComponent.lastPosition = self->positionComponent.position; self->spriteComponent.spriteID = self->pushableComponent.multipush ? SPRITE_ID_MULTIPUSH_BLOCK : SPRITE_ID_PUSH_BLOCK; } EntityPushBlock * EntityPushBlock_copy(EntityPushBlock * self, struct RoomState * roomState) { stemobject_copy_implementation(initCopy, roomState) } void EntityPushBlock_initCopy(EntityPushBlock * self, compat_type(EntityPushBlock *) originalUntyped, struct RoomState * roomState) { call_super_virtual(initCopy, self, originalUntyped, roomState); EntityPushBlock * original = originalUntyped; initComponents(self, original->positionComponent.position, original->pushableComponent.multipush); call_virtual(initCopy, &self->collidableComponent, &original->collidableComponent); call_virtual(initCopy, &self->positionComponent, &original->positionComponent); call_virtual(initCopy, &self->pushableComponent, &original->pushableComponent); call_virtual(initCopy, &self->spriteComponent, &original->spriteComponent); } void EntityPushBlock_dispose(EntityPushBlock * self) { call_super_virtual(dispose, self); } compat_type(GameEntityComponent *) EntityPushBlock_getComponent(EntityPushBlock * self, ComponentType type) { switch (type) { case COMPONENT_COLLIDABLE: return &self->collidableComponent; case COMPONENT_POSITION: return &self->positionComponent; case COMPONENT_PUSHABLE: return &self->pushableComponent; case COMPONENT_SPRITE: return &self->spriteComponent; default: break; } return NULL; } void EntityPushBlock_preadvance(EntityPushBlock * self) { call_virtual(update, &self->positionComponent, (GameEntity *) self); call_virtual(update, &self->pushableComponent, (GameEntity *) self); } void EntityPushBlock_postadvance(EntityPushBlock * self) { if (self->pushableComponent.pushed) { EventDispatcher_dispatchEvent(self->roomState->eventDispatcher, ATOM_event_block_pushed, self); } } bool EntityPushBlock_isEqual(EntityPushBlock * self, EntityPushBlock * compare) { return self->positionComponent.position.x == compare->positionComponent.position.x && self->positionComponent.position.y == compare->positionComponent.position.y; } void EntityPushBlock_enumerateProperties(EntityPushBlock * self, bool transient, GameEntity_enumeratePropertiesCallback callback, void * context) { call_super_virtual(enumerateProperties, self, transient, callback, context); callback(&self->positionComponent.position, PROPERTY_TYPE_Vector2i_int8_t, context); if (!transient) { callback(&self->pushableComponent.multipush, PROPERTY_TYPE_bool, context); } }