Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions config/fxdata/magic.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,18 @@ Cooldown = 0
; BOUND_CRTRS - allow casting on creatures being affected by Armageddon and Teleport, those who are dragging, leaving or being sacrificed, allowing this may have bad side effects.
; ONLY_DIGGERS - can only be cast on special diggers.
; NO_DIGGERS - can only be cast on creatures that are not special diggers.
; ALL_OBJECTS - can target any object.
; OWNED_OBJECTS
; NEUTRL_OBJECTS
; ENEMY_OBJECTS
; ALL_OBJECTS_PICKUP - can target any object that can be picked up.
; OWNED_OBJECTS_PICKUP
; NEUTRL_OBJECTS_PICKUP
; ENEMY_OBJECTS_PICKUP
; ALL_OBJECTS_SLAP - can target any object that can be slapped.
; OWNED_OBJECTS_SLAP
; NEUTRL_OBJECTS_SLAP
; ENEMY_OBJECTS_SLAP
; Miscellaneous:
; NEEDS_DELAY - Requires a delay defined with 'Cooldown' in game turns before it can be cast again.
Castability =
Expand Down Expand Up @@ -1705,7 +1717,7 @@ SoundSamples = 0
SoundPlayed = 0
Power = 0 0 0 0 0 0 0 0 0 0
Cost = 0 0 0 0 0 0 0 0 0
Castability = ANYWHERE OWNED_CRTRS CUSTODY_CRTRS ALL_FOOD ALL_GOLD ALL_OBJECTS
Castability = ANYWHERE OWNED_CRTRS CUSTODY_CRTRS ALL_FOOD ALL_GOLD OWNED_OBJECTS_PICKUP
Artifact = SPELLBOOK_HOE
Properties = INSTINCTIVE
PlayerState = PLAYER_STATE_NONE
Expand Down Expand Up @@ -1768,7 +1780,7 @@ SoundPlayed = 75
Power = 0 0 0 0 0 0 0 0 0 0
Cost = 0 0 0 0 0 0 0 0 0
Duration = 500
Castability = ALL_GROUND OWNED_CRTRS BOUND_CRTRS CUSTODY_CRTRS OWNED_BOULDERS OWNED_FOOD
Castability = ALL_GROUND OWNED_CRTRS BOUND_CRTRS CUSTODY_CRTRS OWNED_BOULDERS OWNED_FOOD OWNED_OBJECTS_SLAP
Artifact = SPELLBOOK_SLAP
Properties = INSTINCTIVE
PlayerState = PLAYER_STATE_NONE
Expand Down Expand Up @@ -2280,7 +2292,7 @@ SoundSamples = 0
SoundPlayed = 109
Power = 0 0 0 0 0 0 0 0 0 0
Cost = 0 0 0 0 0 0 0 0 0
Castability = ANYWHERE OWNED_OBJECTS
Castability = ANYWHERE OWNED_OBJECTS_PICKUP
Artifact = NULL
Properties = INSTINCTIVE
PlayerState = PLAYER_STATE_NONE
Expand Down
6 changes: 3 additions & 3 deletions config/fxdata/objects.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ FlameTransparencyFlags = 0
Immobile = 0
; Initial state, only used for chickens.
InitialState = 0
; Possible properties: EXISTS_ONLY_IN_ROOM, DESTROYED_ON_ROOM_CLAIM, CHOWNED_ON_ROOM_CLAIM, DESTROYED_ON_ROOM_PLACE, BUOYANT, BEATING, HEART, HOLD_IN_HAND, IGNORED_BY_IMPS.
; Possible properties: EXISTS_ONLY_IN_ROOM, DESTROYED_ON_ROOM_CLAIM, CHOWNED_ON_ROOM_CLAIM, DESTROYED_ON_ROOM_PLACE, BUOYANT, BEATING, HEART, HOLD_IN_HAND, IGNORED_BY_IMPS, SLAPPABLE.
Properties =
; Function that should be executed to update the object.
; UPDATE_DUNGEON_HEART, UPDATE_CALL_TO_ARMS, UPDATE_ARMOUR, UPDATE_OBJECT_SCALE, UPDATE_POWER_SIGHT, UPDATE_POWER_LIGHTNING, NULL.
Expand Down Expand Up @@ -325,7 +325,7 @@ Size_Z = 128
MaximumSize = 300
DestroyOnLava = 0
DestroyOnLiquid = 1
Health = 1000
Health = 5
FallAcceleration = 9
HandIcon = 59
HandAnimationID = 122
Expand All @@ -338,7 +338,7 @@ DrawClass = 2
Persistence = 2
Immobile = 0
InitialState = 1
Properties = DESTROYED_ON_ROOM_CLAIM
Properties = DESTROYED_ON_ROOM_CLAIM SLAPPABLE
UpdateFunction = NULL

