devolution

Author Topic: General Discussion  (Read 3821571 times)

0 Members and 50 Guests are viewing this topic.

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7230 on: April 29, 2016, 06:07:23 AM »
Let's see.. Can we freely change slave/free status in the code? It won't cause any issues? For instance we have two characters and two ways to finish an event. Depending on the way, one of them will be free and another one will be slave.

Prolly not, for example they would have different location setups and job setting could become messed up, but I can always add moar logic to the switch later and sort everything out... actually, I'll push a new set_status method that can take arguments if we ever need them, I doubt that we will but just in case.

Pull in 5 mins.

Edit:
====>>
Ok, that is done, I'll add the required additional logic there when I normalize Chars code before the release.
« Last Edit: April 29, 2016, 06:15:02 AM by Xela »
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7231 on: April 29, 2016, 06:54:47 AM »
Huh. Conditions might work incorrectly.
Quote
$ register_event_in_label("drunk_lady2", quest="Drunk Lady", locations=["tavern_inside"], restore_priority=0, run_conditions=["hero.gold >= 1000"], jump=True)
$ pytfall.world_events.force_event("drunk_lady2")
This one somehow works with any amount of gold.

I pushed fixed event, it's working, but it's working weirdly. If you don't have 1000 gold, it runs additional event stage, drunk_lady2, which should not even be available if you don't have 1000G. But the event will run no matter your gold. I even tried to remove force_event, didn't helped.
« Last Edit: April 29, 2016, 07:08:20 AM by DarkTl »

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7232 on: April 29, 2016, 07:58:39 AM »
Code: [Select]
            dice = chance to execute (check dice function), use run_conditions otherwise
            dice has priority over run_conditions

You can usually gather the general "gist" from the comments, default dice is 50, unless you clear that, it will supersede conditions, set it to 0 implicitly to get rid of it. I've pushed a possible fix.
« Last Edit: April 29, 2016, 08:00:26 AM by Xela »
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7233 on: April 29, 2016, 08:12:49 AM »
Yeah, I read all the comments yesterday, but didn't noticed that 50 is default.

It's a bad design, most of the time you need either dice 0 or 100 if you don't set it manually when creating an event. And when you set a condition, you need it not 100 anyway, since dice has a priority and overwrites it. So I'll change the default to 0.

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7234 on: April 29, 2016, 08:25:07 AM »
Speaking of which, some stuff in the comments is unclear to me.

What's custom event trigger? What's custom_condition? What's simple_conditions, especially since we kinda have (and use) run_conditions for "simple" conditions?

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7235 on: April 29, 2016, 11:34:14 AM »
What's custom event trigger?

Anything that's not auto or look around I guess...

What's custom_condition?

Method that can be written if someone inherits from the event class. There is a half baked system in place to help set it up.

What's simple_conditions, especially since we kinda have (and use) run_conditions for "simple" conditions?

Run Conditions will only be evaluated (right) before the event is actually ran, using simple conditions you can prevent an event from ever making it to the event cache. There are not many cases where this is useful, the main reason I wrote that for (and structured the event like I have) was because I've read that string evaluations were really slow in Python. It was however long before I realized that "really slow" was still in range of nano/micro seconds not mentioning that strings could have been converted to byte code which would have worked a lot faster.

Long story short, you can add some conditions there to make sure that an event doesn't make it to cache until they are true.It currently works like this:

- We check all event once per day to create cache, so if we ever have a few hundred, we would not have to check 85 event during runtime that don't have even a remote chance to be triggered.
- We run checks on events in cache during runtime, looking at priority/run_conditions and etc.
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7236 on: April 29, 2016, 11:42:59 AM »
Anything that's not auto or look around I guess...
Yeah, I was hoping for a simple example how it even should be used  :)
Same for custom_condition.

Long story short, you can add some conditions there to make sure that an event doesn't make it to cache until they are true.
Is it useless if we force the event into the cache? Or even force_event will check for  simple_conditions first?

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7237 on: April 29, 2016, 12:04:19 PM »
Yeah, I was hoping for a simple example how it even should be used  :)
Same for custom_condition.

Loads of ways I guess... for example, lets take your new hidden_village loc:

Code: [Select]
    $ pytfall.world_events.run_events("auto")
like in all other locs, so all events that have "all" as a location and auto as trigger will get triggers there, but what if you don't want them to but deleting the line is not an option because you still wish your own event to get triggered? That would be a good time to create your own trigger, lets say call it "hidden_village_auto" and change the line to:

Code: [Select]
    $ pytfall.world_events.run_events("hidden_village_auto")
and you're done.

Now when you create events, you set "hidden_village_auto" as their trigger, you'd still have to set the location to village or to all (all will be fine because they will not be triggered anywhere else anyway).

===>>
The other thing is:

Code: [Select]
class MyOwnEventClass(WorldEvent):
    def __init__(self, *args, **kwargs):
        super(MyOwnEventClass, self).__init__(*args, **kwargs)
        # bla bla bla...

    def custom_conditions(self):
        # bla bla bla... if True, I'll be accepted to the cache.

