-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathactions.c
127 lines (108 loc) · 4.95 KB
/
actions.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Thomas Stoeckert
COP 3223H - Final Project
This file handles actions that items can do. When a user uses an item, the following functions
are called according to what action an item has.
*/
#include "actions.h"
#include <stdio.h>
// ---- Player Function ---- //
// HandleAction takes in a pointer to the original item, a pointer to the world information, and the index of the source
// It takes these and divies up the work to the other action handlers
void handleAction(struct item *src, struct world *gamedata, int srcIndex){
struct action *srcAction = &src->itemAction;
struct items *currentRoomItems = &getCurrentRoom(gamedata->worldRooms, gamedata->currentRoomId)->inventory;
int srcActionType = srcAction->actionType;
switch(srcActionType){
case -1:
printf("This %s doesn't seem to do anything...\n", src->name);
return;
case 0:
handleDispenseAction(srcAction, &gamedata->inventory, gamedata->itemPrototypes);
return;
case 1:
handleTransformAction(srcAction, &gamedata->inventory, currentRoomItems, gamedata->itemPrototypes, srcIndex);
return;
case 2:
handleUnlockAction(srcAction, &gamedata->worldRooms, &gamedata->inventory, currentRoomItems->numItems, gamedata->currentRoomId, srcIndex);
return;
case 3:
// Game over - just print out the game-over condition and set the playing value to zero.
printf("%s\n", src->itemAction.desc);
gamedata->playing = 0;
return;
}
}
// ---- Player Function ---- //
// handleDispenseAction takes in a pointer to the original action, a pointer to the user's inventory, and a copy of the
// item prototypes
// A dispense action creates a set amount (or infinite amount) of items, one at a time, in the user's inventory
void handleDispenseAction(struct action *srcAction, struct items *inventory, struct items proto){
struct item dispensedItem;
int *quantity = &srcAction->quantity;
if((*quantity) == 0){
// We don't dispense if the item is exactly zero. If it's negative, it dispenses infinitely by design.
printf("The item can't dispense any more.\n");
return;
} else if((*quantity) > 0){
(*quantity)--;
}
dispensedItem = iFindItemByIndex(proto.itemData, srcAction->itemTarget)->data;
printf("%s\n", srcAction->desc);
inventory->itemData = iAppend(inventory->itemData, dispensedItem);
inventory->numItems++;
return;
}
// ---- Player Function ---- //
// a transform action creates the target item, adds it to the appropriate inventory, then deletes the original after
// informing the user about the transformation
void handleTransformAction(struct action *srcAction, struct items *inventory, struct items *roomItems, struct items proto, int srcIndex){
struct item srcItem;
struct item newItem;
int srcId;
int fromRoom = 0;
if(srcIndex < roomItems->numItems){
fromRoom = 1;
srcItem = iFindItemByIndex(roomItems->itemData, srcIndex)->data;
} else {
srcItem = iFindItemByIndex(inventory->itemData, srcIndex - roomItems->numItems)->data;
}
srcId = srcItem.id;
newItem = iFindItemByIndex(proto.itemData, srcAction->itemTarget)->data;
printf("%s\n", srcAction->desc);
if(fromRoom){
roomItems->itemData = iAppend(roomItems->itemData, newItem);
roomItems->itemData = iDeleteItemByID(roomItems->itemData, srcId);
} else {
inventory->itemData = iAppend(inventory->itemData, newItem);
inventory->itemData = iDeleteItemByID(inventory->itemData, srcId);
}
return;
}
// ---- Player Function ---- //
// An unlock action changes the destination of a door in a room to another destination. This can be used
// for unlocking doors, elevator buttons, shifting mazes, pretty much anything
void handleUnlockAction(struct action *srcAction, struct rooms *worldRooms, struct items *inventory, int numRoomItems, int currentRoomID, int srcIndex) {
struct room *targetRoom;
struct room *currentRoom;
struct doors *targetDoors;
struct door *targetDoor;
if(currentRoomID != srcAction->roomTarget){
printf("This key doesn't seem to work in this room...\n");
return;
}
targetRoom = &rFindRoomByID(worldRooms->roomData, srcAction->roomTarget)->data;
targetDoors = &targetRoom->paths;
targetDoor = &dFindDoorByIndex(targetDoors->paths, srcAction->doorTarget)->data;
currentRoom = getCurrentRoom((*worldRooms), currentRoomID);
targetDoor->dest = srcAction->destTarget;
printf("%s\n", srcAction->desc);
// Remove the key
if(srcIndex >= numRoomItems){
inventory->itemData = iDeleteItemByIndex(inventory->itemData, srcIndex - numRoomItems);
inventory->numItems--;
} else {
currentRoom->inventory.itemData = iDeleteItemByIndex(currentRoom->inventory.itemData, srcIndex);
currentRoom->inventory.numItems--;
}
return;
}