[object11]
Expand Down
8 changes: 8 additions & 0 deletions src/config_magic.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,14 @@ const struct LongNamedCommand powermodel_castability_commands[] = {
{"OWNED_OBJECTS", PwCast_OwnedObjects},
{"NEUTRL_OBJECTS", PwCast_NeutrlObjects},
{"ENEMY_OBJECTS", PwCast_EnemyObjects},
{"ALL_OBJECTS_PICKUP", PwCast_AllObjectsPickup},
{"OWNED_OBJECTS_PICKUP", PwCast_OwnedObjectsPickup},
{"NEUTRL_OBJECTS_PICKUP", PwCast_NeutrlObjectsPickup},
{"ENEMY_OBJECTS_PICKUP", PwCast_EnemyObjectsPickup},
{"ALL_OBJECTS_SLAP", PwCast_AllObjectsSlap},
{"OWNED_OBJECTS_SLAP", PwCast_OwnedObjectsSlap},
{"NEUTRL_OBJECTS_SLAP", PwCast_NeutrlObjectsSlap},
{"ENEMY_OBJECTS_SLAP", PwCast_EnemyObjectsSlap},
{NULL, 0},
};

Expand Down
8 changes: 8 additions & 0 deletions src/config_magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,19 @@ enum ShotModelFlags {
#define PwCast_OwnedObjects (1LL << 32)
#define PwCast_NeutrlObjects (1LL << 33)
#define PwCast_EnemyObjects (1LL << 34)
#define PwCast_OwnedObjectsPickup (1LL << 35)
#define PwCast_NeutrlObjectsPickup (1LL << 36)
#define PwCast_EnemyObjectsPickup (1LL << 37)
#define PwCast_OwnedObjectsSlap (1LL << 38)
#define PwCast_NeutrlObjectsSlap (1LL << 39)
#define PwCast_EnemyObjectsSlap (1LL << 40)

#define PwCast_AllCrtrs (PwCast_CustodyCrtrs|PwCast_OwnedCrtrs|PwCast_AlliedCrtrs|PwCast_EnemyCrtrs|PwCast_NConscCrtrs|PwCast_BoundCrtrs)
#define PwCast_AllFood (PwCast_OwnedFood|PwCast_NeutrlFood|PwCast_EnemyFood)
#define PwCast_AllGold (PwCast_OwnedGold|PwCast_NeutrlGold|PwCast_EnemyGold)
#define PwCast_AllObjects (PwCast_OwnedObjects|PwCast_NeutrlObjects|PwCast_EnemyObjects)
#define PwCast_AllObjectsPickup (PwCast_OwnedObjectsPickup|PwCast_NeutrlObjectsPickup|PwCast_EnemyObjectsPickup)
#define PwCast_AllObjectsSlap (PwCast_OwnedObjectsSlap|PwCast_NeutrlObjectsSlap|PwCast_EnemyObjectsSlap)
#define PwCast_AllThings (PwCast_CustodyCrtrs|PwCast_OwnedCrtrs|PwCast_AlliedCrtrs|PwCast_EnemyCrtrs|PwCast_AllFood|PwCast_AllGold|PwCast_OwnedSpell|PwCast_OwnedBoulders|PwCast_AllObjects)
#define PwCast_AllGround (PwCast_UnclmdGround|PwCast_NeutrlGround|PwCast_OwnedGround|PwCast_AlliedGround|PwCast_EnemyGround)
#define PwCast_NotEnemyGround (PwCast_UnclmdGround|PwCast_NeutrlGround|PwCast_OwnedGround|PwCast_AlliedGround)
Expand Down
1 change: 1 addition & 0 deletions src/config_objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const struct NamedCommand objects_properties_commands[] = {
{"HEART", OMF_Heart },
{"HOLD_IN_HAND", OMF_HoldInHand },
{"IGNORED_BY_IMPS", OMF_IgnoredByImps },
{"SLAPPABLE", OMF_Slappable },
{NULL, 0},
};

Expand Down
1 change: 1 addition & 0 deletions src/config_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum ObjectModelFlags {
OMF_Heart = 0x0040, // Functions as the heart of the dungeon
OMF_HoldInHand = 0x0080, // Object can be picked up to hold
OMF_IgnoredByImps = 0x0100, // Specialdiggers don't dragging this object
OMF_Slappable = 0x0200, // Object can be slapped
};


Expand Down
48 changes: 45 additions & 3 deletions src/magic_powers.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,29 +300,71 @@ TbBool can_cast_power_on_thing(PlayerNumber plyr_idx, const struct Thing *thing,
}
}
if ((powerst->can_cast_flags & PwCast_OwnedObjects) != 0)
{
if (thing->owner == plyr_idx) {
return true;
}
}
if ((powerst->can_cast_flags & PwCast_NeutrlObjects) != 0)
{
if (is_neutral_thing(thing)) {
return true;
}
}
if ((powerst->can_cast_flags & PwCast_EnemyObjects) != 0)
{
if ((thing->owner != plyr_idx) && !is_neutral_thing(thing)) {
return true;
}
}
if ((powerst->can_cast_flags & PwCast_OwnedObjectsPickup) != 0)
{
if (thing->owner == plyr_idx) {
if (object_is_pickable_by_hand_to_hold(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_NeutrlObjects) != 0)
if ((powerst->can_cast_flags & PwCast_NeutrlObjectsPickup) != 0)
{
if (is_neutral_thing(thing)) {
if (object_is_pickable_by_hand_to_hold(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_EnemyObjects) != 0)
if ((powerst->can_cast_flags & PwCast_EnemyObjectsPickup) != 0)
{
if ((thing->owner != plyr_idx) && !is_neutral_thing(thing)) {
if (object_is_pickable_by_hand_to_hold(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_OwnedObjectsSlap) != 0)
{
if (thing->owner == plyr_idx) {
if (object_is_slappable(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_NeutrlObjectsSlap) != 0)
{
if (is_neutral_thing(thing)) {
if (object_is_slappable(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_EnemyObjectsSlap) != 0)
{
if ((thing->owner != plyr_idx) && !is_neutral_thing(thing)) {
if (object_is_slappable(thing)) {
return true;
}
}
}
if ((powerst->can_cast_flags & PwCast_OwnedSpell) != 0)
{
if (thing->owner == plyr_idx) {
Expand All @@ -337,7 +379,7 @@ TbBool can_cast_power_on_thing(PlayerNumber plyr_idx, const struct Thing *thing,
if ((powerst->can_cast_flags & PwCast_OwnedBoulders) != 0)
{
if (thing->owner == plyr_idx) {
if (shot_is_slappable(thing, plyr_idx)) {
if (shot_is_slappable_by_player(thing, plyr_idx)) {
return true;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/packets_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,8 @@ TbBool process_dungeon_control_packet_dungeon_control(long plyr_idx)
{
if (player->primary_cursor_state == CSt_PowerHand && (!player->one_click_lock_cursor)) {
thing = get_nearest_thing_for_slap(plyr_idx, subtile_coord_center(stl_x), subtile_coord_center(stl_y));
magic_use_available_power_on_thing(plyr_idx, PwrK_SLAP, 0, stl_x, stl_y, thing, PwMod_Default);
if(!thing_is_invalid(thing))
magic_use_available_power_on_thing(plyr_idx, PwrK_SLAP, 0, stl_x, stl_y, thing, PwMod_Default);
}
if ((pckt->control_flags & PCtr_LBtnHeld) == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion src/player_instances.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ long pinstfe_hand_whip(struct PlayerInfo *player, int32_t *n)
case TCls_Object:
{
struct Thing* efftng;
if (object_is_slappable(thing, player->id_number))
if (object_is_slappable_by_player(thing, player->id_number))
{
efftng = create_effect(&thing->mappos, TngEff_Dummy, thing->owner);
if (!thing_is_invalid(efftng))
Expand Down
34 changes: 21 additions & 13 deletions src/power_hand.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ TbBool can_thing_be_picked_up2_by_player(const struct Thing *thing, PlayerNumber
}
}

struct Thing *process_object_being_picked_up(struct Thing *thing, long plyr_idx)
struct Thing *process_object_being_picked_up(struct Thing *thing, PlayerNumber plyr_idx)
{
struct Thing *picktng = INVALID_THING;
struct Coord3d pos;
Expand Down Expand Up @@ -312,7 +312,7 @@ struct Thing *process_object_being_picked_up(struct Thing *thing, long plyr_idx)
{
picktng = create_gold_for_hand_grab(thing, plyr_idx);
}
else if (object_is_pickable_by_hand_to_hold_by_player(thing, plyr_idx))
else if (object_is_pickable_by_hand_to_hold(thing))
{
picktng = thing;
}
Expand Down Expand Up @@ -720,10 +720,17 @@ void draw_power_hand(void)
}
}

TbBool object_is_slappable(const struct Thing *thing, long plyr_idx)
TbBool object_is_slappable(const struct Thing* thing)
{
if (thing->owner == plyr_idx) {
return (object_is_mature_food(thing));
struct ObjectConfigStats* objst = get_object_model_stats(thing->model);
return ((objst->model_flags & OMF_Slappable) != 0);
}

TbBool object_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx)
{
if (thing->owner == plyr_idx)
{
return object_is_slappable(thing);
}
return false;
}
Expand Down Expand Up @@ -787,18 +794,18 @@ long near_map_block_thing_filter_ready_for_hand_or_slap(const struct Thing *thin
return -1;
}

TbBool thing_slappable(const struct Thing *thing, long plyr_idx)
TbBool thing_slappable(const struct Thing *thing, PlayerNumber plyr_idx)
{
switch (thing->class_id)
{
case TCls_Object:
return object_is_slappable(thing, plyr_idx);
return object_is_slappable_by_player(thing, plyr_idx);
case TCls_Shot:
return shot_is_slappable(thing, plyr_idx);
return shot_is_slappable_by_player(thing, plyr_idx);
case TCls_Creature:
return creature_is_slappable(thing, plyr_idx);
case TCls_Trap:
return trap_is_slappable(thing, plyr_idx);
return trap_is_slappable_by_player(thing, plyr_idx);
default:
return false;
}
Expand Down Expand Up @@ -1470,8 +1477,7 @@ TbResult use_power_hand(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoor
}
if (!can_thing_be_picked_up_by_player(thing, plyr_idx))
{
ERRORLOG("The %s owned by player %d is not pickable by player %d",thing_model_name(thing),(int)thing->owner,(int)plyr_idx);
return Lb_OK;
return Lb_FAIL;
}
if (thing_is_special_box(thing))
{
Expand Down Expand Up @@ -1524,10 +1530,12 @@ void stop_creatures_around_hand(PlayerNumber plyr_idx, MapSubtlCoord stl_x, Map
}
}

#define HAND_TO_OBJECT_SLAP_DAMAGE 10
TbBool slap_object(struct Thing *thing)
{
if (object_is_mature_food(thing)) {
destroy_object(thing);
if (object_is_slappable(thing))
{
apply_damage_to_thing(thing, HAND_TO_OBJECT_SLAP_DAMAGE, thing->owner);
return true;
}
return false;
Expand Down
7 changes: 4 additions & 3 deletions src/power_hand.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ TbBool object_is_pickable_by_hand_for_use(const struct Thing *thing, long plyr_i
TbBool object_is_pickable_by_hand_to_hold_by_player(const struct Thing* thing, long plyr_idx);
TbBool object_is_pickable_by_hand_to_hold(const struct Thing* thing);
TbBool thing_is_pickable_by_hand(struct PlayerInfo *player, const struct Thing *thing);
struct Thing *process_object_being_picked_up(struct Thing *thing, long a2);
struct Thing *process_object_being_picked_up(struct Thing *thing, PlayerNumber plyr_idx);
void set_power_hand_graphic(unsigned char plyr_idx, long HandAnimationID);
TbBool power_hand_is_empty(const struct PlayerInfo *player);
TbBool power_hand_is_full(const struct PlayerInfo *player);
Expand All @@ -68,8 +68,9 @@ TbBool thing_is_picked_up_by_player(const struct Thing *thing, PlayerNumber plyr
long get_thing_in_hand_id(const struct Thing* thing, PlayerNumber plyr_idx);

TbBool slap_object(struct Thing *thing);
TbBool object_is_slappable(const struct Thing *thing, long plyr_idx);
TbBool thing_slappable(const struct Thing *thing, long plyr_idx);
TbBool object_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool object_is_slappable(const struct Thing* thing);
TbBool thing_slappable(const struct Thing *thing, PlayerNumber plyr_idx);

struct Thing *create_power_hand(PlayerNumber owner);
void delete_power_hand(PlayerNumber owner);
Expand Down
8 changes: 7 additions & 1 deletion src/thing_objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,6 @@ TngUpdateRet update_object(struct Thing *thing)
SYNCDBG(18,"Starting for %s",thing_model_name(thing));
TRACE_THING(thing);


struct ObjectConfigStats* objst = get_object_model_stats(thing->model);

if (objst->updatefn_idx > 0)
Expand Down Expand Up @@ -1785,6 +1784,13 @@ TngUpdateRet update_object(struct Thing *thing)
return TUFRet_Deleted;
}
}

if (thing->health < 0 && !thing_is_dungeon_heart(thing))
{
destroy_object(thing);
return TUFRet_Deleted;
}

SYNCDBG(18,"Updating position");
thing->movement_flags &= ~TMvF_IsOnWater;
thing->movement_flags &= ~TMvF_IsOnLava;
Expand Down
2 changes: 1 addition & 1 deletion src/thing_shots.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ TbBool thing_is_shot(const struct Thing *thing)
return true;
}

TbBool shot_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx)
TbBool shot_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx)
{
if (thing->owner == plyr_idx)
{
Expand Down
2 changes: 1 addition & 1 deletion src/thing_shots.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ long get_damage_of_melee_shot(struct Thing *shotng, const struct Thing *target,
void create_relevant_effect_for_shot_hitting_thing(struct Thing *shotng, struct Thing *target);
int weight_calculated_push_strenght(int weight, int push_strength);

TbBool shot_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool shot_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool shot_model_is_navigable(long tngmodel);
TbBool shot_model_makes_flesh_explosion(long shot_model);
TbBool detonate_shot(struct Thing *shotng, TbBool destroy);
Expand Down
2 changes: 1 addition & 1 deletion src/thing_traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ TbBool trap_is_active(const struct Thing *thing)
return ((thing->trap.num_shots > 0) && (thing->trap.rearm_turn <= get_gameturn()));
}

TbBool trap_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx)
TbBool trap_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx)
{
struct TrapConfigStats *trapst;
if (thing->owner == plyr_idx)
Expand Down
2 changes: 1 addition & 1 deletion src/thing_traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct Thing* activate_trap_spawn_creature(struct Thing* traptng, unsigned char
struct Thing *get_trap_for_position(MapSubtlCoord stl_x, MapSubtlCoord stl_y);
struct Thing *get_trap_for_slab_position(MapSlabCoord slb_x, MapSlabCoord slb_y);
TbBool trap_is_active(const struct Thing *thing);
TbBool trap_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool trap_is_slappable_by_player(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool thing_is_deployed_trap(const struct Thing *thing);
short thing_is_destructible_trap(const struct Thing* thing);
TbBool thing_is_sellable_trap(const struct Thing* thing);
Expand Down