It could be used for some super fancy conditioning that is too difficult to put into strings...

Is it useless if we force the event into the cache? Or even force_event will check for  simple_conditions first?

It'll just be added, I fixed a potential issue while looking at the code, it will now make sure that the event is not already cached.
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7238 on: April 29, 2016, 12:19:03 PM »
I see...

Quote
def run_events(self, trigger_type, default=None, cost=0)
Could it be possible to change the cost of event activation? Seems like atm it's the same everywhere, even though this function assumes we have control over it.

Hm. And code prevents us from making free events either.
Quote
                if hero.AP < cost:
                    renpy.show_screen("message_screen", "Not enough AP left")
                    return
                else:
                    hero.AP -= cost
To make an event always available the cost could be negative, but it will also restore AP  :)
« Last Edit: April 29, 2016, 12:25:47 PM by DarkTl »

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7239 on: April 29, 2016, 01:41:11 PM »
I see...
Could it be possible to change the cost of event activation? Seems like atm it's the same everywhere, even though this function assumes we have control over it.

Hm. And code prevents us from making free events either.To make an event always available the cost could be negative, but it will also restore AP  :)

I don't understand what you're saying here, there is no default cost for event activation by reasoning that you can add "hero.AP >= 1" to conditions if you absolutely need that for the event and you can just settle the cost in the event label itself. That function is used on one special case where you click the look around button that we've agreed to always be prized at one AP, even if nothing was found. It is not used anywhere else.

It also does no such thing as preventing free events, event if hero.AP == 0, 0 < 0 would still return false and the logic would continue.

I think that the code was added by Thewlis because he made our menus system. I am actually not quite sure why it is written as:

Code: [Select]
            if trigger_type != "auto":
                if hero.AP < cost:
                    renpy.show_screen("message_screen", "Not enough AP left")
                    return
                else:
                    hero.AP -= cost
                    for event in l:
                        if event.check_conditions():
                            event.run_event()
                            return
                   
                    else:
                        if default: renpy.call_in_new_context(default)
                        return
           
            else:
                for event in l:
                    if event.check_conditions():
                        event.run_event()
                        return

it seems to me that:

Code: [Select]
                if hero.AP < cost:
                    renpy.show_screen("message_screen", "Not enough AP left")
                    return
                else:
                    hero.AP -= cost
                    for event in l:
                        if event.check_conditions():
                            event.run_event()
                            return
                   
                    else:
                        if default: renpy.call_in_new_context(default)
                        return

just this code would do the exact same thing under all circumstances. I've changed the codebit and pushed.
Like what we're doing?

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7240 on: April 29, 2016, 01:49:22 PM »
Ok, I am going to try writing some interface code for an hour or two :) I've spent most of the day trying to figure out adaptation of some code and now my head is hurting (again).
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7241 on: April 29, 2016, 02:09:37 PM »
I see. I thought there is a global system for controlling AP cost which is not properly used yet, and -1AP during looking around is handled by the button itself, since you get -1AP even without any tied to it quests.

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7242 on: April 29, 2016, 06:28:04 PM »
Do you think Drag&Drop is worth spending some time on for the team building in FG? Or should we go with something simpler/clumsier?
Like what we're doing?

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: General Discussion
« Reply #7243 on: April 29, 2016, 06:47:39 PM »
Our inventory, which probably will be used much more often than teams building, works and looks fine without it.


Alright, enough is enough. I need to know why the system kills quests on the next day even though they have events. I pushed a new rpy where I create two events, two_sisters1 and two_sisters2. One of them can be launched on the next day in the tavern, another one will be launched a day later and it will kill the quest if player will miss the opportunity.

Two events. Yet apparently this thing
Quote
        def next_day(self):
            """Fails quests that have no valid events.
            """
            garbage = list()
           
            # Find incomplete quests with no existing events
            for i in self.active:
                for j in pytfall.world_events.events_cache:
                    if j.quest == i.name:
                        break
               
                else:
                    if not i.manual: garbage.append(i)
           
            while len(garbage) > 0:
                devlog.warning("Garbage Quest found! \"%s\" was failed."%garbage[0].name)
                self.fail_quest(garbage.pop())
doesn't think they are valid for some reason  :-[

And I need to know how to fail quests via lines. Looks like $ pytfall.world_quests.get("Two Sisters").next_in_label("Sadly, you missed you chance to meet her.", "failed") or $ pytfall.world_quests.get("Two Sisters").next_in_label("Sadly, you missed you chance to meet her.", "fail") don't do it. Although it's hard to tell for sure, since atm garbage clearing system kills the quest asap, but I have an impression they don't work  :D
 
« Last Edit: April 29, 2016, 06:52:21 PM by DarkTl »

Offline Xela

  • Global Moderator
  • *****
  • Posts: 6893
  • "It's like hunting cows"
Re: General Discussion
« Reply #7244 on: April 30, 2016, 01:38:23 AM »
I have no clue offhand, gonna be traveling for the better part of the day today. I'll try to find out what's what tonight unless you've done that already.
Like what we're doing?